Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/method_resolution.rs9
-rw-r--r--crates/hir-ty/src/tests/method_resolution.rs39
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs2
3 files changed, 47 insertions, 3 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index c07bd08be4..8ba8071d36 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -30,8 +30,8 @@ use crate::{
utils::all_super_traits,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData,
Goal, Guidance, InEnvironment, Interner, Mutability, Scalar, Solution, Substitution,
- TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, VariableKind,
- WhereClause,
+ TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TyVariableKind,
+ VariableKind, WhereClause,
};
/// This is used as a key for indexing impls.
@@ -1083,6 +1083,11 @@ fn iterate_method_candidates_by_receiver(
table.run_in_snapshot(|table| {
let mut autoderef = autoderef::Autoderef::new(table, receiver_ty.clone(), true);
while let Some((self_ty, _)) = autoderef.next() {
+ if matches!(self_ty.kind(Interner), TyKind::InferenceVar(_, TyVariableKind::General)) {
+ // don't try to resolve methods on unknown types
+ return ControlFlow::Continue(());
+ }
+
iterate_trait_method_candidates(
&self_ty,
autoderef.table,
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index 360a129283..14e2e74653 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -2099,3 +2099,42 @@ fn test() {
"#,
);
}
+
+#[test]
+fn mismatched_args_due_to_supertraits_with_deref() {
+ check_no_mismatches(
+ r#"
+//- minicore: deref
+use core::ops::Deref;
+
+trait Trait1 {
+ type Assoc: Deref<Target = String>;
+}
+
+trait Trait2: Trait1 {
+}
+
+trait Trait3 {
+ type T1: Trait1;
+ type T2: Trait2;
+ fn bar(&self, x: bool, y: bool);
+}
+
+struct Foo;
+
+impl Foo {
+ fn bar(&mut self, _: &'static str) {}
+}
+
+impl Deref for Foo {
+ type Target = u32;
+ fn deref(&self) -> &Self::Target { &0 }
+}
+
+fn problem_method<T: Trait3>() {
+ let mut foo = Foo;
+ foo.bar("hello"); // Rustc ok, RA errors (mismatched args)
+}
+"#,
+ );
+}
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 5f711600a2..2070022d41 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1238,7 +1238,7 @@ fn benchmark_syntax_highlighting_parser() {
})
.count()
};
- assert_eq!(hash, 1169);
+ assert_eq!(hash, 1167);
}
#[test]