forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
Showing
1 changed file
with
63 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Self>) -> usize { 2 } | ||
fn n(self: *const SmartPtr<Self>) -> usize { 2 } | ||
|
||
fn o(self: Pin<&SmartPtr2<Self>>) -> usize { 2 } | ||
fn p(self: Pin<&SmartPtr2<Self>>) -> usize { 2 } | ||
} | ||
|
||
struct SmartPtr<T>(T); | ||
|
||
impl<T> core::ops::Receiver for SmartPtr<T> { | ||
type Target = *mut T; | ||
} | ||
|
||
impl<T> SmartPtr<T> { | ||
// 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<T> 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<A> = &mut sm as *mut SmartPtr<A>; | ||
assert_eq!(smp.m(), 2); | ||
assert_eq!(smp.n(), 1); | ||
|
||
let smp: Pin<&mut SmartPtr2<A>> = pin!(SmartPtr2(A, PhantomData)); | ||
assert_eq!(smp.o(), 2); | ||
let smp: Pin<&mut SmartPtr2<A>> = pin!(SmartPtr2(A, PhantomData)); | ||
assert_eq!(smp.p(), 1); | ||
} |