@@ -77,11 +77,9 @@ impl InferenceDiagnosticsData {
77
77
!( self . name == "_" && matches ! ( self . kind, UnderspecifiedArgKind :: Type { .. } ) )
78
78
}
79
79
80
- fn where_x_is_kind ( & self , in_type : Ty < ' _ > , is_collect : bool ) -> & ' static str {
81
- if is_collect {
82
- "empty"
83
- } else if in_type. is_ty_infer ( ) {
84
- "anon"
80
+ fn where_x_is_kind ( & self , in_type : Ty < ' _ > ) -> & ' static str {
81
+ if in_type. is_ty_infer ( ) {
82
+ ""
85
83
} else if self . name == "_" {
86
84
// FIXME: Consider specializing this message if there is a single `_`
87
85
// in the type.
@@ -185,14 +183,20 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
185
183
printer
186
184
}
187
185
188
- fn ty_to_string < ' tcx > ( infcx : & InferCtxt < ' tcx > , ty : Ty < ' tcx > ) -> String {
186
+ fn ty_to_string < ' tcx > ( infcx : & InferCtxt < ' tcx > , ty : Ty < ' tcx > , def_id : Option < DefId > ) -> String {
189
187
let printer = fmt_printer ( infcx, Namespace :: TypeNS ) ;
190
188
let ty = infcx. resolve_vars_if_possible ( ty) ;
191
- match ty. kind ( ) {
189
+ match ( ty. kind ( ) , def_id ) {
192
190
// We don't want the regular output for `fn`s because it includes its path in
193
191
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
194
- ty:: FnDef ( ..) => ty. fn_sig ( infcx. tcx ) . print ( printer) . unwrap ( ) . into_buffer ( ) ,
195
- _ if ty. is_ty_infer ( ) => "Type" . to_string ( ) ,
192
+ ( ty:: FnDef ( ..) , _) => ty. fn_sig ( infcx. tcx ) . print ( printer) . unwrap ( ) . into_buffer ( ) ,
193
+ ( _, Some ( def_id) )
194
+ if ty. is_ty_infer ( )
195
+ && infcx. tcx . get_diagnostic_item ( sym:: iterator_collect_fn) == Some ( def_id) =>
196
+ {
197
+ "Vec<_>" . to_string ( )
198
+ }
199
+ _ if ty. is_ty_infer ( ) => "/* Type */" . to_string ( ) ,
196
200
// FIXME: The same thing for closures, but this only works when the closure
197
201
// does not capture anything.
198
202
//
@@ -216,15 +220,15 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
216
220
. map ( |args| {
217
221
args. tuple_fields ( )
218
222
. iter ( )
219
- . map ( |arg| ty_to_string ( infcx, arg) )
223
+ . map ( |arg| ty_to_string ( infcx, arg, None ) )
220
224
. collect :: < Vec < _ > > ( )
221
225
. join ( ", " )
222
226
} )
223
227
. unwrap_or_default ( ) ;
224
228
let ret = if fn_sig. output ( ) . skip_binder ( ) . is_unit ( ) {
225
229
String :: new ( )
226
230
} else {
227
- format ! ( " -> {}" , ty_to_string( infcx, fn_sig. output( ) . skip_binder( ) ) )
231
+ format ! ( " -> {}" , ty_to_string( infcx, fn_sig. output( ) . skip_binder( ) , None ) )
228
232
} ;
229
233
format ! ( "fn({}){}" , args, ret)
230
234
}
@@ -410,32 +414,28 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
410
414
let mut infer_subdiags = Vec :: new ( ) ;
411
415
let mut multi_suggestions = Vec :: new ( ) ;
412
416
match kind {
413
- InferSourceKind :: LetBinding { insert_span, pattern_name, ty, is_collect } => {
417
+ InferSourceKind :: LetBinding { insert_span, pattern_name, ty, def_id } => {
414
418
infer_subdiags. push ( SourceKindSubdiag :: LetLike {
415
419
span : insert_span,
416
420
name : pattern_name. map ( |name| name. to_string ( ) ) . unwrap_or_else ( String :: new) ,
417
- x_kind : arg_data. where_x_is_kind ( ty, is_collect ) ,
421
+ x_kind : arg_data. where_x_is_kind ( ty) ,
418
422
prefix_kind : arg_data. kind . clone ( ) ,
419
423
prefix : arg_data. kind . try_get_prefix ( ) . unwrap_or_default ( ) ,
420
424
arg_name : arg_data. name ,
421
425
kind : if pattern_name. is_some ( ) { "with_pattern" } else { "other" } ,
422
- type_name : if is_collect {
423
- "Vec<_>" . to_string ( )
424
- } else {
425
- ty_to_string ( self , ty)
426
- } ,
426
+ type_name : ty_to_string ( self , ty, def_id) ,
427
427
} ) ;
428
428
}
429
429
InferSourceKind :: ClosureArg { insert_span, ty } => {
430
430
infer_subdiags. push ( SourceKindSubdiag :: LetLike {
431
431
span : insert_span,
432
432
name : String :: new ( ) ,
433
- x_kind : arg_data. where_x_is_kind ( ty, false ) ,
433
+ x_kind : arg_data. where_x_is_kind ( ty) ,
434
434
prefix_kind : arg_data. kind . clone ( ) ,
435
435
prefix : arg_data. kind . try_get_prefix ( ) . unwrap_or_default ( ) ,
436
436
arg_name : arg_data. name ,
437
437
kind : "closure" ,
438
- type_name : ty_to_string ( self , ty) ,
438
+ type_name : ty_to_string ( self , ty, None ) ,
439
439
} ) ;
440
440
}
441
441
InferSourceKind :: GenericArg {
@@ -534,7 +534,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
534
534
) ) ;
535
535
}
536
536
InferSourceKind :: ClosureReturn { ty, data, should_wrap_expr } => {
537
- let ty_info = ty_to_string ( self , ty) ;
537
+ let ty_info = ty_to_string ( self , ty, None ) ;
538
538
multi_suggestions. push ( SourceKindMultiSuggestion :: new_closure_return (
539
539
ty_info,
540
540
data,
@@ -622,7 +622,7 @@ enum InferSourceKind<'tcx> {
622
622
insert_span : Span ,
623
623
pattern_name : Option < Ident > ,
624
624
ty : Ty < ' tcx > ,
625
- is_collect : bool ,
625
+ def_id : Option < DefId > ,
626
626
} ,
627
627
ClosureArg {
628
628
insert_span : Span ,
@@ -677,7 +677,7 @@ impl<'tcx> InferSourceKind<'tcx> {
677
677
if ty. is_closure ( ) {
678
678
( "closure" , closure_as_fn_str ( infcx, ty) )
679
679
} else if !ty. is_ty_infer ( ) {
680
- ( "normal" , ty_to_string ( infcx, ty) )
680
+ ( "normal" , ty_to_string ( infcx, ty, None ) )
681
681
} else {
682
682
( "other" , String :: new ( ) )
683
683
}
@@ -807,14 +807,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
807
807
let cost = self . source_cost ( & new_source) + self . attempt ;
808
808
debug ! ( ?cost) ;
809
809
self . attempt += 1 ;
810
- if let Some ( InferSource { kind : InferSourceKind :: GenericArg { def_id, ..} , .. } ) = self . infer_source
811
- && self . infcx . tcx . get_diagnostic_item ( sym:: iterator_collect_fn) == Some ( def_id)
812
- && let InferSourceKind :: LetBinding { ref ty, ref mut is_collect, ..} = new_source. kind
810
+ if let Some ( InferSource { kind : InferSourceKind :: GenericArg { def_id : did, ..} , .. } ) = self . infer_source
811
+ && let InferSourceKind :: LetBinding { ref ty, ref mut def_id, ..} = new_source. kind
813
812
&& ty. is_ty_infer ( )
814
813
{
815
814
// Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
816
815
// `let x: _ = iter.collect();`, as this is a very common case.
817
- * is_collect = true ;
816
+ * def_id = Some ( did ) ;
818
817
}
819
818
if cost < self . infer_source_cost {
820
819
self . infer_source_cost = cost;
@@ -1113,7 +1112,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
1113
1112
insert_span : local. pat . span . shrink_to_hi ( ) ,
1114
1113
pattern_name : local. pat . simple_ident ( ) ,
1115
1114
ty,
1116
- is_collect : false ,
1115
+ def_id : None ,
1117
1116
} ,
1118
1117
} )
1119
1118
}
0 commit comments