Merge pull request #21434 from ChayimFriedman2/traits-mix

fix: Remove code made redundant by method resolution rewrite
This commit is contained in:
Shoyu Vanilla (Flint) 2026-01-10 12:49:22 +00:00 committed by GitHub
commit 25c0131519
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 88 additions and 45 deletions

View file

@ -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

View file

@ -891,13 +891,14 @@ use core::ops::Deref;
struct BufWriter {}
struct Mutex<T> {}
struct MutexGuard<'a, T> {}
struct Mutex<T>(T);
struct MutexGuard<'a, T>(&'a T);
impl<T> Mutex<T> {
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<BufWriter>;
@ -905,14 +906,18 @@ fn flush(&self) {
}
"#,
expect![[r#"
123..127 'self': &'? Mutex<T>
150..152 '{}': MutexGuard<'?, T>
234..238 'self': &'? {unknown}
240..290 '{ ...()); }': ()
250..251 'w': &'? Mutex<BufWriter>
276..287 '*(w.lock())': BufWriter
278..279 'w': &'? Mutex<BufWriter>
278..286 'w.lock()': MutexGuard<'?, BufWriter>
129..133 'self': &'? Mutex<T>
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<BufWriter>
331..342 '*(w.lock())': BufWriter
333..334 'w': &'? Mutex<BufWriter>
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<DB = Self>;
}
trait ForeignKeyLike {
type DB: DatabaseLike;
fn host_columns(&self, database: &Self::DB);
}
trait ColumnLike {
type DB: DatabaseLike;
fn foo() -> &&<<Self as ColumnLike>::DB as DatabaseLike>::ForeignKey {
loop {}
}
fn foreign_keys(&self, database: &Self::DB) {
let fk = Self::foo();
fk.host_columns(database);
}
}
"#,
);
}

View file

@ -429,7 +429,7 @@ fn associated_type_shorthand_from_method_bound() {
trait Iterable {
type Item;
}
struct S<T>;
struct S<T>(T);
impl<T> S<T> {
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<T>;
struct F<T>(PhantomData<T>);
impl<T> F<T> {
fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
}
fn test() {
F.foo(S);
F::<u32>.foo(S);
F::<u32>.foo::<i32>(S);
F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
F(PhantomData).foo(S);
F::<u32>(PhantomData).foo(S);
F::<u32>(PhantomData).foo::<i32>(S);
F::<u32>(PhantomData).foo::<i32, u32>(S); // extraneous argument should be ignored
}"#,
expect![[r#"
87..91 'self': F<T>
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::<u32>': F<u32>
163..178 'F::<u32>.foo(S)': (u32, {unknown})
176..177 'S': S
184..192 'F::<u32>': F<u32>
184..206 'F::<u3...32>(S)': (u32, i32)
204..205 'S': S
212..220 'F::<u32>': F<u32>
212..239 'F::<u3...32>(S)': (u32, i32)
237..238 'S': S
135..139 'self': F<T>
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::<u32>': fn F<u32>(PhantomData<u32>) -> F<u32>
224..245 'F::<u3...mData)': F<u32>
224..252 'F::<u3...foo(S)': (u32, {unknown})
233..244 'PhantomData': PhantomData<u32>
250..251 'S': S
258..266 'F::<u32>': fn F<u32>(PhantomData<u32>) -> F<u32>
258..279 'F::<u3...mData)': F<u32>
258..293 'F::<u3...32>(S)': (u32, i32)
267..278 'PhantomData': PhantomData<u32>
291..292 'S': S
299..307 'F::<u32>': fn F<u32>(PhantomData<u32>) -> F<u32>
299..320 'F::<u3...mData)': F<u32>
299..339 'F::<u3...32>(S)': (u32, i32)
308..319 'PhantomData': PhantomData<u32>
337..338 'S': S
"#]],
);
}
@ -4012,7 +4022,7 @@ fn f<F: Foo>() {
fn dyn_map() {
check_types(
r#"
pub struct Key<K, V, P = (K, V)> {}
pub struct Key<K, V, P = (K, V)>(K, V, P);
pub trait Policy {
type K;
@ -4024,7 +4034,7 @@ impl<K, V> Policy for (K, V) {
type V = V;
}
pub struct KeyMap<KEY> {}
pub struct KeyMap<KEY>(KEY);
impl<P: Policy> KeyMap<Key<P::K, P::V, P>> {
pub fn get(&self, key: &P::K) -> P::V {
@ -5023,7 +5033,7 @@ fn main() {
278..280 '{}': ()
290..291 '_': Box<dyn Iterator<Item = &'? [u8]> + '?>
294..298 'iter': Box<dyn Iterator<Item = &'? [u8]> + 'static>
294..310 'iter.i...iter()': Box<dyn Iterator<Item = &'? [u8]> + 'static>
294..310 'iter.i...iter()': Box<dyn Iterator<Item = &'? [u8]> + '?>
152..156 'self': &'? mut Box<I>
177..208 '{ ... }': Option<<I as Iterator>::Item>
191..198 'loop {}': !