Skip to content

Commit

Permalink
Arbitrary self types v2: add disambiguation tests.
Browse files Browse the repository at this point in the history
The deshadowing algorithm in this PR is at risk of triggering in
undesirable circumstances, where extension traits have made methods
available. Add a couple of tests corresponding to cases where this has
been encountered.
  • Loading branch information
adetaylor committed Nov 21, 2024
1 parent 75561b6 commit b7da5e1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
38 changes: 38 additions & 0 deletions tests/ui/self/conflicting_inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//@ run-pass
//@ revisions: default feature
#![cfg_attr(feature, feature(arbitrary_self_types))]

// This test aims to be like the IndexVec within rustc, and conflicts
// over its into_iter().

#[allow(dead_code)]
trait Foo {
fn foo(self) -> usize;
}

struct IndexVec<T>(T);

impl<T> std::ops::Deref for IndexVec<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<'a, T> Foo for &'a IndexVec<T> {
fn foo(self) -> usize {
2
}
}

impl<T> IndexVec<T> {
fn foo(self) -> usize {
1
}
}

fn main() {
let ivec = IndexVec(0usize);
assert_eq!(ivec.foo(), 1);
}
63 changes: 63 additions & 0 deletions tests/ui/self/conflicting_inner2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//@ run-pass
//@ revisions: default feature
#![cfg_attr(feature, feature(arbitrary_self_types))]

use std::pin::Pin;
use std::ops::DerefMut;
use std::marker::Unpin;

struct TryChunks;

impl TryChunks {
#[allow(dead_code)]
fn take(self: std::pin::Pin<&mut Self>) -> usize {
1
}
}

#[allow(dead_code)]
trait Stream {
fn poll_next(self: std::pin::Pin<&mut Self>);
}

#[allow(dead_code)]
trait StreamExt: Stream {
#[allow(dead_code)]
fn take(self) -> usize where Self: Sized
{
2
}
}

impl<T: ?Sized> StreamExt for T where T: Stream {}

impl Stream for TryChunks {
fn poll_next(self: std::pin::Pin<&mut Self>) {
assert_eq!(self.take(), 1);
}
}

#[allow(dead_code)]
impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
#[allow(dead_code)]
fn poll_next(mut self: Pin<&mut Self>) {
S::poll_next(Pin::new(&mut **self))
}
}

#[allow(dead_code)]
impl<P> Stream for Pin<P>
where
P: DerefMut + Unpin,
P::Target: Stream,
{
#[allow(dead_code)]
fn poll_next(self: Pin<&mut Self>) {
self.get_mut().as_mut().poll_next()
}
}

fn main() {
let mut item = Box::pin(TryChunks);
item.as_mut().poll_next();
}

0 comments on commit b7da5e1

Please sign in to comment.