Skip to content

Commit e0c36c7

Browse files
committed
Rust: Move associated types tests into separate file
1 parent 5d00a4d commit e0c36c7

File tree

3 files changed

+6566
-6775
lines changed

3 files changed

+6566
-6775
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
mod associated_type_in_trait {
2+
#[derive(Debug)]
3+
struct Wrapper<A> {
4+
field: A,
5+
}
6+
7+
impl<A> Wrapper<A> {
8+
fn unwrap(self) -> A {
9+
self.field // $ fieldof=Wrapper
10+
}
11+
}
12+
13+
trait MyTrait {
14+
type AssociatedType;
15+
16+
// MyTrait::m1
17+
fn m1(self) -> Self::AssociatedType;
18+
19+
fn m2(self) -> Self::AssociatedType
20+
where
21+
Self::AssociatedType: Default,
22+
Self: Sized,
23+
{
24+
self.m1(); // $ target=MyTrait::m1 type=self.m1():AssociatedType
25+
Self::AssociatedType::default()
26+
}
27+
}
28+
29+
trait MyTraitAssoc2 {
30+
type GenericAssociatedType<AssociatedParam>;
31+
32+
// MyTrait::put
33+
fn put<A>(&self, a: A) -> Self::GenericAssociatedType<A>;
34+
35+
fn putTwo<A>(&self, a: A, b: A) -> Self::GenericAssociatedType<A> {
36+
self.put(a); // $ target=MyTrait::put
37+
self.put(b) // $ target=MyTrait::put
38+
}
39+
}
40+
41+
// A generic trait with multiple associated types.
42+
trait TraitMultipleAssoc<TrG> {
43+
type Assoc1;
44+
type Assoc2;
45+
46+
fn get_zero(&self) -> TrG;
47+
48+
fn get_one(&self) -> Self::Assoc1;
49+
50+
fn get_two(&self) -> Self::Assoc2;
51+
}
52+
53+
#[derive(Debug, Default)]
54+
struct S;
55+
56+
#[derive(Debug, Default)]
57+
struct S2;
58+
59+
#[derive(Debug, Default)]
60+
struct AT;
61+
62+
impl MyTrait for S {
63+
type AssociatedType = AT;
64+
65+
// S::m1
66+
fn m1(self) -> Self::AssociatedType {
67+
AT
68+
}
69+
}
70+
71+
impl MyTraitAssoc2 for S {
72+
// Associated type with a type parameter
73+
type GenericAssociatedType<AssociatedParam> = Wrapper<AssociatedParam>;
74+
75+
// S::put
76+
fn put<A>(&self, a: A) -> Wrapper<A> {
77+
Wrapper { field: a }
78+
}
79+
}
80+
81+
impl MyTrait for S2 {
82+
// Associated type definition with a type argument
83+
type AssociatedType = Wrapper<S2>;
84+
85+
fn m1(self) -> Self::AssociatedType {
86+
Wrapper { field: self }
87+
}
88+
}
89+
90+
// NOTE: This implementation is just to make it possible to call `m2` on `S2.`
91+
impl Default for Wrapper<S2> {
92+
fn default() -> Self {
93+
Wrapper { field: S2 }
94+
}
95+
}
96+
97+
// Function that returns an associated type from a trait bound
98+
99+
fn g<T: MyTrait>(thing: T) -> <T as MyTrait>::AssociatedType {
100+
thing.m1() // $ target=MyTrait::m1
101+
}
102+
103+
impl TraitMultipleAssoc<AT> for AT {
104+
type Assoc1 = S;
105+
type Assoc2 = S2;
106+
107+
fn get_zero(&self) -> AT {
108+
AT
109+
}
110+
111+
fn get_one(&self) -> Self::Assoc1 {
112+
S
113+
}
114+
115+
fn get_two(&self) -> Self::Assoc2 {
116+
S2
117+
}
118+
}
119+
120+
pub fn test() {
121+
let x1 = S;
122+
// Call to method in `impl` block
123+
println!("{:?}", x1.m1()); // $ target=S::m1 type=x1.m1():AT
124+
125+
let x2 = S;
126+
// Call to default method in `trait` block
127+
let y = x2.m2(); // $ target=m2 type=y:AT
128+
println!("{:?}", y);
129+
130+
let x3 = S;
131+
// Call to the method in `impl` block
132+
println!("{:?}", x3.put(1).unwrap()); // $ target=S::put target=unwrap
133+
134+
// Call to default implementation in `trait` block
135+
println!("{:?}", x3.putTwo(2, 3).unwrap()); // $ target=putTwo target=unwrap
136+
137+
let x4 = g(S); // $ target=g $ MISSING: type=x4:AT
138+
println!("{:?}", x4);
139+
140+
let x5 = S2;
141+
println!("{:?}", x5.m1()); // $ target=m1 type=x5.m1():A.S2
142+
let x6 = S2;
143+
println!("{:?}", x6.m2()); // $ target=m2 type=x6.m2():A.S2
144+
145+
let assoc_zero = AT.get_zero(); // $ target=get_zero type=assoc_zero:AT
146+
let assoc_one = AT.get_one(); // $ target=get_one type=assoc_one:S
147+
let assoc_two = AT.get_two(); // $ target=get_two type=assoc_two:S2
148+
}
149+
}
150+
151+
mod associated_type_in_supertrait {
152+
trait Supertrait {
153+
type Content;
154+
// Supertrait::insert
155+
fn insert(&self, content: Self::Content);
156+
}
157+
158+
trait Subtrait: Supertrait {
159+
// Subtrait::get_content
160+
fn get_content(&self) -> Self::Content;
161+
}
162+
163+
// A subtrait declared using a `where` clause.
164+
trait Subtrait2
165+
where
166+
Self: Supertrait,
167+
{
168+
// Subtrait2::insert_two
169+
fn insert_two(&self, c1: Self::Content, c2: Self::Content) {
170+
self.insert(c1); // $ target=Supertrait::insert
171+
self.insert(c2); // $ target=Supertrait::insert
172+
}
173+
}
174+
175+
struct MyType<T>(T);
176+
177+
impl<T> Supertrait for MyType<T> {
178+
type Content = T;
179+
fn insert(&self, _content: Self::Content) {
180+
println!("Inserting content: ");
181+
}
182+
}
183+
184+
impl<T: Clone> Subtrait for MyType<T> {
185+
// MyType::get_content
186+
fn get_content(&self) -> Self::Content {
187+
(*self).0.clone() // $ fieldof=MyType target=clone target=deref
188+
}
189+
}
190+
191+
fn get_content<T: Subtrait>(item: &T) -> T::Content {
192+
item.get_content() // $ target=Subtrait::get_content
193+
}
194+
195+
fn insert_three<T: Subtrait2>(item: &T, c1: T::Content, c2: T::Content, c3: T::Content) {
196+
item.insert(c1); // $ target=Supertrait::insert
197+
item.insert_two(c2, c3); // $ target=Subtrait2::insert_two
198+
}
199+
200+
pub fn test() {
201+
let item1 = MyType(42i64);
202+
let _content1 = item1.get_content(); // $ target=MyType::get_content MISSING: type=_content1:i64
203+
204+
let item2 = MyType(true);
205+
let _content2 = get_content(&item2); // $ target=get_content MISSING: type=_content2:bool
206+
}
207+
}
208+
209+
mod generic_associated_type_name_clash {
210+
struct GenS<GenT>(GenT);
211+
212+
trait TraitWithAssocType {
213+
type Output;
214+
fn get_input(self) -> Self::Output;
215+
}
216+
217+
impl<Output> TraitWithAssocType for GenS<Output> {
218+
// This is not a recursive type, the `Output` on the right-hand side
219+
// refers to the type parameter of the impl block just above.
220+
type Output = Result<Output, Output>;
221+
222+
fn get_input(self) -> Self::Output {
223+
Ok(self.0) // $ fieldof=GenS type=Ok(...):Result type=Ok(...):T.Output type=Ok(...):E.Output
224+
}
225+
}
226+
227+
pub fn test() {
228+
let _y = GenS(true).get_input(); // $ type=_y:Result type=_y:T.bool type=_y:E.bool target=get_input
229+
}
230+
}
231+
232+
pub fn test() {
233+
associated_type_in_trait::test(); // $ target=test
234+
associated_type_in_supertrait::test(); // $ target=test
235+
generic_associated_type_name_clash::test(); // $ target=test
236+
}

0 commit comments

Comments
 (0)