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..011347e5c4 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: 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; +} +"#, + ); +} + +#[test] +fn resolve_minicore_iterator() { + check_types( + r#" +//- minicore: iterators, sized +fn foo() { + let m = core::iter::repeat(()).filter_map(|()| Some(92)).next(); +} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Option +"#, + ); +} diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index f8ca5c269c..2cd4fa809a 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 5c63e27879..8474014a2c 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 {