Skip to content

Commit 42dfdb8

Browse files
bors[bot]cynecx
andauthored
Merge #9090
9090: hir_ty: use correct receiver_ty in method resolution r=cynecx a=cynecx Fixes #8100. Co-authored-by: cynecx <[email protected]>
2 parents a127b10 + 759cb07 commit 42dfdb8

File tree

3 files changed

+82
-12
lines changed

3 files changed

+82
-12
lines changed

crates/hir_ty/src/infer/expr.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ impl<'a> InferenceContext<'a> {
890890
method_name,
891891
)
892892
});
893-
let (derefed_receiver_ty, method_ty, substs) = match resolved {
893+
let (receiver_ty, method_ty, substs) = match resolved {
894894
Some((ty, func)) => {
895895
let ty = canonicalized_receiver.decanonicalize_ty(ty);
896896
let generics = generics(self.db.upcast(), func.into());
@@ -916,16 +916,7 @@ impl<'a> InferenceContext<'a> {
916916
}
917917
None => (self.err_ty(), Vec::new(), self.err_ty()),
918918
};
919-
// Apply autoref so the below unification works correctly
920-
// FIXME: return correct autorefs from lookup_method
921-
let actual_receiver_ty = match self.resolve_ty_shallow(&expected_receiver_ty).as_reference()
922-
{
923-
Some((_, lifetime, mutability)) => {
924-
TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
925-
}
926-
_ => derefed_receiver_ty,
927-
};
928-
self.unify(&expected_receiver_ty, &actual_receiver_ty);
919+
self.unify(&expected_receiver_ty, &receiver_ty);
929920

930921
self.check_call_arguments(args, &param_tys);
931922
self.normalize_associated_types_in(ret_ty)

crates/hir_ty/src/method_resolution.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,8 @@ fn iterate_inherent_methods(
721721
cov_mark::hit!(impl_self_type_match_without_receiver);
722722
continue;
723723
}
724-
if callback(&self_ty.value, item) {
724+
let receiver_ty = receiver_ty.map(|x| &x.value).unwrap_or(&self_ty.value);
725+
if callback(receiver_ty, item) {
725726
return true;
726727
}
727728
}

crates/hir_ty/src/tests/simple.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,3 +2634,81 @@ fn f() {
26342634
"#]],
26352635
)
26362636
}
2637+
2638+
#[test]
2639+
fn infer_boxed_self_receiver() {
2640+
check_infer(
2641+
r#"
2642+
#[lang = "deref"]
2643+
pub trait Deref {
2644+
type Target;
2645+
fn deref(&self) -> &Self::Target;
2646+
}
2647+
2648+
struct Box<T>(T);
2649+
2650+
impl<T> Deref for Box<T> {
2651+
type Target = T;
2652+
fn deref(&self) -> &Self::Target;
2653+
}
2654+
2655+
struct Foo<T>(T);
2656+
2657+
impl<T> Foo<T> {
2658+
fn get_inner<'a>(self: &'a Box<Self>) -> &'a T {}
2659+
2660+
fn get_self<'a>(self: &'a Box<Self>) -> &'a Self {}
2661+
2662+
fn into_inner(self: Box<Self>) -> Self {}
2663+
}
2664+
2665+
fn main() {
2666+
let boxed = Box(Foo(0_i32));
2667+
2668+
let bad1 = boxed.get_inner();
2669+
let good1 = Foo::get_inner(&boxed);
2670+
2671+
let bad2 = boxed.get_self();
2672+
let good2 = Foo::get_self(&boxed);
2673+
2674+
let inner = boxed.into_inner();
2675+
}
2676+
"#,
2677+
expect![[r#"
2678+
67..71 'self': &Self
2679+
175..179 'self': &Box<T>
2680+
259..263 'self': &Box<Foo<T>>
2681+
289..291 '{}': ()
2682+
313..317 'self': &Box<Foo<T>>
2683+
346..348 '{}': ()
2684+
368..372 'self': Box<Foo<T>>
2685+
393..395 '{}': ()
2686+
409..630 '{ ...r(); }': ()
2687+
419..424 'boxed': Box<Foo<i32>>
2688+
427..430 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
2689+
427..442 'Box(Foo(0_i32))': Box<Foo<i32>>
2690+
431..434 'Foo': Foo<i32>(i32) -> Foo<i32>
2691+
431..441 'Foo(0_i32)': Foo<i32>
2692+
435..440 '0_i32': i32
2693+
453..457 'bad1': &i32
2694+
460..465 'boxed': Box<Foo<i32>>
2695+
460..477 'boxed....nner()': &i32
2696+
487..492 'good1': &i32
2697+
495..509 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
2698+
495..517 'Foo::g...boxed)': &i32
2699+
510..516 '&boxed': &Box<Foo<i32>>
2700+
511..516 'boxed': Box<Foo<i32>>
2701+
528..532 'bad2': &Foo<i32>
2702+
535..540 'boxed': Box<Foo<i32>>
2703+
535..551 'boxed....self()': &Foo<i32>
2704+
561..566 'good2': &Foo<i32>
2705+
569..582 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
2706+
569..590 'Foo::g...boxed)': &Foo<i32>
2707+
583..589 '&boxed': &Box<Foo<i32>>
2708+
584..589 'boxed': Box<Foo<i32>>
2709+
601..606 'inner': Foo<i32>
2710+
609..614 'boxed': Box<Foo<i32>>
2711+
609..627 'boxed....nner()': Foo<i32>
2712+
"#]],
2713+
);
2714+
}

0 commit comments

Comments
 (0)