Skip to content

Commit fb52883

Browse files
committed
Account for existing type params when suggesting replacing _ for a new one
1 parent 6c8b2dc commit fb52883

File tree

3 files changed

+81
-34
lines changed

3 files changed

+81
-34
lines changed

src/librustc_typeck/collect.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,30 @@ crate fn placeholder_type_error(
134134
suggest: bool,
135135
) {
136136
if !placeholder_types.is_empty() {
137-
let mut sugg: Vec<_> = placeholder_types.iter().map(|sp| (*sp, "T".to_string())).collect();
137+
let possible_names = ["T", "K", "L", "A", "B", "C"];
138+
let used_names = generics.iter().filter_map(|p| match p.name {
139+
hir::ParamName::Plain(ident) => Some(ident.name),
140+
_ => None,
141+
}).collect::<Vec<_>>();
142+
143+
let mut type_name = "ParamName";
144+
for name in &possible_names {
145+
if !used_names.contains(&Symbol::intern(name)) {
146+
type_name = name;
147+
break;
148+
}
149+
}
150+
151+
let mut sugg: Vec<_> = placeholder_types.iter()
152+
.map(|sp| (*sp, type_name.to_string()))
153+
.collect();
138154
if generics.is_empty() {
139-
sugg.push((ident_span.shrink_to_hi(), "<T>".to_string()));
155+
sugg.push((ident_span.shrink_to_hi(), format!("<{}>", type_name)));
140156
} else {
141-
sugg.push((generics.iter().last().unwrap().span.shrink_to_hi(), ", T".to_string()));
157+
sugg.push((
158+
generics.iter().last().unwrap().span.shrink_to_hi(),
159+
format!(", {}", type_name),
160+
));
142161
}
143162
let mut err = struct_span_err!(
144163
tcx.sess,

src/test/ui/typeck/typeck_type_placeholder_item.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ static TEST5: (_, _) = (1, 2);
1919
fn test6(_: _) { }
2020
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
2121

22+
fn test6_b<T>(_: _, _: T) { }
23+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
24+
25+
fn test6_c<T, K, L, A, B>(_: _, _: (T, K, L, A, B)) { }
26+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
27+
2228
fn test7(x: _) { let _x: usize = x; }
2329
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
2430

src/test/ui/typeck/typeck_type_placeholder_item.stderr

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,29 @@ LL | fn test6<T>(_: T) { }
5454
| ^^^ ^
5555

5656
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
57-
--> $DIR/typeck_type_placeholder_item.rs:22:13
57+
--> $DIR/typeck_type_placeholder_item.rs:22:18
58+
|
59+
LL | fn test6_b<T>(_: _, _: T) { }
60+
| ^ not allowed in type signatures
61+
|
62+
help: use type parameters instead
63+
|
64+
LL | fn test6_b<T, K>(_: K, _: T) { }
65+
| ^^^ ^
66+
67+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
68+
--> $DIR/typeck_type_placeholder_item.rs:25:30
69+
|
70+
LL | fn test6_c<T, K, L, A, B>(_: _, _: (T, K, L, A, B)) { }
71+
| ^ not allowed in type signatures
72+
|
73+
help: use type parameters instead
74+
|
75+
LL | fn test6_c<T, K, L, A, B, C>(_: C, _: (T, K, L, A, B)) { }
76+
| ^^^ ^
77+
78+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
79+
--> $DIR/typeck_type_placeholder_item.rs:28:13
5880
|
5981
LL | fn test7(x: _) { let _x: usize = x; }
6082
| ^ not allowed in type signatures
@@ -65,7 +87,7 @@ LL | fn test7<T>(x: T) { let _x: usize = x; }
6587
| ^^^ ^
6688

6789
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
68-
--> $DIR/typeck_type_placeholder_item.rs:25:22
90+
--> $DIR/typeck_type_placeholder_item.rs:31:22
6991
|
7092
LL | fn test8(_f: fn() -> _) { }
7193
| ^ not allowed in type signatures
@@ -76,7 +98,7 @@ LL | fn test8<T>(_f: fn() -> T) { }
7698
| ^^^ ^
7799

78100
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
79-
--> $DIR/typeck_type_placeholder_item.rs:47:8
101+
--> $DIR/typeck_type_placeholder_item.rs:53:8
80102
|
81103
LL | a: _,
82104
| ^ not allowed in type signatures
@@ -95,7 +117,7 @@ LL | b: (T, T),
95117
|
96118

97119
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
98-
--> $DIR/typeck_type_placeholder_item.rs:53:21
120+
--> $DIR/typeck_type_placeholder_item.rs:59:21
99121
|
100122
LL | fn fn_test() -> _ { 5 }
101123
| ^
@@ -104,7 +126,7 @@ LL | fn fn_test() -> _ { 5 }
104126
| help: replace this with the correct return type: `i32`
105127

106128
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
107-
--> $DIR/typeck_type_placeholder_item.rs:56:22
129+
--> $DIR/typeck_type_placeholder_item.rs:62:22
108130
|
109131
LL | fn fn_test2() -> (_, _) { (5, 5) }
110132
| ^^^^^^
@@ -113,7 +135,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) }
113135
| help: replace this with the correct return type: `(i32, i32)`
114136

115137
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
116-
--> $DIR/typeck_type_placeholder_item.rs:59:22
138+
--> $DIR/typeck_type_placeholder_item.rs:65:22
117139
|
118140
LL | static FN_TEST3: _ = "test";
119141
| ^
@@ -122,7 +144,7 @@ LL | static FN_TEST3: _ = "test";
122144
| help: replace `_` with the correct type: `&'static str`
123145

124146
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
125-
--> $DIR/typeck_type_placeholder_item.rs:62:22
147+
--> $DIR/typeck_type_placeholder_item.rs:68:22
126148
|
127149
LL | static FN_TEST4: _ = 145;
128150
| ^
@@ -131,15 +153,15 @@ LL | static FN_TEST4: _ = 145;
131153
| help: replace `_` with the correct type: `i32`
132154

133155
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
134-
--> $DIR/typeck_type_placeholder_item.rs:65:23
156+
--> $DIR/typeck_type_placeholder_item.rs:71:23
135157
|
136158
LL | static FN_TEST5: (_, _) = (1, 2);
137159
| ^ ^ not allowed in type signatures
138160
| |
139161
| not allowed in type signatures
140162

141163
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
142-
--> $DIR/typeck_type_placeholder_item.rs:68:20
164+
--> $DIR/typeck_type_placeholder_item.rs:74:20
143165
|
144166
LL | fn fn_test6(_: _) { }
145167
| ^ not allowed in type signatures
@@ -150,7 +172,7 @@ LL | fn fn_test6<T>(_: T) { }
150172
| ^^^ ^
151173

152174
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
153-
--> $DIR/typeck_type_placeholder_item.rs:71:20
175+
--> $DIR/typeck_type_placeholder_item.rs:77:20
154176
|
155177
LL | fn fn_test7(x: _) { let _x: usize = x; }
156178
| ^ not allowed in type signatures
@@ -161,7 +183,7 @@ LL | fn fn_test7<T>(x: T) { let _x: usize = x; }
161183
| ^^^ ^
162184

163185
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
164-
--> $DIR/typeck_type_placeholder_item.rs:74:29
186+
--> $DIR/typeck_type_placeholder_item.rs:80:29
165187
|
166188
LL | fn fn_test8(_f: fn() -> _) { }
167189
| ^ not allowed in type signatures
@@ -172,7 +194,7 @@ LL | fn fn_test8<T>(_f: fn() -> T) { }
172194
| ^^^ ^
173195

174196
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
175-
--> $DIR/typeck_type_placeholder_item.rs:96:12
197+
--> $DIR/typeck_type_placeholder_item.rs:102:12
176198
|
177199
LL | a: _,
178200
| ^ not allowed in type signatures
@@ -191,19 +213,19 @@ LL | b: (T, T),
191213
|
192214

193215
error[E0282]: type annotations needed
194-
--> $DIR/typeck_type_placeholder_item.rs:101:27
216+
--> $DIR/typeck_type_placeholder_item.rs:107:27
195217
|
196218
LL | fn fn_test11(_: _) -> (_, _) { panic!() }
197219
| ^^^^^^ cannot infer type
198220

199221
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
200-
--> $DIR/typeck_type_placeholder_item.rs:101:27
222+
--> $DIR/typeck_type_placeholder_item.rs:107:27
201223
|
202224
LL | fn fn_test11(_: _) -> (_, _) { panic!() }
203225
| ^^^^^^ not allowed in type signatures
204226

205227
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
206-
--> $DIR/typeck_type_placeholder_item.rs:105:29
228+
--> $DIR/typeck_type_placeholder_item.rs:111:29
207229
|
208230
LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
209231
| ^^^^^^
@@ -212,7 +234,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
212234
| help: replace this with the correct return type: `(i32, i32)`
213235

214236
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
215-
--> $DIR/typeck_type_placeholder_item.rs:108:21
237+
--> $DIR/typeck_type_placeholder_item.rs:114:21
216238
|
217239
LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
218240
| ^ ^ not allowed in type signatures
@@ -225,7 +247,7 @@ LL | fn fn_test13<T>(x: T) -> (i32, T) { (x, x) }
225247
| ^^^ ^ ^
226248

227249
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
228-
--> $DIR/typeck_type_placeholder_item.rs:113:31
250+
--> $DIR/typeck_type_placeholder_item.rs:119:31
229251
|
230252
LL | fn method_test1(&self, x: _);
231253
| ^ not allowed in type signatures
@@ -236,7 +258,7 @@ LL | fn method_test1<T>(&self, x: T);
236258
| ^^^ ^
237259

238260
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
239-
--> $DIR/typeck_type_placeholder_item.rs:115:31
261+
--> $DIR/typeck_type_placeholder_item.rs:121:31
240262
|
241263
LL | fn method_test2(&self, x: _) -> _;
242264
| ^ ^ not allowed in type signatures
@@ -249,7 +271,7 @@ LL | fn method_test2<T>(&self, x: T) -> T;
249271
| ^^^ ^ ^
250272

251273
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
252-
--> $DIR/typeck_type_placeholder_item.rs:117:31
274+
--> $DIR/typeck_type_placeholder_item.rs:123:31
253275
|
254276
LL | fn method_test3(&self) -> _;
255277
| ^ not allowed in type signatures
@@ -260,7 +282,7 @@ LL | fn method_test3<T>(&self) -> T;
260282
| ^^^ ^
261283

262284
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
263-
--> $DIR/typeck_type_placeholder_item.rs:119:26
285+
--> $DIR/typeck_type_placeholder_item.rs:125:26
264286
|
265287
LL | fn assoc_fn_test1(x: _);
266288
| ^ not allowed in type signatures
@@ -271,7 +293,7 @@ LL | fn assoc_fn_test1<T>(x: T);
271293
| ^^^ ^
272294

273295
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
274-
--> $DIR/typeck_type_placeholder_item.rs:121:26
296+
--> $DIR/typeck_type_placeholder_item.rs:127:26
275297
|
276298
LL | fn assoc_fn_test2(x: _) -> _;
277299
| ^ ^ not allowed in type signatures
@@ -284,7 +306,7 @@ LL | fn assoc_fn_test2<T>(x: T) -> T;
284306
| ^^^ ^ ^
285307

286308
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
287-
--> $DIR/typeck_type_placeholder_item.rs:123:28
309+
--> $DIR/typeck_type_placeholder_item.rs:129:28
288310
|
289311
LL | fn assoc_fn_test3() -> _;
290312
| ^ not allowed in type signatures
@@ -295,7 +317,7 @@ LL | fn assoc_fn_test3<T>() -> T;
295317
| ^^^ ^
296318

297319
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
298-
--> $DIR/typeck_type_placeholder_item.rs:31:24
320+
--> $DIR/typeck_type_placeholder_item.rs:37:24
299321
|
300322
LL | fn test9(&self) -> _ { () }
301323
| ^
@@ -304,7 +326,7 @@ LL | fn test9(&self) -> _ { () }
304326
| help: replace this with the correct return type: `()`
305327

306328
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
307-
--> $DIR/typeck_type_placeholder_item.rs:34:27
329+
--> $DIR/typeck_type_placeholder_item.rs:40:27
308330
|
309331
LL | fn test10(&self, _x : _) { }
310332
| ^ not allowed in type signatures
@@ -315,7 +337,7 @@ LL | fn test10<T>(&self, _x : T) { }
315337
| ^^^ ^
316338

317339
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
318-
--> $DIR/typeck_type_placeholder_item.rs:39:24
340+
--> $DIR/typeck_type_placeholder_item.rs:45:24
319341
|
320342
LL | fn clone(&self) -> _ { Test9 }
321343
| ^
@@ -324,7 +346,7 @@ LL | fn clone(&self) -> _ { Test9 }
324346
| help: replace this with the correct return type: `Test9`
325347

326348
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
327-
--> $DIR/typeck_type_placeholder_item.rs:42:37
349+
--> $DIR/typeck_type_placeholder_item.rs:48:37
328350
|
329351
LL | fn clone_from(&mut self, other: _) { *self = Test9; }
330352
| ^ not allowed in type signatures
@@ -335,7 +357,7 @@ LL | fn clone_from<T>(&mut self, other: T) { *self = Test9; }
335357
| ^^^ ^
336358

337359
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
338-
--> $DIR/typeck_type_placeholder_item.rs:80:31
360+
--> $DIR/typeck_type_placeholder_item.rs:86:31
339361
|
340362
LL | fn fn_test9(&self) -> _ { () }
341363
| ^
@@ -344,7 +366,7 @@ LL | fn fn_test9(&self) -> _ { () }
344366
| help: replace this with the correct return type: `()`
345367

346368
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
347-
--> $DIR/typeck_type_placeholder_item.rs:83:34
369+
--> $DIR/typeck_type_placeholder_item.rs:89:34
348370
|
349371
LL | fn fn_test10(&self, _x : _) { }
350372
| ^ not allowed in type signatures
@@ -355,7 +377,7 @@ LL | fn fn_test10<T>(&self, _x : T) { }
355377
| ^^^ ^
356378

357379
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
358-
--> $DIR/typeck_type_placeholder_item.rs:88:28
380+
--> $DIR/typeck_type_placeholder_item.rs:94:28
359381
|
360382
LL | fn clone(&self) -> _ { FnTest9 }
361383
| ^
@@ -364,7 +386,7 @@ LL | fn clone(&self) -> _ { FnTest9 }
364386
| help: replace this with the correct return type: `main::FnTest9`
365387

366388
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
367-
--> $DIR/typeck_type_placeholder_item.rs:91:41
389+
--> $DIR/typeck_type_placeholder_item.rs:97:41
368390
|
369391
LL | fn clone_from(&mut self, other: _) { *self = FnTest9; }
370392
| ^ not allowed in type signatures
@@ -374,7 +396,7 @@ help: use type parameters instead
374396
LL | fn clone_from<T>(&mut self, other: T) { *self = FnTest9; }
375397
| ^^^ ^
376398

377-
error: aborting due to 36 previous errors
399+
error: aborting due to 38 previous errors
378400

379401
Some errors have detailed explanations: E0121, E0282.
380402
For more information about an error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)