Rollup merge of #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 #135155 cc ``@adetaylor``
This commit is contained in:
commit
c49fc911f4
2 changed files with 44 additions and 3 deletions
|
@ -347,9 +347,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
// yield an object-type (e.g., `&Object` or `Box<Object>`
|
// yield an object-type (e.g., `&Object` or `Box<Object>`
|
||||||
// etc).
|
// etc).
|
||||||
|
|
||||||
// FIXME: this feels, like, super dubious
|
let mut autoderef = self.fcx.autoderef(self.span, self_ty);
|
||||||
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()
|
.include_raw_pointers()
|
||||||
.find_map(|(ty, _)| match ty.kind() {
|
.find_map(|(ty, _)| match ty.kind() {
|
||||||
ty::Dynamic(data, ..) => Some(closure(
|
ty::Dynamic(data, ..) => Some(closure(
|
||||||
|
|
33
tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs
Normal file
33
tests/ui/self/arbitrary_self_types_dispatch_to_vtable.rs
Normal file
|
@ -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();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue