@@ -20,7 +20,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
20
20
use rustc_middle:: ty:: { self , DefIdTree , InferConst } ;
21
21
use rustc_middle:: ty:: { GenericArg , GenericArgKind , SubstsRef } ;
22
22
use rustc_middle:: ty:: { IsSuggestable , Ty , TyCtxt , TypeckResults } ;
23
- use rustc_span:: symbol:: { kw, Ident } ;
23
+ use rustc_span:: symbol:: { kw, sym , Ident } ;
24
24
use rustc_span:: { BytePos , Span } ;
25
25
use std:: borrow:: Cow ;
26
26
use std:: iter;
@@ -78,12 +78,12 @@ impl InferenceDiagnosticsData {
78
78
}
79
79
80
80
fn where_x_is_kind ( & self , in_type : Ty < ' _ > ) -> & ' static str {
81
- if in_type. is_ty_infer ( ) {
82
- "empty"
83
- } else if self . name == "_" {
81
+ if self . name == "_" {
84
82
// FIXME: Consider specializing this message if there is a single `_`
85
83
// in the type.
86
84
"underscore"
85
+ } else if in_type. is_ty_infer ( ) {
86
+ "empty"
87
87
} else {
88
88
"has_name"
89
89
}
@@ -368,6 +368,7 @@ impl<'tcx> InferCtxt<'tcx> {
368
368
}
369
369
370
370
impl < ' tcx > TypeErrCtxt < ' _ , ' tcx > {
371
+ #[ instrument( level = "debug" , skip( self , error_code) ) ]
371
372
pub fn emit_inference_failure_err (
372
373
& self ,
373
374
body_id : Option < hir:: BodyId > ,
@@ -406,16 +407,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
406
407
let mut infer_subdiags = Vec :: new ( ) ;
407
408
let mut multi_suggestions = Vec :: new ( ) ;
408
409
match kind {
409
- InferSourceKind :: LetBinding { insert_span, pattern_name, ty } => {
410
+ InferSourceKind :: LetBinding { insert_span, pattern_name, ty, is_collect } => {
410
411
infer_subdiags. push ( SourceKindSubdiag :: LetLike {
411
412
span : insert_span,
412
413
name : pattern_name. map ( |name| name. to_string ( ) ) . unwrap_or_else ( String :: new) ,
413
- x_kind : arg_data. where_x_is_kind ( ty) ,
414
+ x_kind : if is_collect { "empty" } else { arg_data. where_x_is_kind ( ty) } ,
414
415
prefix_kind : arg_data. kind . clone ( ) ,
415
416
prefix : arg_data. kind . try_get_prefix ( ) . unwrap_or_default ( ) ,
416
417
arg_name : arg_data. name ,
417
418
kind : if pattern_name. is_some ( ) { "with_pattern" } else { "other" } ,
418
- type_name : ty_to_string ( self , ty) ,
419
+ type_name : if is_collect {
420
+ "Vec<_>" . to_string ( )
421
+ } else {
422
+ ty_to_string ( self , ty)
423
+ } ,
419
424
} ) ;
420
425
}
421
426
InferSourceKind :: ClosureArg { insert_span, ty } => {
@@ -608,6 +613,7 @@ enum InferSourceKind<'tcx> {
608
613
insert_span : Span ,
609
614
pattern_name : Option < Ident > ,
610
615
ty : Ty < ' tcx > ,
616
+ is_collect : bool ,
611
617
} ,
612
618
ClosureArg {
613
619
insert_span : Span ,
@@ -788,10 +794,19 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
788
794
/// Uses `fn source_cost` to determine whether this inference source is preferable to
789
795
/// previous sources. We generally prefer earlier sources.
790
796
#[ instrument( level = "debug" , skip( self ) ) ]
791
- fn update_infer_source ( & mut self , new_source : InferSource < ' tcx > ) {
797
+ fn update_infer_source ( & mut self , mut new_source : InferSource < ' tcx > ) {
792
798
let cost = self . source_cost ( & new_source) + self . attempt ;
793
799
debug ! ( ?cost) ;
794
800
self . attempt += 1 ;
801
+ if let Some ( InferSource { kind : InferSourceKind :: GenericArg { def_id, ..} , .. } ) = self . infer_source
802
+ && self . infcx . tcx . get_diagnostic_item ( sym:: iterator_collect_fn) == Some ( def_id)
803
+ && let InferSourceKind :: LetBinding { ref ty, ref mut is_collect, ..} = new_source. kind
804
+ && ty. is_ty_infer ( )
805
+ {
806
+ // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
807
+ // `let x: _ = iter.collect();`, as this is a very common case.
808
+ * is_collect = true ;
809
+ }
795
810
if cost < self . infer_source_cost {
796
811
self . infer_source_cost = cost;
797
812
self . infer_source = Some ( new_source) ;
@@ -1089,6 +1104,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
1089
1104
insert_span : local. pat . span . shrink_to_hi ( ) ,
1090
1105
pattern_name : local. pat . simple_ident ( ) ,
1091
1106
ty,
1107
+ is_collect : false ,
1092
1108
} ,
1093
1109
} )
1094
1110
}
0 commit comments