diff --git a/src/typing/error.rs b/src/typing/error.rs index 0260f97..11366a6 100644 --- a/src/typing/error.rs +++ b/src/typing/error.rs @@ -67,7 +67,7 @@ impl TypeError { match &self.kind { TypeErrorKind::InvalidBinaryOperator { operator, lhs, rhs } => { - Report::build(ReportKind::Error, 0u32, 0) + Report::build(ReportKind::Error, lhs.span.source, lhs.span.start) .with_message(format!( "Invalid binary operation {} between {} and {}", operator.op.to_string().fg(c0), @@ -100,36 +100,46 @@ impl TypeError { let span = function.body.value.as_ref().unwrap().span; - let report = Report::build(ReportKind::Error, 0u32, 0) - .with_message("Function body does not match the signature") - .with_labels([ - Label::new(function.body.span.unwrap()) - .with_message("In this function's body") - .with_color(c2), + let func_return_type_text = function + .return_type + .as_ref() + .unwrap_or(&Type::Unit) + .to_string() + .fg(signature_color); + + let mut report = Report::build( + ReportKind::Error, + span.source, + function.body.value.as_ref().unwrap().span.start, + ) + .with_message("Function body does not match the signature") + .with_labels([ + Label::new(function.body.span.unwrap()) + .with_message("In this function's body") + .with_color(c2), + Label::new(span) + .with_message(format!( + "Returned expression has type {} but the function should return {}", + block_type.to_string().fg(block_color), + func_return_type_text, + )) + .with_color(block_color), + ]); + + if let Some(span) = function.return_type_span { + report.add_label( Label::new(span) - .with_message(format!( - "Returned expression has type {} but the function should return {}", - block_type.to_string().fg(block_color), - function - .return_type - .as_ref() - .unwrap_or(&Type::Unit) - .to_string() - .fg(signature_color) - )) - .with_color(block_color), - ]); + .with_message(format!("The signature shows {}", func_return_type_text)) + .with_color(signature_color), + ); + } - let report = - report.with_note("The last expression of a function's body is returned"); + report.set_note("The last expression of a function's body is returned"); - let report = if function.return_type.is_none() { - report.with_help( - "You may need to add the return type to the function's signature", - ) - } else { + if function.return_type.is_none() { report - }; + .set_help("You may need to add the return type to the function's signature") + } report.finish() } @@ -146,37 +156,36 @@ impl TypeError { let is_bare_return = return_expr.is_none(); - let report = Report::build(ReportKind::Error, *return_stmt.span.source(), 0) - .with_message("Return type does not match the function's signature") - .with_label( - Label::new(return_expr.as_ref().unwrap_or(return_stmt).span) - .with_color(c1) - .with_message(if is_bare_return { - format!("Bare return has type {}", Type::Unit.to_string().fg(c1)) - } else { - format!( - "This expression has type {}", - return_stmt.ty.to_string().fg(c1) - ) - }), - ); + let mut report = Report::build( + ReportKind::Error, + *return_stmt.span.source(), + return_stmt.span.start, + ) + .with_message("Return type does not match the function's signature") + .with_label( + Label::new(return_expr.as_ref().unwrap_or(return_stmt).span) + .with_color(c1) + .with_message(if is_bare_return { + format!("Bare return has type {}", Type::Unit.to_string().fg(c1)) + } else { + format!( + "This expression has type {}", + return_stmt.ty.to_string().fg(c1) + ) + }), + ); - let report = if let Some(ret_ty_span) = function.return_type_span { - report.with_label(Label::new(ret_ty_span).with_color(c0).with_message(format!( + if let Some(ret_ty_span) = function.return_type_span { + report.add_label(Label::new(ret_ty_span).with_color(c0).with_message(format!( "The signature shows {}", function.return_type.as_ref().unwrap().to_string().fg(c0) ))) - } else { - report - }; + } - let report = if function.return_type.is_none() { - report.with_help( - "You may need to add the return type to the function's signature", - ) - } else { + if function.return_type.is_none() { report - }; + .set_help("You may need to add the return type to the function's signature") + } report.finish() }