Unnamed repository; edit this file 'description' to name the repository.
Remove code made redundant by method resolution rewrite
Its job is now done elsewhere, and it's also wrong (not accounting for autoderef)
Chayim Refael Friedman 3 months ago
parent 36a2b8f · commit 1816f9c
-rw-r--r--crates/hir-ty/src/infer/expr.rs12
-rw-r--r--crates/hir-ty/src/tests/regression.rs55
-rw-r--r--crates/hir-ty/src/tests/traits.rs66
3 files changed, 88 insertions, 45 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 226e9f5cd6..62339779a5 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/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/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index c805f03044..df49d7999f 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -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);
+ }
+}
+ "#,
+ );
+}
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 38591f486e..b825a0a8f0 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -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 {}': !