mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Merge #3147
3147: Check that impl self type matches up with expected self type in path mode r=matklad a=flodiebold Fixes #3144. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
b2b94cbf71
3 changed files with 42 additions and 0 deletions
|
@ -4,6 +4,7 @@ test_utils::marks!(
|
||||||
type_var_cycles_resolve_completely
|
type_var_cycles_resolve_completely
|
||||||
type_var_cycles_resolve_as_possible
|
type_var_cycles_resolve_as_possible
|
||||||
type_var_resolves_to_int_var
|
type_var_resolves_to_int_var
|
||||||
|
impl_self_type_match_without_receiver
|
||||||
match_ergonomics_ref
|
match_ergonomics_ref
|
||||||
coerce_merge_fail_fallback
|
coerce_merge_fail_fallback
|
||||||
trait_self_implements_self
|
trait_self_implements_self
|
||||||
|
|
|
@ -425,6 +425,15 @@ fn iterate_inherent_methods<T>(
|
||||||
if !is_valid_candidate(db, name, receiver_ty, item, self_ty) {
|
if !is_valid_candidate(db, name, receiver_ty, item, self_ty) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// we have to check whether the self type unifies with the type
|
||||||
|
// that the impl is for. If we have a receiver type, this
|
||||||
|
// already happens in `is_valid_candidate` above; if not, we
|
||||||
|
// check it here
|
||||||
|
if receiver_ty.is_none() && inherent_impl_substs(db, impl_block, self_ty).is_none()
|
||||||
|
{
|
||||||
|
test_utils::tested_by!(impl_self_type_match_without_receiver);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some(result) = callback(&self_ty.value, item) {
|
if let Some(result) = callback(&self_ty.value, item) {
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -963,6 +963,38 @@ fn test() { S2.into()<|>; }
|
||||||
assert_eq!(t, "{unknown}");
|
assert_eq!(t, "{unknown}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn method_resolution_overloaded_method() {
|
||||||
|
test_utils::covers!(impl_self_type_match_without_receiver);
|
||||||
|
let t = type_at(
|
||||||
|
r#"
|
||||||
|
//- main.rs
|
||||||
|
struct Wrapper<T>(T);
|
||||||
|
struct Foo<T>(T);
|
||||||
|
struct Bar<T>(T);
|
||||||
|
|
||||||
|
impl<T> Wrapper<Foo<T>> {
|
||||||
|
pub fn new(foo_: T) -> Self {
|
||||||
|
Wrapper(Foo(foo_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Wrapper<Bar<T>> {
|
||||||
|
pub fn new(bar_: T) -> Self {
|
||||||
|
Wrapper(Bar(bar_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a = Wrapper::<Foo<f32>>::new(1.0);
|
||||||
|
let b = Wrapper::<Bar<f32>>::new(1.0);
|
||||||
|
(a, b)<|>;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
assert_eq!(t, "(Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)")
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn method_resolution_encountering_fn_type() {
|
fn method_resolution_encountering_fn_type() {
|
||||||
type_at(
|
type_at(
|
||||||
|
|
Loading…
Reference in a new issue