feat: add file and location to error reports

This commit is contained in:
Romain Paquet 2025-11-05 20:23:17 +01:00
parent ff586ca2d8
commit efb8607569

View file

@ -67,7 +67,7 @@ impl TypeError {
match &self.kind { match &self.kind {
TypeErrorKind::InvalidBinaryOperator { operator, lhs, rhs } => { TypeErrorKind::InvalidBinaryOperator { operator, lhs, rhs } => {
Report::build(ReportKind::Error, 0u32, 0) Report::build(ReportKind::Error, lhs.span.source, lhs.span.start)
.with_message(format!( .with_message(format!(
"Invalid binary operation {} between {} and {}", "Invalid binary operation {} between {} and {}",
operator.op.to_string().fg(c0), operator.op.to_string().fg(c0),
@ -100,7 +100,18 @@ impl TypeError {
let span = function.body.value.as_ref().unwrap().span; let span = function.body.value.as_ref().unwrap().span;
let report = Report::build(ReportKind::Error, 0u32, 0) 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_message("Function body does not match the signature")
.with_labels([ .with_labels([
Label::new(function.body.span.unwrap()) Label::new(function.body.span.unwrap())
@ -110,26 +121,25 @@ impl TypeError {
.with_message(format!( .with_message(format!(
"Returned expression has type {} but the function should return {}", "Returned expression has type {} but the function should return {}",
block_type.to_string().fg(block_color), block_type.to_string().fg(block_color),
function func_return_type_text,
.return_type
.as_ref()
.unwrap_or(&Type::Unit)
.to_string()
.fg(signature_color)
)) ))
.with_color(block_color), .with_color(block_color),
]); ]);
let report = if let Some(span) = function.return_type_span {
report.with_note("The last expression of a function's body is returned"); report.add_label(
Label::new(span)
.with_message(format!("The signature shows {}", func_return_type_text))
.with_color(signature_color),
);
}
let report = if function.return_type.is_none() { report.set_note("The last expression of a function's body is returned");
report.with_help(
"You may need to add the return type to the function's signature", if function.return_type.is_none() {
)
} else {
report report
}; .set_help("You may need to add the return type to the function's signature")
}
report.finish() report.finish()
} }
@ -146,7 +156,11 @@ impl TypeError {
let is_bare_return = return_expr.is_none(); let is_bare_return = return_expr.is_none();
let report = Report::build(ReportKind::Error, *return_stmt.span.source(), 0) 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_message("Return type does not match the function's signature")
.with_label( .with_label(
Label::new(return_expr.as_ref().unwrap_or(return_stmt).span) Label::new(return_expr.as_ref().unwrap_or(return_stmt).span)
@ -161,22 +175,17 @@ impl TypeError {
}), }),
); );
let report = if let Some(ret_ty_span) = function.return_type_span { if let Some(ret_ty_span) = function.return_type_span {
report.with_label(Label::new(ret_ty_span).with_color(c0).with_message(format!( report.add_label(Label::new(ret_ty_span).with_color(c0).with_message(format!(
"The signature shows {}", "The signature shows {}",
function.return_type.as_ref().unwrap().to_string().fg(c0) function.return_type.as_ref().unwrap().to_string().fg(c0)
))) )))
} else { }
report
};
let report = if function.return_type.is_none() { if function.return_type.is_none() {
report.with_help(
"You may need to add the return type to the function's signature",
)
} else {
report report
}; .set_help("You may need to add the return type to the function's signature")
}
report.finish() report.finish()
} }