@@ -160,15 +160,7 @@ crate fn placeholder_type_error(
160
160
format ! ( ", {}" , type_name) ,
161
161
) ) ;
162
162
}
163
- let mut err = struct_span_err ! (
164
- tcx. sess,
165
- placeholder_types. clone( ) ,
166
- E0121 ,
167
- "the type placeholder `_` is not allowed within types on item signatures" ,
168
- ) ;
169
- for span in & placeholder_types {
170
- err. span_label ( * span, "not allowed in type signatures" ) ;
171
- }
163
+ let mut err = bad_placeholder_type ( tcx, placeholder_types) ;
172
164
if suggest {
173
165
err. multipart_suggestion (
174
166
"use type parameters instead" ,
@@ -184,14 +176,8 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
184
176
hir:: ItemKind :: Union ( _, generics)
185
177
| hir:: ItemKind :: Enum ( _, generics)
186
178
| hir:: ItemKind :: Struct ( _, generics) => ( & generics. params [ ..] , true ) ,
187
- hir:: ItemKind :: Static ( ty, ..) => {
188
- if let hir:: TyKind :: Infer = ty. kind {
189
- return ; // We handle it elsewhere to attempt to suggest an appropriate type.
190
- } else {
191
- ( & [ ] [ ..] , false )
192
- }
193
- }
194
179
hir:: ItemKind :: TyAlias ( _, generics) => ( & generics. params [ ..] , false ) ,
180
+ // hir::ItemKind::Static(ty, ..) => {
195
181
// hir::ItemKind::Fn(..) |
196
182
// hir::ItemKind::Const(..) => {} // We handle these elsewhere to suggest appropriate type.
197
183
_ => return ,
@@ -255,15 +241,21 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
255
241
///////////////////////////////////////////////////////////////////////////
256
242
// Utility types and common code for the above passes.
257
243
258
- fn bad_placeholder_type ( tcx : TyCtxt < ' tcx > , span : Span ) -> errors:: DiagnosticBuilder < ' tcx > {
259
- let mut diag = struct_span_err ! (
244
+ fn bad_placeholder_type (
245
+ tcx : TyCtxt < ' tcx > ,
246
+ mut spans : Vec < Span > ,
247
+ ) -> errors:: DiagnosticBuilder < ' tcx > {
248
+ spans. sort ( ) ;
249
+ let mut err = struct_span_err ! (
260
250
tcx. sess,
261
- span ,
251
+ spans . clone ( ) ,
262
252
E0121 ,
263
253
"the type placeholder `_` is not allowed within types on item signatures" ,
264
254
) ;
265
- diag. span_label ( span, "not allowed in type signatures" ) ;
266
- diag
255
+ for span in spans {
256
+ err. span_label ( span, "not allowed in type signatures" ) ;
257
+ }
258
+ err
267
259
}
268
260
269
261
impl ItemCtxt < ' tcx > {
@@ -298,7 +290,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
298
290
}
299
291
300
292
fn ty_infer ( & self , _: Option < & ty:: GenericParamDef > , span : Span ) -> Ty < ' tcx > {
301
- self . tcx ( ) . sess . delay_span_bug ( span, "bad placeholder type, but no error was emitted " ) ;
293
+ self . tcx ( ) . sess . delay_span_bug ( span, "bad placeholder type" ) ;
302
294
self . tcx ( ) . types . err
303
295
}
304
296
@@ -308,7 +300,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
308
300
_: Option < & ty:: GenericParamDef > ,
309
301
span : Span ,
310
302
) -> & ' tcx Const < ' tcx > {
311
- bad_placeholder_type ( self . tcx ( ) , span) . emit ( ) ;
303
+ bad_placeholder_type ( self . tcx ( ) , vec ! [ span] ) . emit ( ) ;
312
304
313
305
self . tcx ( ) . consts . err
314
306
}
@@ -1233,7 +1225,7 @@ fn infer_placeholder_type(
1233
1225
span : Span ,
1234
1226
item_ident : Ident ,
1235
1227
) -> Ty < ' _ > {
1236
- let ty = tcx. typeck_tables_of ( def_id) . node_type ( body_id. hir_id ) ;
1228
+ let ty = tcx. diagnostic_only_typeck_tables_of ( def_id) . node_type ( body_id. hir_id ) ;
1237
1229
1238
1230
// If this came from a free `const` or `static mut?` item,
1239
1231
// then the user may have written e.g. `const A = 42;`.
@@ -1253,7 +1245,7 @@ fn infer_placeholder_type(
1253
1245
. emit ( ) ;
1254
1246
}
1255
1247
None => {
1256
- let mut diag = bad_placeholder_type ( tcx, span) ;
1248
+ let mut diag = bad_placeholder_type ( tcx, vec ! [ span] ) ;
1257
1249
if ty != tcx. types . err {
1258
1250
diag. span_suggestion (
1259
1251
span,
@@ -1284,12 +1276,8 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1284
1276
}
1285
1277
TraitItemKind :: Const ( ref ty, body_id) => body_id
1286
1278
. and_then ( |body_id| {
1287
- if let hir :: TyKind :: Infer = ty . kind {
1279
+ if is_infer_ty ( ty ) {
1288
1280
Some ( infer_placeholder_type ( tcx, def_id, body_id, ty. span , item. ident ) )
1289
- } else if is_infer_ty ( ty) {
1290
- // Infering this would cause a cycle error.
1291
- tcx. sess . delay_span_bug ( ty. span , "`_` placeholder but no error emitted" ) ;
1292
- Some ( tcx. types . err )
1293
1281
} else {
1294
1282
None
1295
1283
}
@@ -1307,12 +1295,8 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1307
1295
tcx. mk_fn_def ( def_id, substs)
1308
1296
}
1309
1297
ImplItemKind :: Const ( ref ty, body_id) => {
1310
- if let hir :: TyKind :: Infer = ty . kind {
1298
+ if is_infer_ty ( ty ) {
1311
1299
infer_placeholder_type ( tcx, def_id, body_id, ty. span , item. ident )
1312
- } else if is_infer_ty ( ty) {
1313
- // Infering this would cause a cycle error.
1314
- tcx. sess . delay_span_bug ( ty. span , "`_` placeholder but no error emitted" ) ;
1315
- tcx. types . err
1316
1300
} else {
1317
1301
icx. to_ty ( ty)
1318
1302
}
@@ -1336,12 +1320,8 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
1336
1320
Node :: Item ( item) => {
1337
1321
match item. kind {
1338
1322
ItemKind :: Static ( ref ty, .., body_id) | ItemKind :: Const ( ref ty, body_id) => {
1339
- if let hir :: TyKind :: Infer = ty . kind {
1323
+ if is_infer_ty ( ty ) {
1340
1324
infer_placeholder_type ( tcx, def_id, body_id, ty. span , item. ident )
1341
- } else if is_infer_ty ( ty) {
1342
- // Infering this would cause a cycle error.
1343
- tcx. sess . delay_span_bug ( ty. span , "`_` placeholder but no error emitted" ) ;
1344
- tcx. types . err
1345
1325
} else {
1346
1326
icx. to_ty ( ty)
1347
1327
}
@@ -1818,7 +1798,7 @@ crate fn is_infer_ty(ty: &hir::Ty<'_>) -> bool {
1818
1798
hir:: TyKind :: Slice ( ty) | hir:: TyKind :: Array ( ty, _) => is_infer_ty ( ty) ,
1819
1799
hir:: TyKind :: Tup ( tys)
1820
1800
if !tys. is_empty ( )
1821
- && tys. iter ( ) . all ( |ty| match ty. kind {
1801
+ && tys. iter ( ) . any ( |ty| match ty. kind {
1822
1802
hir:: TyKind :: Infer => true ,
1823
1803
_ => false ,
1824
1804
} ) =>
@@ -1858,12 +1838,14 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
1858
1838
match get_infer_ret_ty ( & sig. decl . output ) {
1859
1839
Some ( ty) => {
1860
1840
let fn_sig = tcx. typeck_tables_of ( def_id) . liberated_fn_sigs ( ) [ hir_id] ;
1861
- let mut diag = bad_placeholder_type ( tcx, ty. span ) ;
1841
+ let mut visitor = PlaceholderHirTyCollector :: new ( ) ;
1842
+ visitor. visit_ty ( ty) ;
1843
+ let mut diag = bad_placeholder_type ( tcx, visitor. 0 ) ;
1862
1844
let ret_ty = fn_sig. output ( ) ;
1863
1845
if ret_ty != tcx. types . err {
1864
1846
diag. span_suggestion (
1865
1847
ty. span ,
1866
- "replace this with the correct return type" ,
1848
+ "replace with the correct return type" ,
1867
1849
ret_ty. to_string ( ) ,
1868
1850
Applicability :: MaybeIncorrect ,
1869
1851
) ;
0 commit comments