diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2022-07-23 21:16:59 +0100 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2022-07-23 21:16:59 +0100 |
| commit | a436be44b2952df94acf1f91591e0bc788c36dc3 (patch) | |
| tree | 3f8f22783ad51b3786279bd0f2928094b1b3fe5e | |
| parent | 2be00623e4fb1edc6a8a13f1d1c55b3ea093a732 (diff) | |
| download | rust-a436be44b2952df94acf1f91591e0bc788c36dc3.tar.gz rust-a436be44b2952df94acf1f91591e0bc788c36dc3.zip | |
feat: don't highlight the whole fn on return-type mismatch
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/type_mismatch.rs | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 5826bed3434..1b353ce56ba 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -1,7 +1,12 @@ use hir::{db::AstDatabase, HirDisplay, Type}; -use ide_db::{famous_defs::FamousDefs, source_change::SourceChange}; +use ide_db::{ + base_db::{FileRange, SourceDatabase}, + famous_defs::FamousDefs, + source_change::SourceChange, +}; use syntax::{ - ast::{BlockExpr, ExprStmt}, + algo::find_node_at_range, + ast::{self, BlockExpr, ExprStmt}, AstNode, }; use text_edit::TextEdit; @@ -13,6 +18,18 @@ use crate::{fix, Assist, Diagnostic, DiagnosticsContext}; // This diagnostic is triggered when the type of an expression does not match // the expected type. pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Diagnostic { + let FileRange { file_id, range } = + ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())); + + let source_file = ctx.sema.db.parse(file_id); + let block = find_node_at_range::<ast::BlockExpr>(&source_file.syntax_node(), range) + .filter(|it| it.syntax().text_range() == range); + let display_range = block + .and_then(|it| it.stmt_list()) + .and_then(|it| it.r_curly_token()) + .map(|it| it.text_range()) + .unwrap_or(range); + let mut diag = Diagnostic::new( "type-mismatch", format!( @@ -20,7 +37,7 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) d.expected.display(ctx.sema.db), d.actual.display(ctx.sema.db) ), - ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, + display_range, ) .with_fixes(fixes(ctx, d)); if diag.fixes.is_none() { @@ -545,4 +562,18 @@ fn test() -> String { "#, ); } + + #[test] + fn type_mismatch_on_block() { + check_diagnostics( + r#" +fn f() -> i32 { + let x = 1; + let y = 2; + let _ = x + y; + } +//^ error: expected i32, found () +"#, + ); + } } |
