-
Notifications
You must be signed in to change notification settings - Fork 13k
/
Copy patharbitrary-self-from-method-substs.rs
110 lines (95 loc) · 3.17 KB
/
arbitrary-self-from-method-substs.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//@ revisions: default feature
#![cfg_attr(feature, feature(arbitrary_self_types))]
use std::ops::Deref;
use std::marker::PhantomData;
struct Foo(u32);
impl Foo {
fn get<R: Deref<Target = Self>>(self: R) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get1<R: Deref<Target = Self>>(self: &R) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get2<R: Deref<Target = Self>>(self: &mut R) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get3<R: Deref<Target = Self>>(self: std::rc::Rc<R>) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get4<R: Deref<Target = Self>>(self: &std::rc::Rc<R>) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get5<R: Deref<Target = Self>>(self: std::rc::Rc<&R>) -> u32 {
//~^ ERROR: invalid generic `self` parameter type
self.0
}
fn get6<FR: FindReceiver>(self: FR::Receiver, other: FR) -> u32 {
//[default]~^ ERROR: `<FR as FindReceiver>::Receiver` cannot be used as the type of `self`
42
}
}
struct SmartPtr<'a, T: ?Sized>(&'a T);
impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unimplemented!()
}
}
struct SmartPtr2<'a, T: ?Sized>(&'a T);
impl<'a, T: ?Sized> Deref for SmartPtr2<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unimplemented!()
}
}
struct Bar<R>(std::marker::PhantomData<R>);
impl<R: std::ops::Deref<Target = Self>> Bar<R> {
fn get(self: R) {}
//[default]~^ ERROR: `R` cannot be used as the type of `self`
}
trait FindReceiver {
type Receiver: Deref<Target = Foo>;
}
struct Silly;
impl FindReceiver for Silly {
type Receiver = std::rc::Rc<Foo>;
}
fn main() {
let mut foo = Foo(1);
foo.get::<&Foo>();
//[feature]~^ ERROR mismatched types
foo.get::<std::rc::Rc<Foo>>();
//[feature]~^ ERROR mismatched types
let smart_ptr = SmartPtr(&foo);
let smart_ptr2 = SmartPtr2(&foo);
smart_ptr.get(); // this compiles
smart_ptr.get::<SmartPtr2<Foo>>();
//[feature]~^ ERROR mismatched types
smart_ptr.get::<&Foo>();
//[feature]~^ ERROR mismatched types
let mut foo = Foo(1);
// This test is slightly contrived in an attempt to generate a mismatched types
// error for the self type below, without using the turbofish.
foo.get6(Silly);
//~^ ERROR type mismatch
let mut foo = Foo(1);
let foo = &foo;
foo.get6(Silly);
//~^ ERROR type mismatch
let t = std::rc::Rc::new(Bar(std::marker::PhantomData));
t.get();
//~^ ERROR its trait bounds were not satisfied
let t = &t;
// This is a further attempt at triggering 'type mismatch' errors
// from arbitrary self types without resorting to the turbofish.
// Ideally, here, t is Thing<Rc<Target=Self>> while we're going to call
// it with a &t method receiver. However, this doesn't work since that
// type of t becomes recursive and trait bounds can't be satisfied.
t.get();
//~^ ERROR its trait bounds were not satisfied
}