From d45708fabe1f43b0c229b6b5222b7a2d5420d07e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 7 Mar 2023 15:24:43 +0100 Subject: [PATCH] Don't trigger unresolved method/field diagnostics on types containing errors --- crates/hir-ty/src/chalk_ext.rs | 7 ++++++- crates/hir-ty/src/infer.rs | 4 ++-- .../src/handlers/unresolved_field.rs | 13 +++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs index 45c975dfcd..e6aefbf271 100644 --- a/crates/hir-ty/src/chalk_ext.rs +++ b/crates/hir-ty/src/chalk_ext.rs @@ -13,7 +13,7 @@ use crate::{ db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, - QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause, + QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause, }; pub trait TyExt { @@ -22,6 +22,7 @@ pub trait TyExt { fn is_floating_point(&self) -> bool; fn is_never(&self) -> bool; fn is_unknown(&self) -> bool; + fn contains_unknown(&self) -> bool; fn is_ty_var(&self) -> bool; fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>; @@ -76,6 +77,10 @@ impl TyExt for Ty { matches!(self.kind(Interner), TyKind::Error) } + fn contains_unknown(&self) -> bool { + self.data(Interner).flags.contains(TypeFlags::HAS_ERROR) + } + fn is_ty_var(&self) -> bool { matches!(self.kind(Interner), TyKind::InferenceVar(_, _)) } diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 869b39ab37..ef15f54d29 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -548,7 +548,7 @@ impl<'a> InferenceContext<'a> { { *ty = table.resolve_completely(ty.clone()); // FIXME: Remove this when we are on par with rustc in terms of inference - if ty.is_unknown() { + if ty.contains_unknown() { return false; } @@ -557,7 +557,7 @@ impl<'a> InferenceContext<'a> { { let clear = if let Some(ty) = field_with_same_name { *ty = table.resolve_completely(ty.clone()); - ty.is_unknown() + ty.contains_unknown() } else { false }; diff --git a/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 9754fc3f68..7de03416e5 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -129,6 +129,19 @@ fn foo() { Foo.bar; // ^^^^^^^ 💡 error: no field `bar` on type `Foo`, but a method with a similar name exists } +"#, + ); + } + + #[test] + fn no_diagnostic_on_unknown() { + check_diagnostics( + r#" +fn foo() { + x.foo; + (&x).foo; + (&((x,),),).foo; +} "#, ); }