mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 20:54:13 +00:00
hir_ty: use correct receiver_ty in method resolution
This commit is contained in:
parent
7c1d8ca635
commit
759cb07891
@ -890,7 +890,7 @@ impl<'a> InferenceContext<'a> {
|
||||
method_name,
|
||||
)
|
||||
});
|
||||
let (derefed_receiver_ty, method_ty, substs) = match resolved {
|
||||
let (receiver_ty, method_ty, substs) = match resolved {
|
||||
Some((ty, func)) => {
|
||||
let ty = canonicalized_receiver.decanonicalize_ty(ty);
|
||||
let generics = generics(self.db.upcast(), func.into());
|
||||
@ -916,16 +916,7 @@ impl<'a> InferenceContext<'a> {
|
||||
}
|
||||
None => (self.err_ty(), Vec::new(), self.err_ty()),
|
||||
};
|
||||
// Apply autoref so the below unification works correctly
|
||||
// FIXME: return correct autorefs from lookup_method
|
||||
let actual_receiver_ty = match self.resolve_ty_shallow(&expected_receiver_ty).as_reference()
|
||||
{
|
||||
Some((_, lifetime, mutability)) => {
|
||||
TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
|
||||
}
|
||||
_ => derefed_receiver_ty,
|
||||
};
|
||||
self.unify(&expected_receiver_ty, &actual_receiver_ty);
|
||||
self.unify(&expected_receiver_ty, &receiver_ty);
|
||||
|
||||
self.check_call_arguments(args, ¶m_tys);
|
||||
self.normalize_associated_types_in(ret_ty)
|
||||
|
@ -721,7 +721,8 @@ fn iterate_inherent_methods(
|
||||
cov_mark::hit!(impl_self_type_match_without_receiver);
|
||||
continue;
|
||||
}
|
||||
if callback(&self_ty.value, item) {
|
||||
let receiver_ty = receiver_ty.map(|x| &x.value).unwrap_or(&self_ty.value);
|
||||
if callback(receiver_ty, item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2634,3 +2634,81 @@ fn f() {
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_boxed_self_receiver() {
|
||||
check_infer(
|
||||
r#"
|
||||
#[lang = "deref"]
|
||||
pub trait Deref {
|
||||
type Target;
|
||||
fn deref(&self) -> &Self::Target;
|
||||
}
|
||||
|
||||
struct Box<T>(T);
|
||||
|
||||
impl<T> Deref for Box<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &Self::Target;
|
||||
}
|
||||
|
||||
struct Foo<T>(T);
|
||||
|
||||
impl<T> Foo<T> {
|
||||
fn get_inner<'a>(self: &'a Box<Self>) -> &'a T {}
|
||||
|
||||
fn get_self<'a>(self: &'a Box<Self>) -> &'a Self {}
|
||||
|
||||
fn into_inner(self: Box<Self>) -> Self {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let boxed = Box(Foo(0_i32));
|
||||
|
||||
let bad1 = boxed.get_inner();
|
||||
let good1 = Foo::get_inner(&boxed);
|
||||
|
||||
let bad2 = boxed.get_self();
|
||||
let good2 = Foo::get_self(&boxed);
|
||||
|
||||
let inner = boxed.into_inner();
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
67..71 'self': &Self
|
||||
175..179 'self': &Box<T>
|
||||
259..263 'self': &Box<Foo<T>>
|
||||
289..291 '{}': ()
|
||||
313..317 'self': &Box<Foo<T>>
|
||||
346..348 '{}': ()
|
||||
368..372 'self': Box<Foo<T>>
|
||||
393..395 '{}': ()
|
||||
409..630 '{ ...r(); }': ()
|
||||
419..424 'boxed': Box<Foo<i32>>
|
||||
427..430 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
|
||||
427..442 'Box(Foo(0_i32))': Box<Foo<i32>>
|
||||
431..434 'Foo': Foo<i32>(i32) -> Foo<i32>
|
||||
431..441 'Foo(0_i32)': Foo<i32>
|
||||
435..440 '0_i32': i32
|
||||
453..457 'bad1': &i32
|
||||
460..465 'boxed': Box<Foo<i32>>
|
||||
460..477 'boxed....nner()': &i32
|
||||
487..492 'good1': &i32
|
||||
495..509 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
|
||||
495..517 'Foo::g...boxed)': &i32
|
||||
510..516 '&boxed': &Box<Foo<i32>>
|
||||
511..516 'boxed': Box<Foo<i32>>
|
||||
528..532 'bad2': &Foo<i32>
|
||||
535..540 'boxed': Box<Foo<i32>>
|
||||
535..551 'boxed....self()': &Foo<i32>
|
||||
561..566 'good2': &Foo<i32>
|
||||
569..582 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
|
||||
569..590 'Foo::g...boxed)': &Foo<i32>
|
||||
583..589 '&boxed': &Box<Foo<i32>>
|
||||
584..589 'boxed': Box<Foo<i32>>
|
||||
601..606 'inner': Foo<i32>
|
||||
609..614 'boxed': Box<Foo<i32>>
|
||||
609..627 'boxed....nner()': Foo<i32>
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user