Merge pull request #21434 from ChayimFriedman2/traits-mix
fix: Remove code made redundant by method resolution rewrite
This commit is contained in:
commit
25c0131519
3 changed files with 88 additions and 45 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {}': !
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue