fix: silence type mismatch diagnostic when type is unknown

This commit is contained in:
Amit Singhmar
2026-04-03 11:05:46 +00:00
parent 166f219169
commit acb162e158
2 changed files with 47 additions and 16 deletions
@@ -20,7 +20,14 @@
//
// This diagnostic is triggered when the type of an expression or pattern does not match
// the expected type.
pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch<'_>) -> Diagnostic {
pub(crate) fn type_mismatch(
ctx: &DiagnosticsContext<'_>,
d: &hir::TypeMismatch<'_>,
) -> Option<Diagnostic> {
if d.expected.is_unknown() || d.actual.is_unknown() {
return None;
}
let display_range = adjusted_display_range(ctx, d.expr_or_pat, &|node| {
let Either::Left(expr) = node else { return None };
let salient_token_range = match expr {
@@ -39,21 +46,23 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch<
cov_mark::hit!(type_mismatch_range_adjustment);
Some(salient_token_range)
});
Diagnostic::new(
DiagnosticCode::RustcHardError("E0308"),
format!(
"expected {}, found {}",
d.expected
.display(ctx.sema.db, ctx.display_target)
.with_closure_style(ClosureStyle::ClosureWithId),
d.actual
.display(ctx.sema.db, ctx.display_target)
.with_closure_style(ClosureStyle::ClosureWithId),
),
display_range,
Some(
Diagnostic::new(
DiagnosticCode::RustcHardError("E0308"),
format!(
"expected {}, found {}",
d.expected
.display(ctx.sema.db, ctx.display_target)
.with_closure_style(ClosureStyle::ClosureWithId),
d.actual
.display(ctx.sema.db, ctx.display_target)
.with_closure_style(ClosureStyle::ClosureWithId),
),
display_range,
)
.stable()
.with_fixes(fixes(ctx, d)),
)
.stable()
.with_fixes(fixes(ctx, d))
}
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch<'_>) -> Option<Vec<Assist>> {
@@ -1250,6 +1259,25 @@ enum E { V() }
let E::V() = &S {};
// ^^^^^^ error: expected S, found E
}
"#,
);
}
#[test]
fn test_ignore_unknown_mismatch() {
check_diagnostics(
r#"
pub trait Foo {
type Out;
}
impl Foo for [i32; 1] {
type Out = ();
}
pub fn foo<T: Foo>(_: T) -> (T::Out,) { loop { } }
fn main() {
let _x = foo(2);
}
"#,
);
}
@@ -430,7 +430,10 @@ pub fn semantic_diagnostics(
AnyDiagnostic::TraitImplRedundantAssocItems(d) => handlers::trait_impl_redundant_assoc_item::trait_impl_redundant_assoc_item(&ctx, &d),
AnyDiagnostic::TraitImplOrphan(d) => handlers::trait_impl_orphan::trait_impl_orphan(&ctx, &d),
AnyDiagnostic::TypedHole(d) => handlers::typed_hole::typed_hole(&ctx, &d),
AnyDiagnostic::TypeMismatch(d) => handlers::type_mismatch::type_mismatch(&ctx, &d),
AnyDiagnostic::TypeMismatch(d) => match handlers::type_mismatch::type_mismatch(&ctx, &d) {
Some(diag) => diag,
None => continue,
},
AnyDiagnostic::UndeclaredLabel(d) => handlers::undeclared_label::undeclared_label(&ctx, &d),
AnyDiagnostic::UnimplementedBuiltinMacro(d) => handlers::unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d),
AnyDiagnostic::UnreachableLabel(d) => handlers::unreachable_label::unreachable_label(&ctx, &d),