@@ -9,6 +9,7 @@ use syntax::source_map::DesugaringKind;
9
9
use syntax:: symbol:: kw;
10
10
use syntax_pos:: Span ;
11
11
use errors:: { Applicability , DiagnosticBuilder } ;
12
+ use std:: borrow:: Cow ;
12
13
13
14
use rustc_error_codes:: * ;
14
15
@@ -113,6 +114,7 @@ fn closure_return_type_suggestion(
113
114
err : & mut DiagnosticBuilder < ' _ > ,
114
115
output : & FunctionRetTy ,
115
116
body : & Body ,
117
+ descr : & str ,
116
118
name : & str ,
117
119
ret : & str ,
118
120
) {
@@ -136,7 +138,7 @@ fn closure_return_type_suggestion(
136
138
suggestion,
137
139
Applicability :: HasPlaceholders ,
138
140
) ;
139
- err. span_label ( span, InferCtxt :: missing_type_msg ( & name) ) ;
141
+ err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr ) ) ;
140
142
}
141
143
142
144
/// 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> {
175
177
& self ,
176
178
ty : Ty < ' tcx > ,
177
179
highlight : Option < ty:: print:: RegionHighlightMode > ,
178
- ) -> ( String , Option < Span > ) {
180
+ ) -> ( String , Option < Span > , Cow < ' static , str > ) {
179
181
if let ty:: Infer ( ty:: TyVar ( ty_vid) ) = ty. kind {
180
182
let ty_vars = self . type_variables . borrow ( ) ;
181
183
let var_origin = ty_vars. var_origin ( ty_vid) ;
182
184
if let TypeVariableOriginKind :: TypeParameterDefinition ( name) = var_origin. kind {
183
185
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
+ ) ;
185
191
}
186
192
}
187
193
}
@@ -192,7 +198,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
192
198
printer. region_highlight_mode = highlight;
193
199
}
194
200
let _ = ty. print ( printer) ;
195
- ( s, None )
201
+ ( s, None , ty . prefix_string ( ) )
196
202
}
197
203
198
204
pub fn need_type_info_err (
@@ -203,7 +209,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
203
209
error_code : TypeAnnotationNeeded ,
204
210
) -> DiagnosticBuilder < ' tcx > {
205
211
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 ) ;
207
213
208
214
let mut local_visitor = FindLocalByTypeVisitor :: new ( & self , ty, & self . tcx . hir ( ) ) ;
209
215
let ty_to_string = |ty : Ty < ' tcx > | -> String {
@@ -308,6 +314,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
308
314
& mut err,
309
315
& decl. output ,
310
316
& body,
317
+ & descr,
311
318
& name,
312
319
& ret,
313
320
) ;
@@ -427,7 +434,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
427
434
span_label. label . is_some ( ) && span_label. span == span
428
435
} ) && local_visitor. found_arg_pattern . is_none ( )
429
436
{ // 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 ) ) ;
431
438
}
432
439
433
440
err
@@ -468,10 +475,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
468
475
) ;
469
476
} else {
470
477
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
+ }
475
487
}
476
488
}
477
489
}
@@ -484,19 +496,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
484
496
ty : Ty < ' tcx > ,
485
497
) -> DiagnosticBuilder < ' tcx > {
486
498
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 ) ;
488
500
let mut err = struct_span_err ! (
489
501
self . tcx. sess, span, E0698 , "type inside {} must be known in this context" , kind,
490
502
) ;
491
- err. span_label ( span, InferCtxt :: missing_type_msg ( & name) ) ;
503
+ err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr ) ) ;
492
504
err
493
505
}
494
506
495
- fn missing_type_msg ( type_name : & str ) -> String {
507
+ fn missing_type_msg ( type_name : & str , descr : & str ) -> Cow < ' static , str > {
496
508
if type_name == "_" {
497
- "cannot infer type" . to_owned ( )
509
+ "cannot infer type" . into ( )
498
510
} else {
499
- format ! ( "cannot infer type for `{}`" , type_name)
511
+ format ! ( "cannot infer type for {} `{}`" , descr , type_name) . into ( )
500
512
}
501
513
}
502
514
}
0 commit comments