Skip to content

Commit a436be4

Browse files
committed
feat: don't highlight the whole fn on return-type mismatch
1 parent 2be0062 commit a436be4

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

crates/ide-diagnostics/src/handlers/type_mismatch.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
use hir::{db::AstDatabase, HirDisplay, Type};
2-
use ide_db::{famous_defs::FamousDefs, source_change::SourceChange};
2+
use ide_db::{
3+
base_db::{FileRange, SourceDatabase},
4+
famous_defs::FamousDefs,
5+
source_change::SourceChange,
6+
};
37
use syntax::{
4-
ast::{BlockExpr, ExprStmt},
8+
algo::find_node_at_range,
9+
ast::{self, BlockExpr, ExprStmt},
510
AstNode,
611
};
712
use text_edit::TextEdit;
@@ -13,14 +18,26 @@ use crate::{fix, Assist, Diagnostic, DiagnosticsContext};
1318
// This diagnostic is triggered when the type of an expression does not match
1419
// the expected type.
1520
pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Diagnostic {
21+
let FileRange { file_id, range } =
22+
ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into()));
23+
24+
let source_file = ctx.sema.db.parse(file_id);
25+
let block = find_node_at_range::<ast::BlockExpr>(&source_file.syntax_node(), range)
26+
.filter(|it| it.syntax().text_range() == range);
27+
let display_range = block
28+
.and_then(|it| it.stmt_list())
29+
.and_then(|it| it.r_curly_token())
30+
.map(|it| it.text_range())
31+
.unwrap_or(range);
32+
1633
let mut diag = Diagnostic::new(
1734
"type-mismatch",
1835
format!(
1936
"expected {}, found {}",
2037
d.expected.display(ctx.sema.db),
2138
d.actual.display(ctx.sema.db)
2239
),
23-
ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
40+
display_range,
2441
)
2542
.with_fixes(fixes(ctx, d));
2643
if diag.fixes.is_none() {
@@ -545,4 +562,18 @@ fn test() -> String {
545562
"#,
546563
);
547564
}
565+
566+
#[test]
567+
fn type_mismatch_on_block() {
568+
check_diagnostics(
569+
r#"
570+
fn f() -> i32 {
571+
let x = 1;
572+
let y = 2;
573+
let _ = x + y;
574+
}
575+
//^ error: expected i32, found ()
576+
"#,
577+
);
578+
}
548579
}

0 commit comments

Comments
 (0)