about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-23 20:20:09 +0000
committerGitHub <noreply@github.com>2022-03-23 20:20:09 +0000
commit75fada4aabdc15d87fe7b63a98d4ce5410ea30f9 (patch)
treee7699677eea50fd0cdbabda362cbf482c829366e
parentde5925da5c4f5840781a8a6481ffa3289c413e4c (diff)
parente0e6bfb9242fad53e3ed49c59e23eaf6653ff13e (diff)
downloadrust-75fada4aabdc15d87fe7b63a98d4ce5410ea30f9.tar.gz
rust-75fada4aabdc15d87fe7b63a98d4ce5410ea30f9.zip
Merge #11805
11805: fix: Don't try to resolve methods on unknown types r=Veykril a=flodiebold

Fixes #10454, and some type mismatches.

Co-authored-by: Florian Diebold <flodiebold@gmail.com>
-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.rs67
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs2
-rw-r--r--crates/test_utils/src/minicore.rs2
5 files changed, 79 insertions, 4 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dffb36b5de3..22cb856535e 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 1c939f3d8aa..768772d5c34 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 56b8db1319e..011347e5c45 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,68 @@ 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;
+}
+"#,
+    );
+}
+
+#[test]
+fn resolve_minicore_iterator() {
+    check_types(
+        r#"
+//- minicore: iterators, sized
+fn foo() {
+    let m = core::iter::repeat(()).filter_map(|()| Some(92)).next();
+}         //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Option<i32>
+"#,
+    );
+}
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index f8ca5c269c4..2cd4fa809a4 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1018,5 +1018,5 @@ fn benchmark_syntax_highlighting_parser() {
             .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))
             .count()
     };
-    assert_eq!(hash, 1616);
+    assert_eq!(hash, 1609);
 }
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index 5c63e27879d..8474014a2cb 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -518,7 +518,7 @@ pub mod iter {
             }
         }
     }
-    pub use self::adapters::Take;
+    pub use self::adapters::{Take, FilterMap};
 
     mod sources {
         mod repeat {