File: arbitrary-self-from-method-substs.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (110 lines) | stat: -rw-r--r-- 3,241 bytes parent folder | download | duplicates (3)
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
}