@@ -20,7 +20,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
2020use rustc_middle:: ty:: { self , DefIdTree , InferConst } ;
2121use rustc_middle:: ty:: { GenericArg , GenericArgKind , SubstsRef } ;
2222use rustc_middle:: ty:: { IsSuggestable , Ty , TyCtxt , TypeckResults } ;
23- use rustc_span:: symbol:: { kw, Ident } ;
23+ use rustc_span:: symbol:: { kw, sym , Ident } ;
2424use rustc_span:: { BytePos , Span } ;
2525use std:: borrow:: Cow ;
2626use std:: iter;
@@ -78,12 +78,12 @@ impl InferenceDiagnosticsData {
7878 }
7979
8080 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 == "_" {
8482 // FIXME: Consider specializing this message if there is a single `_`
8583 // in the type.
8684 "underscore"
85+ } else if in_type. is_ty_infer ( ) {
86+ "empty"
8787 } else {
8888 "has_name"
8989 }
@@ -368,6 +368,7 @@ impl<'tcx> InferCtxt<'tcx> {
368368}
369369
370370impl < ' tcx > TypeErrCtxt < ' _ , ' tcx > {
371+ #[ instrument( level = "debug" , skip( self , error_code) ) ]
371372 pub fn emit_inference_failure_err (
372373 & self ,
373374 body_id : Option < hir:: BodyId > ,
@@ -406,16 +407,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
406407 let mut infer_subdiags = Vec :: new ( ) ;
407408 let mut multi_suggestions = Vec :: new ( ) ;
408409 match kind {
409- InferSourceKind :: LetBinding { insert_span, pattern_name, ty } => {
410+ InferSourceKind :: LetBinding { insert_span, pattern_name, ty, is_collect } => {
410411 infer_subdiags. push ( SourceKindSubdiag :: LetLike {
411412 span : insert_span,
412413 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) } ,
414415 prefix_kind : arg_data. kind . clone ( ) ,
415416 prefix : arg_data. kind . try_get_prefix ( ) . unwrap_or_default ( ) ,
416417 arg_name : arg_data. name ,
417418 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+ } ,
419424 } ) ;
420425 }
421426 InferSourceKind :: ClosureArg { insert_span, ty } => {
@@ -608,6 +613,7 @@ enum InferSourceKind<'tcx> {
608613 insert_span : Span ,
609614 pattern_name : Option < Ident > ,
610615 ty : Ty < ' tcx > ,
616+ is_collect : bool ,
611617 } ,
612618 ClosureArg {
613619 insert_span : Span ,
@@ -788,10 +794,19 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
788794 /// Uses `fn source_cost` to determine whether this inference source is preferable to
789795 /// previous sources. We generally prefer earlier sources.
790796 #[ 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 > ) {
792798 let cost = self . source_cost ( & new_source) + self . attempt ;
793799 debug ! ( ?cost) ;
794800 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+ }
795810 if cost < self . infer_source_cost {
796811 self . infer_source_cost = cost;
797812 self . infer_source = Some ( new_source) ;
@@ -1089,6 +1104,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
10891104 insert_span : local. pat . span . shrink_to_hi ( ) ,
10901105 pattern_name : local. pat . simple_ident ( ) ,
10911106 ty,
1107+ is_collect : false ,
10921108 } ,
10931109 } )
10941110 }
0 commit comments