Unnamed repository; edit this file 'description' to name the repository.
Don't try to resolve methods on unknown types
Fixes #10454, and some type mismatches.
Florian Diebold 2022-03-24
parent 5d2cd18 · commit 8d98f3c
-rw-r--r--crates/hir_ty/src/autoderef.rs7
-rw-r--r--crates/hir_ty/src/method_resolution.rs5
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs55
3 files changed, 65 insertions, 2 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dffb36b5de..22cb856535 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -108,8 +108,13 @@ fn builtin_deref(ty: &Ty) -> Option<&Ty> {
}
fn deref_by_trait(table: &mut InferenceTable, ty: Ty) -> Option<Ty> {
- let db = table.db;
let _p = profile::span("deref_by_trait");
+ if table.resolve_ty_shallow(&ty).inference_var(Interner).is_some() {
+ // don't try to deref unknown variables
+ return None;
+ }
+
+ let db = table.db;
let deref_trait = db
.lang_item(table.trait_env.krate, SmolStr::new_inline("deref"))
.and_then(|l| l.as_trait())?;
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 1c939f3d8a..768772d5c3 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -681,6 +681,11 @@ fn iterate_method_candidates_with_autoref(
name: Option<&Name>,
mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
) -> ControlFlow<()> {
+ if receiver_ty.value.is_general_var(Interner, &receiver_ty.binders) {
+ // don't try to resolve methods on unknown types
+ return ControlFlow::Continue(());
+ }
+
iterate_method_candidates_by_receiver(
receiver_ty,
first_adjustment.clone(),
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 56b8db1319..95957f6235 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -2,7 +2,7 @@ use expect_test::expect;
use crate::tests::check;
-use super::{check_infer, check_types};
+use super::{check_infer, check_no_mismatches, check_types};
#[test]
fn infer_slice_method() {
@@ -1697,3 +1697,56 @@ fn test() {
"#,
);
}
+
+#[test]
+fn bad_inferred_reference_1() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized
+pub trait Into<T>: Sized {
+ fn into(self) -> T;
+}
+impl<T> Into<T> for T {
+ fn into(self) -> T { self }
+}
+
+trait ExactSizeIterator {
+ fn len(&self) -> usize;
+}
+
+pub struct Foo;
+impl Foo {
+ fn len(&self) -> usize { 0 }
+}
+
+pub fn test(generic_args: impl Into<Foo>) {
+ let generic_args = generic_args.into();
+ generic_args.len();
+ let _: Foo = generic_args;
+}
+"#,
+ );
+}
+
+#[test]
+fn bad_inferred_reference_2() {
+ check_no_mismatches(
+ r#"
+//- minicore: deref
+trait ExactSizeIterator {
+ fn len(&self) -> usize;
+}
+
+pub struct Foo;
+impl Foo {
+ fn len(&self) -> usize { 0 }
+}
+
+pub fn test() {
+ let generic_args;
+ generic_args.len();
+ let _: Foo = generic_args;
+}
+"#,
+ );
+}