Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22619 from Wilfred/error_type_receivers
fix: Exclude impls on the error type from impl enumeration
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 25 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/method_resolution.rs | 27 |
2 files changed, 52 insertions, 0 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 9e0188fd26..b68f664d51 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -728,7 +728,13 @@ impl TraitImpls { { continue; } + let self_ty = trait_ref.self_ty(); + if self_ty_has_error_constructor(self_ty) { + // If we see `impl Foo for NoSuchType`, just ignore it. + continue; + } + let interner = DbInterner::new_no_crate(db); let entry = map.entry(trait_ref.def_id.0).or_default(); match simplify_type(interner, self_ty, TreatParams::InstantiateWithInfer) { @@ -864,3 +870,22 @@ impl TraitImpls { } } } + +fn self_ty_has_error_constructor<'db>(mut self_ty: Ty<'db>) -> bool { + if !self_ty.references_non_lt_error() { + return false; + } + + loop { + self_ty = match self_ty.kind() { + TyKind::Error(_) => return true, + TyKind::Ref(_, inner, _) + | TyKind::RawPtr(inner, _) + | TyKind::Array(inner, _) + | TyKind::Slice(inner) + | TyKind::Pat(inner, _) => inner, + TyKind::UnsafeBinder(inner) => inner.skip_binder(), + _ => return false, + }; + } +} diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs index 2084c01853..985ecb6c5d 100644 --- a/crates/hir-ty/src/tests/method_resolution.rs +++ b/crates/hir-ty/src/tests/method_resolution.rs @@ -2258,3 +2258,30 @@ fn main() { "#, ); } + +#[test] +fn trait_impl_with_error_self_ty_does_not_match_arbitrary_receiver() { + check_types( + r#" +//- minicore: sized +trait UnrelatedTrait { + fn take(self) {} +} + +struct MyOption<T>(T); + +impl<T> MyOption<T> { + fn take(&mut self) -> MyOption<T> { + loop {} + } +} + +fn f<T>(mut o: MyOption<T>) { + let value = o.take(); + //^^^^^ MyOption<T> +} + +impl UnrelatedTrait for &'_ MissingType {} +"#, + ); +} |