From 8d98f3c983960c99b871e8d7398a6706d93e43f7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 23 Mar 2022 19:18:12 +0100 Subject: [PATCH] Don't try to resolve methods on unknown types Fixes #10454, and some type mismatches. --- crates/hir_ty/src/autoderef.rs | 7 ++- crates/hir_ty/src/method_resolution.rs | 5 ++ crates/hir_ty/src/tests/method_resolution.rs | 55 +++++++++++++++++++- 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 { - 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: Sized { + fn into(self) -> T; +} +impl Into 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) { + 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; +} +"#, + ); +}