Don't trigger unresolved method/field diagnostics on types containing errors

This commit is contained in:
Lukas Wirth 2023-03-07 15:24:43 +01:00
parent 31c12ec282
commit d45708fabe
3 changed files with 21 additions and 3 deletions

View file

@ -13,7 +13,7 @@ use crate::{
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, 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, from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, 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 { pub trait TyExt {
@ -22,6 +22,7 @@ pub trait TyExt {
fn is_floating_point(&self) -> bool; fn is_floating_point(&self) -> bool;
fn is_never(&self) -> bool; fn is_never(&self) -> bool;
fn is_unknown(&self) -> bool; fn is_unknown(&self) -> bool;
fn contains_unknown(&self) -> bool;
fn is_ty_var(&self) -> bool; fn is_ty_var(&self) -> bool;
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>; fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
@ -76,6 +77,10 @@ impl TyExt for Ty {
matches!(self.kind(Interner), TyKind::Error) 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 { fn is_ty_var(&self) -> bool {
matches!(self.kind(Interner), TyKind::InferenceVar(_, _)) matches!(self.kind(Interner), TyKind::InferenceVar(_, _))
} }

View file

@ -548,7 +548,7 @@ impl<'a> InferenceContext<'a> {
{ {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
// FIXME: Remove this when we are on par with rustc in terms of inference // FIXME: Remove this when we are on par with rustc in terms of inference
if ty.is_unknown() { if ty.contains_unknown() {
return false; return false;
} }
@ -557,7 +557,7 @@ impl<'a> InferenceContext<'a> {
{ {
let clear = if let Some(ty) = field_with_same_name { let clear = if let Some(ty) = field_with_same_name {
*ty = table.resolve_completely(ty.clone()); *ty = table.resolve_completely(ty.clone());
ty.is_unknown() ty.contains_unknown()
} else { } else {
false false
}; };

View file

@ -129,6 +129,19 @@ fn foo() {
Foo.bar; Foo.bar;
// ^^^^^^^ 💡 error: no field `bar` on type `Foo`, but a method with a similar name exists // ^^^^^^^ 💡 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;
}
"#, "#,
); );
} }