Skip to content

Commit 268a1ff

Browse files
committed
Account for Paths on is_suggestable_infer_ty
Fix #68162.
1 parent 30ca215 commit 268a1ff

File tree

3 files changed

+86
-45
lines changed

3 files changed

+86
-45
lines changed

src/librustc_typeck/collect.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,16 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
18061806
}
18071807
}
18081808

1809+
fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
1810+
generic_args
1811+
.iter()
1812+
.filter_map(|arg| match arg {
1813+
hir::GenericArg::Type(ty) => Some(ty),
1814+
_ => None,
1815+
})
1816+
.any(is_suggestable_infer_ty)
1817+
}
1818+
18091819
/// Whether `ty` is a type with `_` placeholders that can be infered. Used in diagnostics only to
18101820
/// use inference to provide suggestions for the appropriate type if possible.
18111821
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
@@ -1815,13 +1825,16 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
18151825
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
18161826
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
18171827
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
1818-
Def(_, generic_args) => generic_args
1819-
.iter()
1820-
.filter_map(|arg| match arg {
1821-
hir::GenericArg::Type(ty) => Some(ty),
1822-
_ => None,
1823-
})
1824-
.any(is_suggestable_infer_ty),
1828+
Def(_, generic_args) => are_suggestable_generic_args(generic_args),
1829+
Path(hir::QPath::TypeRelative(ty, segment)) => {
1830+
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args)
1831+
}
1832+
Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
1833+
ty_opt.map_or(false, is_suggestable_infer_ty)
1834+
|| segments
1835+
.iter()
1836+
.any(|segment| are_suggestable_generic_args(segment.generic_args().args))
1837+
}
18251838
_ => false,
18261839
}
18271840
}

src/test/ui/typeck/typeck_type_placeholder_item.rs

+7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ struct Test10 {
6868
}
6969

7070
pub fn main() {
71+
static A = 42;
72+
//~^ ERROR missing type for `static` item
73+
static B: _ = 42;
74+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
75+
static C: Option<_> = Some(42);
76+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
77+
7178
fn fn_test() -> _ { 5 }
7279
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
7380

src/test/ui/typeck/typeck_type_placeholder_item.stderr

+59-38
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
error: expected identifier, found reserved identifier `_`
2-
--> $DIR/typeck_type_placeholder_item.rs:146:18
2+
--> $DIR/typeck_type_placeholder_item.rs:153:18
33
|
44
LL | struct BadStruct<_>(_);
55
| ^ expected identifier, found reserved identifier
66

77
error: expected identifier, found reserved identifier `_`
8-
--> $DIR/typeck_type_placeholder_item.rs:149:16
8+
--> $DIR/typeck_type_placeholder_item.rs:156:16
99
|
1010
LL | trait BadTrait<_> {}
1111
| ^ expected identifier, found reserved identifier
1212

1313
error: expected identifier, found reserved identifier `_`
14-
--> $DIR/typeck_type_placeholder_item.rs:159:19
14+
--> $DIR/typeck_type_placeholder_item.rs:166:19
1515
|
1616
LL | struct BadStruct1<_, _>(_);
1717
| ^ expected identifier, found reserved identifier
1818

1919
error: expected identifier, found reserved identifier `_`
20-
--> $DIR/typeck_type_placeholder_item.rs:159:22
20+
--> $DIR/typeck_type_placeholder_item.rs:166:22
2121
|
2222
LL | struct BadStruct1<_, _>(_);
2323
| ^ expected identifier, found reserved identifier
2424

2525
error: expected identifier, found reserved identifier `_`
26-
--> $DIR/typeck_type_placeholder_item.rs:164:19
26+
--> $DIR/typeck_type_placeholder_item.rs:171:19
2727
|
2828
LL | struct BadStruct2<_, T>(_, T);
2929
| ^ expected identifier, found reserved identifier
3030

3131
error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters
32-
--> $DIR/typeck_type_placeholder_item.rs:159:22
32+
--> $DIR/typeck_type_placeholder_item.rs:166:22
3333
|
3434
LL | struct BadStruct1<_, _>(_);
3535
| - ^ already used
@@ -177,8 +177,29 @@ LL |
177177
LL | b: (T, T),
178178
|
179179

180+
error: missing type for `static` item
181+
--> $DIR/typeck_type_placeholder_item.rs:71:12
182+
|
183+
LL | static A = 42;
184+
| ^ help: provide a type for the item: `A: i32`
185+
186+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
187+
--> $DIR/typeck_type_placeholder_item.rs:73:15
188+
|
189+
LL | static B: _ = 42;
190+
| ^
191+
| |
192+
| not allowed in type signatures
193+
| help: replace `_` with the correct type: `i32`
194+
195+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
196+
--> $DIR/typeck_type_placeholder_item.rs:75:15
197+
|
198+
LL | static C: Option<_> = Some(42);
199+
| ^^^^^^^^^ not allowed in type signatures
200+
180201
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
181-
--> $DIR/typeck_type_placeholder_item.rs:71:21
202+
--> $DIR/typeck_type_placeholder_item.rs:78:21
182203
|
183204
LL | fn fn_test() -> _ { 5 }
184205
| ^
@@ -187,7 +208,7 @@ LL | fn fn_test() -> _ { 5 }
187208
| help: replace with the correct return type: `i32`
188209

189210
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
190-
--> $DIR/typeck_type_placeholder_item.rs:74:23
211+
--> $DIR/typeck_type_placeholder_item.rs:81:23
191212
|
192213
LL | fn fn_test2() -> (_, _) { (5, 5) }
193214
| -^--^-
@@ -197,7 +218,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) }
197218
| help: replace with the correct return type: `(i32, i32)`
198219

199220
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
200-
--> $DIR/typeck_type_placeholder_item.rs:77:22
221+
--> $DIR/typeck_type_placeholder_item.rs:84:22
201222
|
202223
LL | static FN_TEST3: _ = "test";
203224
| ^
@@ -206,7 +227,7 @@ LL | static FN_TEST3: _ = "test";
206227
| help: replace `_` with the correct type: `&'static str`
207228

208229
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
209-
--> $DIR/typeck_type_placeholder_item.rs:80:22
230+
--> $DIR/typeck_type_placeholder_item.rs:87:22
210231
|
211232
LL | static FN_TEST4: _ = 145;
212233
| ^
@@ -215,13 +236,13 @@ LL | static FN_TEST4: _ = 145;
215236
| help: replace `_` with the correct type: `i32`
216237

217238
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
218-
--> $DIR/typeck_type_placeholder_item.rs:83:22
239+
--> $DIR/typeck_type_placeholder_item.rs:90:22
219240
|
220241
LL | static FN_TEST5: (_, _) = (1, 2);
221242
| ^^^^^^ not allowed in type signatures
222243

223244
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
224-
--> $DIR/typeck_type_placeholder_item.rs:86:20
245+
--> $DIR/typeck_type_placeholder_item.rs:93:20
225246
|
226247
LL | fn fn_test6(_: _) { }
227248
| ^ not allowed in type signatures
@@ -232,7 +253,7 @@ LL | fn fn_test6<T>(_: T) { }
232253
| ^^^ ^
233254

234255
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
235-
--> $DIR/typeck_type_placeholder_item.rs:89:20
256+
--> $DIR/typeck_type_placeholder_item.rs:96:20
236257
|
237258
LL | fn fn_test7(x: _) { let _x: usize = x; }
238259
| ^ not allowed in type signatures
@@ -243,13 +264,13 @@ LL | fn fn_test7<T>(x: T) { let _x: usize = x; }
243264
| ^^^ ^
244265

245266
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
246-
--> $DIR/typeck_type_placeholder_item.rs:92:29
267+
--> $DIR/typeck_type_placeholder_item.rs:99:29
247268
|
248269
LL | fn fn_test8(_f: fn() -> _) { }
249270
| ^ not allowed in type signatures
250271

251272
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
252-
--> $DIR/typeck_type_placeholder_item.rs:92:29
273+
--> $DIR/typeck_type_placeholder_item.rs:99:29
253274
|
254275
LL | fn fn_test8(_f: fn() -> _) { }
255276
| ^ not allowed in type signatures
@@ -260,7 +281,7 @@ LL | fn fn_test8<T>(_f: fn() -> T) { }
260281
| ^^^ ^
261282

262283
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
263-
--> $DIR/typeck_type_placeholder_item.rs:115:12
284+
--> $DIR/typeck_type_placeholder_item.rs:122:12
264285
|
265286
LL | a: _,
266287
| ^ not allowed in type signatures
@@ -279,21 +300,21 @@ LL | b: (T, T),
279300
|
280301

281302
error[E0282]: type annotations needed
282-
--> $DIR/typeck_type_placeholder_item.rs:120:27
303+
--> $DIR/typeck_type_placeholder_item.rs:127:27
283304
|
284305
LL | fn fn_test11(_: _) -> (_, _) { panic!() }
285306
| ^^^^^^ cannot infer type
286307

287308
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
288-
--> $DIR/typeck_type_placeholder_item.rs:120:28
309+
--> $DIR/typeck_type_placeholder_item.rs:127:28
289310
|
290311
LL | fn fn_test11(_: _) -> (_, _) { panic!() }
291312
| ^ ^ not allowed in type signatures
292313
| |
293314
| not allowed in type signatures
294315

295316
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
296-
--> $DIR/typeck_type_placeholder_item.rs:124:30
317+
--> $DIR/typeck_type_placeholder_item.rs:131:30
297318
|
298319
LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
299320
| -^--^-
@@ -303,7 +324,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
303324
| help: replace with the correct return type: `(i32, i32)`
304325

305326
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
306-
--> $DIR/typeck_type_placeholder_item.rs:127:33
327+
--> $DIR/typeck_type_placeholder_item.rs:134:33
307328
|
308329
LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
309330
| ------^-
@@ -312,7 +333,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
312333
| help: replace with the correct return type: `(i32, i32)`
313334

314335
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
315-
--> $DIR/typeck_type_placeholder_item.rs:146:21
336+
--> $DIR/typeck_type_placeholder_item.rs:153:21
316337
|
317338
LL | struct BadStruct<_>(_);
318339
| ^ not allowed in type signatures
@@ -323,7 +344,7 @@ LL | struct BadStruct<T>(T);
323344
| ^ ^
324345

325346
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
326-
--> $DIR/typeck_type_placeholder_item.rs:151:15
347+
--> $DIR/typeck_type_placeholder_item.rs:158:15
327348
|
328349
LL | impl BadTrait<_> for BadStruct<_> {}
329350
| ^ ^ not allowed in type signatures
@@ -336,13 +357,13 @@ LL | impl<T> BadTrait<T> for BadStruct<T> {}
336357
| ^^^ ^ ^
337358

338359
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
339-
--> $DIR/typeck_type_placeholder_item.rs:154:34
360+
--> $DIR/typeck_type_placeholder_item.rs:161:34
340361
|
341362
LL | fn impl_trait() -> impl BadTrait<_> {
342363
| ^ not allowed in type signatures
343364

344365
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
345-
--> $DIR/typeck_type_placeholder_item.rs:159:25
366+
--> $DIR/typeck_type_placeholder_item.rs:166:25
346367
|
347368
LL | struct BadStruct1<_, _>(_);
348369
| ^ not allowed in type signatures
@@ -353,7 +374,7 @@ LL | struct BadStruct1<T, _>(T);
353374
| ^ ^
354375

355376
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
356-
--> $DIR/typeck_type_placeholder_item.rs:164:25
377+
--> $DIR/typeck_type_placeholder_item.rs:171:25
357378
|
358379
LL | struct BadStruct2<_, T>(_, T);
359380
| ^ not allowed in type signatures
@@ -364,7 +385,7 @@ LL | struct BadStruct2<K, T>(K, T);
364385
| ^ ^
365386

366387
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
367-
--> $DIR/typeck_type_placeholder_item.rs:168:14
388+
--> $DIR/typeck_type_placeholder_item.rs:175:14
368389
|
369390
LL | type X = Box<_>;
370391
| ^ not allowed in type signatures
@@ -381,7 +402,7 @@ LL | fn test10<T>(&self, _x : T) { }
381402
| ^^^ ^
382403

383404
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
384-
--> $DIR/typeck_type_placeholder_item.rs:132:31
405+
--> $DIR/typeck_type_placeholder_item.rs:139:31
385406
|
386407
LL | fn method_test1(&self, x: _);
387408
| ^ not allowed in type signatures
@@ -392,7 +413,7 @@ LL | fn method_test1<T>(&self, x: T);
392413
| ^^^ ^
393414

394415
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
395-
--> $DIR/typeck_type_placeholder_item.rs:134:31
416+
--> $DIR/typeck_type_placeholder_item.rs:141:31
396417
|
397418
LL | fn method_test2(&self, x: _) -> _;
398419
| ^ ^ not allowed in type signatures
@@ -405,7 +426,7 @@ LL | fn method_test2<T>(&self, x: T) -> T;
405426
| ^^^ ^ ^
406427

407428
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
408-
--> $DIR/typeck_type_placeholder_item.rs:136:31
429+
--> $DIR/typeck_type_placeholder_item.rs:143:31
409430
|
410431
LL | fn method_test3(&self) -> _;
411432
| ^ not allowed in type signatures
@@ -416,7 +437,7 @@ LL | fn method_test3<T>(&self) -> T;
416437
| ^^^ ^
417438

418439
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
419-
--> $DIR/typeck_type_placeholder_item.rs:138:26
440+
--> $DIR/typeck_type_placeholder_item.rs:145:26
420441
|
421442
LL | fn assoc_fn_test1(x: _);
422443
| ^ not allowed in type signatures
@@ -427,7 +448,7 @@ LL | fn assoc_fn_test1<T>(x: T);
427448
| ^^^ ^
428449

429450
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
430-
--> $DIR/typeck_type_placeholder_item.rs:140:26
451+
--> $DIR/typeck_type_placeholder_item.rs:147:26
431452
|
432453
LL | fn assoc_fn_test2(x: _) -> _;
433454
| ^ ^ not allowed in type signatures
@@ -440,7 +461,7 @@ LL | fn assoc_fn_test2<T>(x: T) -> T;
440461
| ^^^ ^ ^
441462

442463
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
443-
--> $DIR/typeck_type_placeholder_item.rs:142:28
464+
--> $DIR/typeck_type_placeholder_item.rs:149:28
444465
|
445466
LL | fn assoc_fn_test3() -> _;
446467
| ^ not allowed in type signatures
@@ -462,7 +483,7 @@ LL | fn clone_from<T>(&mut self, other: T) { *self = Test9; }
462483
| ^^^ ^
463484

464485
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
465-
--> $DIR/typeck_type_placeholder_item.rs:102:34
486+
--> $DIR/typeck_type_placeholder_item.rs:109:34
466487
|
467488
LL | fn fn_test10(&self, _x : _) { }
468489
| ^ not allowed in type signatures
@@ -473,7 +494,7 @@ LL | fn fn_test10<T>(&self, _x : T) { }
473494
| ^^^ ^
474495

475496
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
476-
--> $DIR/typeck_type_placeholder_item.rs:110:41
497+
--> $DIR/typeck_type_placeholder_item.rs:117:41
477498
|
478499
LL | fn clone_from(&mut self, other: _) { *self = FnTest9; }
479500
| ^ not allowed in type signatures
@@ -484,7 +505,7 @@ LL | fn clone_from<T>(&mut self, other: T) { *self = FnTest9; }
484505
| ^^^ ^
485506

486507
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
487-
--> $DIR/typeck_type_placeholder_item.rs:174:21
508+
--> $DIR/typeck_type_placeholder_item.rs:181:21
488509
|
489510
LL | type Y = impl Trait<_>;
490511
| ^ not allowed in type signatures
@@ -508,7 +529,7 @@ LL | fn clone(&self) -> _ { Test9 }
508529
| help: replace with the correct return type: `Test9`
509530

510531
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
511-
--> $DIR/typeck_type_placeholder_item.rs:99:31
532+
--> $DIR/typeck_type_placeholder_item.rs:106:31
512533
|
513534
LL | fn fn_test9(&self) -> _ { () }
514535
| ^
@@ -517,15 +538,15 @@ LL | fn fn_test9(&self) -> _ { () }
517538
| help: replace with the correct return type: `()`
518539

519540
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
520-
--> $DIR/typeck_type_placeholder_item.rs:107:28
541+
--> $DIR/typeck_type_placeholder_item.rs:114:28
521542
|
522543
LL | fn clone(&self) -> _ { FnTest9 }
523544
| ^
524545
| |
525546
| not allowed in type signatures
526547
| help: replace with the correct return type: `main::FnTest9`
527548

528-
error: aborting due to 55 previous errors
549+
error: aborting due to 58 previous errors
529550

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

0 commit comments

Comments
 (0)