From cb88030b286dab999d835aeebd21a2cc56c96b8c Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 19 Dec 2024 11:12:35 +0000 Subject: [PATCH] Arbitrary self types v2: niche deshadowing test Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent. There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled. Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur. --- .../arbitrary_self_types_niche_deshadowing.rs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/ui/self/arbitrary_self_types_niche_deshadowing.rs diff --git a/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs b/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs new file mode 100644 index 0000000000000..9326eca1f5353 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs @@ -0,0 +1,63 @@ +//@ run-pass + +#![allow(dead_code)] +#![allow(incomplete_features)] + +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] +#![feature(pin_ergonomics)] + +use std::pin::Pin; +use std::pin::pin; +use std::marker::PhantomData; + +struct A; + +impl A { + fn m(self: *const SmartPtr) -> usize { 2 } + fn n(self: *const SmartPtr) -> usize { 2 } + + fn o(self: Pin<&SmartPtr2>) -> usize { 2 } + fn p(self: Pin<&SmartPtr2>) -> usize { 2 } +} + +struct SmartPtr(T); + +impl core::ops::Receiver for SmartPtr { + type Target = *mut T; +} + +impl SmartPtr { + // In general we try to detect cases where a method in a smart pointer + // "shadows" a method in the referent (in this test, A). + // This method "shadows" the 'n' method in the inner type A + // We do not attempt to produce an error in these shadowing cases + // since the type signature of this method and the corresponding + // method in A are pretty unlikely to occur in practice, + // and because it shows up conflicts between *const::cast and *mut::cast. + fn n(self: *mut Self) -> usize { 1 } +} + +struct SmartPtr2<'a, T>(T, PhantomData<&'a T>); + +impl<'a, T> core::ops::Receiver for SmartPtr2<'a, T> { + type Target = Pin<&'a mut T>; +} + +impl SmartPtr2<'_, T> { + // Similarly, this method shadows the method in A + // Can only happen with the unstable feature pin_ergonomics + fn p(self: Pin<&mut Self>) -> usize { 1 } +} + +fn main() { + let mut sm = SmartPtr(A); + let smp: *mut SmartPtr = &mut sm as *mut SmartPtr; + assert_eq!(smp.m(), 2); + assert_eq!(smp.n(), 1); + + let smp: Pin<&mut SmartPtr2> = pin!(SmartPtr2(A, PhantomData)); + assert_eq!(smp.o(), 2); + let smp: Pin<&mut SmartPtr2> = pin!(SmartPtr2(A, PhantomData)); + assert_eq!(smp.p(), 1); +}