Skip to content

Commit

Permalink
Unrolled build for rust-lang#135179
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#135179 - compiler-errors:arbitrary-self-types-object, r=BoxyUwU

Make sure to use `Receiver` trait when extracting object method candidate

In method confirmation, the `extract_existential_trait_ref` function re-extracts the object type by derefing until it reaches an object. If we're assembling methods via the `Receiver` trait, make sure we re-do our work also using the receiver trait.

Fixes rust-lang#135155

cc ``@adetaylor``
  • Loading branch information
rust-timer authored Feb 8, 2025
2 parents e060723 + 999695b commit 4aa5db5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
14 changes: 11 additions & 3 deletions compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// yield an object-type (e.g., `&Object` or `Box<Object>`
// etc).

// FIXME: this feels, like, super dubious
self.fcx
.autoderef(self.span, self_ty)
let mut autoderef = self.fcx.autoderef(self.span, self_ty);

// We don't need to gate this behind arbitrary self types
// per se, but it does make things a bit more gated.
if self.tcx.features().arbitrary_self_types()
|| self.tcx.features().arbitrary_self_types_pointers()
{
autoderef = autoderef.use_receiver_trait();
}

autoderef
.include_raw_pointers()
.find_map(|(ty, _)| match ty.kind() {
ty::Dynamic(data, ..) => Some(closure(
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ check-pass

#![feature(derive_coerce_pointee)]
#![feature(arbitrary_self_types)]

use std::marker::CoercePointee;
use std::ops::Receiver;

// `CoercePointee` isn't needed here, it's just a simpler
// (and more conceptual) way of deriving `DispatchFromDyn`.
// You could think of `MyDispatcher` as a smart pointer
// that just doesn't deref to its target type.
#[derive(CoercePointee)]
#[repr(transparent)]
struct MyDispatcher<T: ?Sized>(*const T);

impl<T: ?Sized> Receiver for MyDispatcher<T> {
type Target = T;
}
struct Test;

trait Trait {
fn test(self: MyDispatcher<Self>);
}

impl Trait for Test {
fn test(self: MyDispatcher<Self>) {
todo!()
}
}
fn main() {
MyDispatcher::<dyn Trait>(core::ptr::null_mut::<Test>()).test();
}

0 comments on commit 4aa5db5

Please sign in to comment.