diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 226e9f5cd667..62339779a562 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -1704,7 +1704,7 @@ impl<'db> InferenceContext<'_, 'db> { }); match resolved { Ok((func, _is_visible)) => { - self.check_method_call(tgt_expr, &[], func.sig, receiver_ty, expected) + self.check_method_call(tgt_expr, &[], func.sig, expected) } Err(_) => self.err_ty(), } @@ -1844,7 +1844,7 @@ impl<'db> InferenceContext<'_, 'db> { item: func.def_id.into(), }) } - self.check_method_call(tgt_expr, args, func.sig, receiver_ty, expected) + self.check_method_call(tgt_expr, args, func.sig, expected) } // Failed to resolve, report diagnostic and try to resolve as call to field access or // assoc function @@ -1934,16 +1934,14 @@ impl<'db> InferenceContext<'_, 'db> { tgt_expr: ExprId, args: &[ExprId], sig: FnSig<'db>, - receiver_ty: Ty<'db>, expected: &Expectation<'db>, ) -> Ty<'db> { - let (formal_receiver_ty, param_tys) = if !sig.inputs_and_output.inputs().is_empty() { - (sig.inputs_and_output.as_slice()[0], &sig.inputs_and_output.inputs()[1..]) + let param_tys = if !sig.inputs_and_output.inputs().is_empty() { + &sig.inputs_and_output.inputs()[1..] } else { - (self.types.types.error, &[] as _) + &[] }; let ret_ty = sig.output(); - self.table.unify(formal_receiver_ty, receiver_ty); self.check_call_arguments(tgt_expr, param_tys, ret_ty, expected, args, &[], sig.c_variadic); ret_ty diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index c805f030446c..df49d7999fee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -891,13 +891,14 @@ use core::ops::Deref; struct BufWriter {} -struct Mutex {} -struct MutexGuard<'a, T> {} +struct Mutex(T); +struct MutexGuard<'a, T>(&'a T); impl Mutex { fn lock(&self) -> MutexGuard<'_, T> {} } impl<'a, T: 'a> Deref for MutexGuard<'a, T> { type Target = T; + fn deref(&self) -> &Self::Target { loop {} } } fn flush(&self) { let w: &Mutex; @@ -905,14 +906,18 @@ fn flush(&self) { } "#, expect![[r#" - 123..127 'self': &'? Mutex - 150..152 '{}': MutexGuard<'?, T> - 234..238 'self': &'? {unknown} - 240..290 '{ ...()); }': () - 250..251 'w': &'? Mutex - 276..287 '*(w.lock())': BufWriter - 278..279 'w': &'? Mutex - 278..286 'w.lock()': MutexGuard<'?, BufWriter> + 129..133 'self': &'? Mutex + 156..158 '{}': MutexGuard<'?, T> + 242..246 'self': &'? MutexGuard<'a, T> + 265..276 '{ loop {} }': &'? T + 267..274 'loop {}': ! + 272..274 '{}': () + 289..293 'self': &'? {unknown} + 295..345 '{ ...()); }': () + 305..306 'w': &'? Mutex + 331..342 '*(w.lock())': BufWriter + 333..334 'w': &'? Mutex + 333..341 'w.lock()': MutexGuard<'?, BufWriter> "#]], ); } @@ -2563,3 +2568,33 @@ fn main() { "#, ); } + +#[test] +fn regression_21429() { + check_no_mismatches( + r#" +trait DatabaseLike { + type ForeignKey: ForeignKeyLike; +} + +trait ForeignKeyLike { + type DB: DatabaseLike; + + fn host_columns(&self, database: &Self::DB); +} + +trait ColumnLike { + type DB: DatabaseLike; + + fn foo() -> &&<::DB as DatabaseLike>::ForeignKey { + loop {} + } + + fn foreign_keys(&self, database: &Self::DB) { + let fk = Self::foo(); + fk.host_columns(database); + } +} + "#, + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 38591f486e97..b825a0a8f0e5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -429,7 +429,7 @@ fn associated_type_shorthand_from_method_bound() { trait Iterable { type Item; } -struct S; +struct S(T); impl S { fn foo(self) -> T::Item where T: Iterable { loop {} } } @@ -1103,40 +1103,50 @@ fn test() { fn argument_impl_trait_type_args_2() { check_infer_with_mismatches( r#" -//- minicore: sized +//- minicore: sized, phantom_data +use core::marker::PhantomData; + trait Trait {} struct S; impl Trait for S {} -struct F; +struct F(PhantomData); impl F { fn foo(self, x: impl Trait) -> (T, U) { loop {} } } fn test() { - F.foo(S); - F::.foo(S); - F::.foo::(S); - F::.foo::(S); // extraneous argument should be ignored + F(PhantomData).foo(S); + F::(PhantomData).foo(S); + F::(PhantomData).foo::(S); + F::(PhantomData).foo::(S); // extraneous argument should be ignored }"#, expect![[r#" - 87..91 'self': F - 93..94 'x': impl Trait - 118..129 '{ loop {} }': (T, U) - 120..127 'loop {}': ! - 125..127 '{}': () - 143..283 '{ ...ored }': () - 149..150 'F': F<{unknown}> - 149..157 'F.foo(S)': ({unknown}, {unknown}) - 155..156 'S': S - 163..171 'F::': F - 163..178 'F::.foo(S)': (u32, {unknown}) - 176..177 'S': S - 184..192 'F::': F - 184..206 'F::(S)': (u32, i32) - 204..205 'S': S - 212..220 'F::': F - 212..239 'F::(S)': (u32, i32) - 237..238 'S': S + 135..139 'self': F + 141..142 'x': impl Trait + 166..177 '{ loop {} }': (T, U) + 168..175 'loop {}': ! + 173..175 '{}': () + 191..383 '{ ...ored }': () + 197..198 'F': fn F<{unknown}>(PhantomData<{unknown}>) -> F<{unknown}> + 197..211 'F(PhantomData)': F<{unknown}> + 197..218 'F(Phan...foo(S)': ({unknown}, {unknown}) + 199..210 'PhantomData': PhantomData<{unknown}> + 216..217 'S': S + 224..232 'F::': fn F(PhantomData) -> F + 224..245 'F:: + 224..252 'F:: + 250..251 'S': S + 258..266 'F::': fn F(PhantomData) -> F + 258..279 'F:: + 258..293 'F::(S)': (u32, i32) + 267..278 'PhantomData': PhantomData + 291..292 'S': S + 299..307 'F::': fn F(PhantomData) -> F + 299..320 'F:: + 299..339 'F::(S)': (u32, i32) + 308..319 'PhantomData': PhantomData + 337..338 'S': S "#]], ); } @@ -4012,7 +4022,7 @@ fn f() { fn dyn_map() { check_types( r#" -pub struct Key {} +pub struct Key(K, V, P); pub trait Policy { type K; @@ -4024,7 +4034,7 @@ impl Policy for (K, V) { type V = V; } -pub struct KeyMap {} +pub struct KeyMap(KEY); impl KeyMap> { pub fn get(&self, key: &P::K) -> P::V { @@ -5023,7 +5033,7 @@ fn main() { 278..280 '{}': () 290..291 '_': Box + '?> 294..298 'iter': Box + 'static> - 294..310 'iter.i...iter()': Box + 'static> + 294..310 'iter.i...iter()': Box + '?> 152..156 'self': &'? mut Box 177..208 '{ ... }': Option<::Item> 191..198 'loop {}': !