Skip to content

Commit fd5658d

Browse files
committed
Rust: Tweak tests for associated types
1 parent e0c36c7 commit fd5658d

File tree

2 files changed

+578
-493
lines changed

2 files changed

+578
-493
lines changed
Lines changed: 162 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,58 @@
1-
mod associated_type_in_trait {
2-
#[derive(Debug)]
3-
struct Wrapper<A> {
4-
field: A,
1+
#[derive(Debug, Default, Copy, Clone)]
2+
struct Wrapper<A>(A);
3+
4+
impl<A> Wrapper<A> {
5+
fn unwrap(self) -> A {
6+
self.0 // $ fieldof=Wrapper
57
}
8+
}
69

7-
impl<A> Wrapper<A> {
8-
fn unwrap(self) -> A {
9-
self.field // $ fieldof=Wrapper
10-
}
10+
#[derive(Debug, Default)]
11+
struct S;
12+
13+
#[derive(Debug, Default)]
14+
struct S2;
15+
16+
#[derive(Debug, Default)]
17+
struct S3;
18+
19+
trait GetSet {
20+
type Output;
21+
22+
// GetSet::get
23+
fn get(&self) -> Self::Output;
24+
25+
// GetSet::set
26+
fn set(&self, _a: Self::Output) {}
27+
}
28+
29+
trait AnotherGet: GetSet {
30+
type AnotherOutput;
31+
32+
// AnotherGet::get_another
33+
fn get_another(&self) -> Self::AnotherOutput;
34+
}
35+
36+
impl GetSet for S {
37+
type Output = S3;
38+
39+
// S::get
40+
fn get(&self) -> Self::Output {
41+
S3
1142
}
43+
}
44+
45+
impl<T: Copy> GetSet for Wrapper<T> {
46+
type Output = T;
47+
48+
// Wrapper::get
49+
fn get(&self) -> Self::Output {
50+
self.0 // $ fieldof=Wrapper
51+
}
52+
}
53+
54+
mod default_method_using_associated_type {
55+
use super::*;
1256

1357
trait MyTrait {
1458
type AssociatedType;
@@ -22,49 +66,77 @@ mod associated_type_in_trait {
2266
Self: Sized,
2367
{
2468
self.m1(); // $ target=MyTrait::m1 type=self.m1():AssociatedType
25-
Self::AssociatedType::default()
69+
let _default = Self::AssociatedType::default(); // $ MISSING: target=default _default:AssociatedType
70+
Self::AssociatedType::default() // $ MISSING: target=default
2671
}
2772
}
2873

29-
trait MyTraitAssoc2 {
30-
type GenericAssociatedType<AssociatedParam>;
74+
impl MyTrait for S {
75+
type AssociatedType = S3;
3176

32-
// MyTrait::put
33-
fn put<A>(&self, a: A) -> Self::GenericAssociatedType<A>;
77+
// S::m1
78+
fn m1(self) -> Self::AssociatedType {
79+
S3
80+
}
81+
}
3482

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
83+
impl MyTrait for S2 {
84+
// Associated type definition with a type argument
85+
type AssociatedType = Wrapper<S2>;
86+
87+
fn m1(self) -> Self::AssociatedType {
88+
Wrapper(self)
3889
}
3990
}
4091

41-
// A generic trait with multiple associated types.
42-
trait TraitMultipleAssoc<TrG> {
43-
type Assoc1;
44-
type Assoc2;
92+
pub fn test() {
93+
let x1 = S;
94+
// Call to method in `impl` block
95+
println!("{:?}", x1.m1()); // $ target=S::m1 type=x1.m1():S3
4596

46-
fn get_zero(&self) -> TrG;
97+
let x2 = S;
98+
// Call to default method in `trait` block
99+
let y = x2.m2(); // $ target=m2 type=y:S3
100+
println!("{:?}", y);
47101

48-
fn get_one(&self) -> Self::Assoc1;
102+
let x5 = S2;
103+
println!("{:?}", x5.m1()); // $ target=m1 type=x5.m1():A.S2
104+
let x6 = S2;
105+
println!("{:?}", x6.m2()); // $ target=m2 type=x6.m2():A.S2
106+
}
107+
}
49108

50-
fn get_two(&self) -> Self::Assoc2;
109+
// Tests for signatures that access associated types from type parameters
110+
mod type_param_access_associated_type {
111+
use super::*;
112+
113+
fn tp_with_as<T: GetSet>(thing: T) -> <T as GetSet>::Output {
114+
thing.get() // $ target=GetSet::get
51115
}
52116

53-
#[derive(Debug, Default)]
54-
struct S;
117+
fn tp_without_as<T: GetSet>(thing: T) -> T::Output {
118+
thing.get() // $ target=GetSet::get
119+
}
55120

56-
#[derive(Debug, Default)]
57-
struct S2;
121+
pub fn test() {
122+
let _o1 = tp_with_as(S); // $ target=tp_with_as MISSING: type=_o1:S3
123+
let _o2 = tp_without_as(S); // $ target=tp_without_as MISSING: type=_o2:S3
124+
}
125+
}
58126

59-
#[derive(Debug, Default)]
60-
struct AT;
127+
mod generic_associated_type {
128+
use super::*;
61129

62-
impl MyTrait for S {
63-
type AssociatedType = AT;
130+
trait MyTraitAssoc2 {
131+
type GenericAssociatedType<AssociatedParam>;
64132

65-
// S::m1
66-
fn m1(self) -> Self::AssociatedType {
67-
AT
133+
// MyTraitAssoc2::put
134+
fn put<A>(&self, a: A) -> Self::GenericAssociatedType<A>;
135+
136+
// MyTraitAssoc2::put_two
137+
fn put_two<A>(&self, a: A, b: A) -> Self::GenericAssociatedType<A> {
138+
self.put(a); // $ target=MyTraitAssoc2::put
139+
self.put(b) // $ target=MyTraitAssoc2::put
68140
}
69141
}
70142

@@ -74,38 +146,41 @@ mod associated_type_in_trait {
74146

75147
// S::put
76148
fn put<A>(&self, a: A) -> Wrapper<A> {
77-
Wrapper { field: a }
149+
Wrapper(a)
78150
}
79151
}
80152

81-
impl MyTrait for S2 {
82-
// Associated type definition with a type argument
83-
type AssociatedType = Wrapper<S2>;
153+
pub fn test() {
154+
let s = S;
155+
// Call to the method in `impl` block
156+
let _g1 = s.put(1i32); // $ target=S::put type=_g1:A.i32
84157

85-
fn m1(self) -> Self::AssociatedType {
86-
Wrapper { field: self }
87-
}
158+
// Call to default implementation in `trait` block
159+
let _g2 = s.put_two(true, false); // $ target=MyTraitAssoc2::put_two MISSING: type=_g2:A.bool
88160
}
161+
}
89162

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-
}
163+
mod multiple_associated_types {
164+
use super::*;
96165

97-
// Function that returns an associated type from a trait bound
166+
// A generic trait with multiple associated types.
167+
trait TraitMultipleAssoc<TrG> {
168+
type Assoc1;
169+
type Assoc2;
98170

99-
fn g<T: MyTrait>(thing: T) -> <T as MyTrait>::AssociatedType {
100-
thing.m1() // $ target=MyTrait::m1
171+
fn get_zero(&self) -> TrG;
172+
173+
fn get_one(&self) -> Self::Assoc1;
174+
175+
fn get_two(&self) -> Self::Assoc2;
101176
}
102177

103-
impl TraitMultipleAssoc<AT> for AT {
178+
impl TraitMultipleAssoc<S3> for S3 {
104179
type Assoc1 = S;
105180
type Assoc2 = S2;
106181

107-
fn get_zero(&self) -> AT {
108-
AT
182+
fn get_zero(&self) -> S3 {
183+
S3
109184
}
110185

111186
fn get_one(&self) -> Self::Assoc1 {
@@ -118,82 +193,59 @@ mod associated_type_in_trait {
118193
}
119194

120195
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
196+
let _assoc_zero = S3.get_zero(); // $ target=get_zero type=_assoc_zero:S3
197+
let _assoc_one = S3.get_one(); // $ target=get_one type=_assoc_one:S
198+
let _assoc_two = S3.get_two(); // $ target=get_two type=_assoc_two:S2
148199
}
149200
}
150201

151202
mod associated_type_in_supertrait {
152-
trait Supertrait {
153-
type Content;
154-
// Supertrait::insert
155-
fn insert(&self, content: Self::Content);
156-
}
203+
use super::*;
157204

158-
trait Subtrait: Supertrait {
205+
trait Subtrait: GetSet {
159206
// Subtrait::get_content
160-
fn get_content(&self) -> Self::Content;
207+
fn get_content(&self) -> Self::Output;
161208
}
162209

163210
// A subtrait declared using a `where` clause.
164211
trait Subtrait2
165212
where
166-
Self: Supertrait,
213+
Self: GetSet,
167214
{
168215
// 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
216+
fn insert_two(&self, c1: Self::Output, c2: Self::Output) {
217+
self.set(c1); // $ target=GetSet::set
218+
self.set(c2); // $ target=GetSet::set
172219
}
173220
}
174221

175222
struct MyType<T>(T);
176223

177-
impl<T> Supertrait for MyType<T> {
178-
type Content = T;
179-
fn insert(&self, _content: Self::Content) {
224+
impl<T: Copy> GetSet for MyType<T> {
225+
type Output = T;
226+
227+
fn get(&self) -> Self::Output {
228+
self.0 // $ fieldof=MyType
229+
}
230+
231+
fn set(&self, _content: Self::Output) {
180232
println!("Inserting content: ");
181233
}
182234
}
183235

184-
impl<T: Clone> Subtrait for MyType<T> {
236+
impl<T: Copy> Subtrait for MyType<T> {
185237
// MyType::get_content
186-
fn get_content(&self) -> Self::Content {
187-
(*self).0.clone() // $ fieldof=MyType target=clone target=deref
238+
fn get_content(&self) -> Self::Output {
239+
(*self).0 // $ fieldof=MyType target=deref
188240
}
189241
}
190242

191-
fn get_content<T: Subtrait>(item: &T) -> T::Content {
243+
fn get_content<T: Subtrait>(item: &T) -> T::Output {
192244
item.get_content() // $ target=Subtrait::get_content
193245
}
194246

195-
fn insert_three<T: Subtrait2>(item: &T, c1: T::Content, c2: T::Content, c3: T::Content) {
196-
item.insert(c1); // $ target=Supertrait::insert
247+
fn insert_three<T: Subtrait2>(item: &T, c1: T::Output, c2: T::Output, c3: T::Output) {
248+
item.set(c1); // $ target=GetSet::set
197249
item.insert_two(c2, c3); // $ target=Subtrait2::insert_two
198250
}
199251

@@ -207,30 +259,30 @@ mod associated_type_in_supertrait {
207259
}
208260

209261
mod generic_associated_type_name_clash {
210-
struct GenS<GenT>(GenT);
262+
use super::*;
211263

212-
trait TraitWithAssocType {
213-
type Output;
214-
fn get_input(self) -> Self::Output;
215-
}
264+
struct ST<T>(T);
216265

217-
impl<Output> TraitWithAssocType for GenS<Output> {
266+
impl<Output: Copy> GetSet for ST<Output> {
218267
// This is not a recursive type, the `Output` on the right-hand side
219268
// refers to the type parameter of the impl block just above.
220269
type Output = Result<Output, Output>;
221270

222-
fn get_input(self) -> Self::Output {
223-
Ok(self.0) // $ fieldof=GenS type=Ok(...):Result type=Ok(...):T.Output type=Ok(...):E.Output
271+
fn get(&self) -> Self::Output {
272+
Ok(self.0) // $ fieldof=ST type=Ok(...):Result type=Ok(...):T.Output type=Ok(...):E.Output
224273
}
225274
}
226275

227276
pub fn test() {
228-
let _y = GenS(true).get_input(); // $ type=_y:Result type=_y:T.bool type=_y:E.bool target=get_input
277+
let _y = ST(true).get(); // $ type=_y:Result type=_y:T.bool type=_y:E.bool target=get
229278
}
230279
}
231280

232281
pub fn test() {
233-
associated_type_in_trait::test(); // $ target=test
282+
default_method_using_associated_type::test(); // $ target=test
283+
type_param_access_associated_type::test(); // $ target=test
284+
generic_associated_type::test(); // $ target=test
285+
multiple_associated_types::test(); // $ target=test
234286
associated_type_in_supertrait::test(); // $ target=test
235287
generic_associated_type_name_clash::test(); // $ target=test
236288
}

0 commit comments

Comments
 (0)