about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-07 14:25:20 +0000
committerbors <bors@rust-lang.org>2023-03-07 14:25:20 +0000
commitecc32c2f8517576b26060915bcb0cdb00cafd060 (patch)
tree5c6a8a5d788e827ccc77c215a8a1d3867f4db18a
parent44ff3c407a9db70f0c8f02b04d73ab1f883f37fe (diff)
parentd45708fabe1f43b0c229b6b5222b7a2d5420d07e (diff)
downloadrust-ecc32c2f8517576b26060915bcb0cdb00cafd060.tar.gz
rust-ecc32c2f8517576b26060915bcb0cdb00cafd060.zip
Auto merge of #14271 - Veykril:ty-diag-err, r=Veykril
Don't trigger unresolved method/field diagnostics on types containing errors
-rw-r--r--crates/hir-ty/src/chalk_ext.rs7
-rw-r--r--crates/hir-ty/src/infer.rs4
-rw-r--r--crates/ide-diagnostics/src/handlers/unresolved_field.rs13
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 45c975dfcdc..e6aefbf2716 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 3a75f871211..7de5b4295fc 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -567,7 +567,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;
                 }
 
@@ -576,7 +576,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 9754fc3f68b..7de03416e56 100644
--- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs
+++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs
@@ -132,4 +132,17 @@ fn foo() {
 "#,
         );
     }
+
+    #[test]
+    fn no_diagnostic_on_unknown() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    x.foo;
+    (&x).foo;
+    (&((x,),),).foo;
+}
+"#,
+        );
+    }
 }