@@ -113,9 +113,9 @@ pub struct ItemCtxt<'tcx> {
113
113
///////////////////////////////////////////////////////////////////////////
114
114
115
115
#[ derive( Default ) ]
116
- crate struct PlaceholderHirTyCollector ( crate Vec < Span > ) ;
116
+ crate struct HirPlaceholderCollector ( crate Vec < Span > ) ;
117
117
118
- impl < ' v > Visitor < ' v > for PlaceholderHirTyCollector {
118
+ impl < ' v > Visitor < ' v > for HirPlaceholderCollector {
119
119
type Map = intravisit:: ErasedMap < ' v > ;
120
120
121
121
fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
@@ -137,6 +137,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
137
137
_ => { }
138
138
}
139
139
}
140
+ fn visit_array_length ( & mut self , length : & ' v hir:: ArrayLen ) {
141
+ if let & hir:: ArrayLen :: Infer ( _, span) = length {
142
+ self . 0 . push ( span) ;
143
+ }
144
+ intravisit:: walk_array_len ( self , length)
145
+ }
140
146
}
141
147
142
148
struct CollectItemTypesVisitor < ' tcx > {
@@ -181,7 +187,7 @@ crate fn placeholder_type_error<'tcx>(
181
187
sugg. push ( ( span, format ! ( ", {}" , type_name) ) ) ;
182
188
}
183
189
184
- let mut err = bad_placeholder ( tcx, "type" , placeholder_types, kind) ;
190
+ let mut err = bad_placeholder ( tcx, placeholder_types, kind) ;
185
191
186
192
// Suggest, but only if it is not a function in const or static
187
193
if suggest {
@@ -239,7 +245,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
239
245
_ => return ,
240
246
} ;
241
247
242
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
248
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
243
249
visitor. visit_item ( item) ;
244
250
245
251
placeholder_type_error (
@@ -317,7 +323,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
317
323
318
324
fn bad_placeholder < ' tcx > (
319
325
tcx : TyCtxt < ' tcx > ,
320
- placeholder_kind : & ' static str ,
321
326
mut spans : Vec < Span > ,
322
327
kind : & ' static str ,
323
328
) -> rustc_errors:: DiagnosticBuilder < ' tcx > {
@@ -328,8 +333,7 @@ fn bad_placeholder<'tcx>(
328
333
tcx. sess,
329
334
spans. clone( ) ,
330
335
E0121 ,
331
- "the {} placeholder `_` is not allowed within types on item signatures for {}" ,
332
- placeholder_kind,
336
+ "the placeholder `_` is not allowed within types on item signatures for {}" ,
333
337
kind
334
338
) ;
335
339
for span in spans {
@@ -387,7 +391,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
387
391
}
388
392
389
393
fn ty_infer ( & self , _: Option < & ty:: GenericParamDef > , span : Span ) -> Ty < ' tcx > {
390
- self . tcx ( ) . ty_error_with_message ( span, "bad_placeholder_type " )
394
+ self . tcx ( ) . ty_error_with_message ( span, "bad placeholder type " )
391
395
}
392
396
393
397
fn ct_infer (
@@ -396,13 +400,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
396
400
_: Option < & ty:: GenericParamDef > ,
397
401
span : Span ,
398
402
) -> & ' tcx Const < ' tcx > {
399
- bad_placeholder ( self . tcx ( ) , "const" , vec ! [ span] , "generic" ) . emit ( ) ;
400
- // Typeck doesn't expect erased regions to be returned from `type_of`.
401
403
let ty = self . tcx . fold_regions ( ty, & mut false , |r, _| match r {
402
404
ty:: ReErased => self . tcx . lifetimes . re_static ,
403
405
_ => r,
404
406
} ) ;
405
- self . tcx ( ) . const_error ( ty)
407
+ self . tcx ( ) . const_error_with_message ( ty, span , "bad placeholder constant" )
406
408
}
407
409
408
410
fn projected_ty_from_poly_trait_ref (
@@ -746,7 +748,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
746
748
match item. kind {
747
749
hir:: ForeignItemKind :: Fn ( ..) => tcx. ensure ( ) . fn_sig ( item. def_id ) ,
748
750
hir:: ForeignItemKind :: Static ( ..) => {
749
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
751
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
750
752
visitor. visit_foreign_item ( item) ;
751
753
placeholder_type_error (
752
754
tcx,
@@ -829,7 +831,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
829
831
hir:: ItemKind :: Const ( ty, ..) | hir:: ItemKind :: Static ( ty, ..) => {
830
832
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
831
833
if let hir:: TyKind :: TraitObject ( ..) = ty. kind {
832
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
834
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
833
835
visitor. visit_item ( it) ;
834
836
placeholder_type_error (
835
837
tcx,
@@ -865,7 +867,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
865
867
hir:: TraitItemKind :: Const ( ..) => {
866
868
tcx. ensure ( ) . type_of ( trait_item_id. def_id ) ;
867
869
// Account for `const C: _;`.
868
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
870
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
869
871
visitor. visit_trait_item ( trait_item) ;
870
872
placeholder_type_error ( tcx, None , & [ ] , visitor. 0 , false , None , "constant" ) ;
871
873
}
@@ -874,7 +876,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
874
876
tcx. ensure ( ) . item_bounds ( trait_item_id. def_id ) ;
875
877
tcx. ensure ( ) . type_of ( trait_item_id. def_id ) ;
876
878
// Account for `type T = _;`.
877
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
879
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
878
880
visitor. visit_trait_item ( trait_item) ;
879
881
placeholder_type_error ( tcx, None , & [ ] , visitor. 0 , false , None , "associated type" ) ;
880
882
}
@@ -883,7 +885,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
883
885
tcx. ensure ( ) . item_bounds ( trait_item_id. def_id ) ;
884
886
// #74612: Visit and try to find bad placeholders
885
887
// even if there is no concrete type.
886
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
888
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
887
889
visitor. visit_trait_item ( trait_item) ;
888
890
889
891
placeholder_type_error ( tcx, None , & [ ] , visitor. 0 , false , None , "associated type" ) ;
@@ -905,7 +907,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
905
907
}
906
908
hir:: ImplItemKind :: TyAlias ( _) => {
907
909
// Account for `type T = _;`
908
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
910
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
909
911
visitor. visit_impl_item ( impl_item) ;
910
912
911
913
placeholder_type_error ( tcx, None , & [ ] , visitor. 0 , false , None , "associated type" ) ;
@@ -1738,10 +1740,14 @@ fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
1738
1740
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
1739
1741
/// use inference to provide suggestions for the appropriate type if possible.
1740
1742
fn is_suggestable_infer_ty ( ty : & hir:: Ty < ' _ > ) -> bool {
1743
+ debug ! ( ?ty) ;
1741
1744
use hir:: TyKind :: * ;
1742
1745
match & ty. kind {
1743
1746
Infer => true ,
1744
- Slice ( ty) | Array ( ty, _) => is_suggestable_infer_ty ( ty) ,
1747
+ Slice ( ty) => is_suggestable_infer_ty ( ty) ,
1748
+ Array ( ty, length) => {
1749
+ is_suggestable_infer_ty ( ty) || matches ! ( length, hir:: ArrayLen :: Infer ( _, _) )
1750
+ }
1745
1751
Tup ( tys) => tys. iter ( ) . any ( is_suggestable_infer_ty) ,
1746
1752
Ptr ( mut_ty) | Rptr ( _, mut_ty) => is_suggestable_infer_ty ( mut_ty. ty ) ,
1747
1753
OpaqueDef ( _, generic_args) => are_suggestable_generic_args ( generic_args) ,
@@ -1793,9 +1799,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
1793
1799
} ) ;
1794
1800
let fn_sig = ty:: Binder :: dummy ( fn_sig) ;
1795
1801
1796
- let mut visitor = PlaceholderHirTyCollector :: default ( ) ;
1802
+ let mut visitor = HirPlaceholderCollector :: default ( ) ;
1797
1803
visitor. visit_ty ( ty) ;
1798
- let mut diag = bad_placeholder ( tcx, "type" , visitor. 0 , "return type" ) ;
1804
+ let mut diag = bad_placeholder ( tcx, visitor. 0 , "return type" ) ;
1799
1805
let ret_ty = fn_sig. skip_binder ( ) . output ( ) ;
1800
1806
if !ret_ty. references_error ( ) {
1801
1807
if !ret_ty. is_closure ( ) {
0 commit comments