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