@@ -9,6 +9,7 @@ use syntax::source_map::DesugaringKind;
99use syntax:: symbol:: kw;
1010use syntax_pos:: Span ;
1111use errors:: { Applicability , DiagnosticBuilder } ;
12+ use std:: borrow:: Cow ;
1213
1314use rustc_error_codes:: * ;
1415
@@ -113,6 +114,7 @@ fn closure_return_type_suggestion(
113114 err : & mut DiagnosticBuilder < ' _ > ,
114115 output : & FunctionRetTy ,
115116 body : & Body ,
117+ descr : & str ,
116118 name : & str ,
117119 ret : & str ,
118120) {
@@ -136,7 +138,7 @@ fn closure_return_type_suggestion(
136138 suggestion,
137139 Applicability :: HasPlaceholders ,
138140 ) ;
139- err. span_label ( span, InferCtxt :: missing_type_msg ( & name) ) ;
141+ err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr ) ) ;
140142}
141143
142144/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -175,13 +177,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
175177 & self ,
176178 ty : Ty < ' tcx > ,
177179 highlight : Option < ty:: print:: RegionHighlightMode > ,
178- ) -> ( String , Option < Span > ) {
180+ ) -> ( String , Option < Span > , Cow < ' static , str > ) {
179181 if let ty:: Infer ( ty:: TyVar ( ty_vid) ) = ty. kind {
180182 let ty_vars = self . type_variables . borrow ( ) ;
181183 let var_origin = ty_vars. var_origin ( ty_vid) ;
182184 if let TypeVariableOriginKind :: TypeParameterDefinition ( name) = var_origin. kind {
183185 if name != kw:: SelfUpper {
184- return ( name. to_string ( ) , Some ( var_origin. span ) ) ;
186+ return (
187+ name. to_string ( ) ,
188+ Some ( var_origin. span ) ,
189+ "type parameter" . into ( ) ,
190+ ) ;
185191 }
186192 }
187193 }
@@ -192,7 +198,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
192198 printer. region_highlight_mode = highlight;
193199 }
194200 let _ = ty. print ( printer) ;
195- ( s, None )
201+ ( s, None , ty . prefix_string ( ) )
196202 }
197203
198204 pub fn need_type_info_err (
@@ -203,7 +209,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
203209 error_code : TypeAnnotationNeeded ,
204210 ) -> DiagnosticBuilder < ' tcx > {
205211 let ty = self . resolve_vars_if_possible ( & ty) ;
206- let ( name, name_sp) = self . extract_type_name ( & ty, None ) ;
212+ let ( name, name_sp, descr ) = self . extract_type_name ( & ty, None ) ;
207213
208214 let mut local_visitor = FindLocalByTypeVisitor :: new ( & self , ty, & self . tcx . hir ( ) ) ;
209215 let ty_to_string = |ty : Ty < ' tcx > | -> String {
@@ -308,6 +314,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
308314 & mut err,
309315 & decl. output ,
310316 & body,
317+ & descr,
311318 & name,
312319 & ret,
313320 ) ;
@@ -427,7 +434,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
427434 span_label. label . is_some ( ) && span_label. span == span
428435 } ) && local_visitor. found_arg_pattern . is_none ( )
429436 { // Avoid multiple labels pointing at `span`.
430- err. span_label ( span, InferCtxt :: missing_type_msg ( & name) ) ;
437+ err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr ) ) ;
431438 }
432439
433440 err
@@ -468,10 +475,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
468475 ) ;
469476 } else {
470477 let sig = self . tcx . fn_sig ( did) ;
471- err. span_label ( e. span , & format ! (
472- "this method call resolves to `{:?}`" ,
473- sig. output( ) . skip_binder( ) ,
474- ) ) ;
478+ let bound_output = sig. output ( ) ;
479+ let output = bound_output. skip_binder ( ) ;
480+ err. span_label ( e. span , & format ! ( "this method call resolves to `{:?}`" , output) ) ;
481+ let kind = & output. kind ;
482+ if let ty:: Projection ( proj) | ty:: UnnormalizedProjection ( proj) = kind {
483+ if let Some ( span) = self . tcx . hir ( ) . span_if_local ( proj. item_def_id ) {
484+ err. span_label ( span, & format ! ( "`{:?}` defined here" , output) ) ;
485+ }
486+ }
475487 }
476488 }
477489 }
@@ -484,19 +496,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
484496 ty : Ty < ' tcx > ,
485497 ) -> DiagnosticBuilder < ' tcx > {
486498 let ty = self . resolve_vars_if_possible ( & ty) ;
487- let name = self . extract_type_name ( & ty, None ) . 0 ;
499+ let ( name, _ , descr ) = self . extract_type_name ( & ty, None ) ;
488500 let mut err = struct_span_err ! (
489501 self . tcx. sess, span, E0698 , "type inside {} must be known in this context" , kind,
490502 ) ;
491- err. span_label ( span, InferCtxt :: missing_type_msg ( & name) ) ;
503+ err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr ) ) ;
492504 err
493505 }
494506
495- fn missing_type_msg ( type_name : & str ) -> String {
507+ fn missing_type_msg ( type_name : & str , descr : & str ) -> Cow < ' static , str > {
496508 if type_name == "_" {
497- "cannot infer type" . to_owned ( )
509+ "cannot infer type" . into ( )
498510 } else {
499- format ! ( "cannot infer type for `{}`" , type_name)
511+ format ! ( "cannot infer type for {} `{}`" , descr , type_name) . into ( )
500512 }
501513 }
502514}
0 commit comments