@@ -150,12 +150,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
150
150
& self ,
151
151
ty : Ty < ' tcx > ,
152
152
highlight : Option < ty:: print:: RegionHighlightMode > ,
153
- ) -> String {
153
+ ) -> ( String , Option < Span > ) {
154
154
if let ty:: Infer ( ty:: TyVar ( ty_vid) ) = ty. sty {
155
155
let ty_vars = self . type_variables . borrow ( ) ;
156
- if let TypeVariableOriginKind :: TypeParameterDefinition ( name ) =
157
- ty_vars . var_origin ( ty_vid ) . kind {
158
- return name. to_string ( ) ;
156
+ let var_origin = ty_vars . var_origin ( ty_vid ) ;
157
+ if let TypeVariableOriginKind :: TypeParameterDefinition ( name ) = var_origin. kind {
158
+ return ( name. to_string ( ) , Some ( var_origin . span ) ) ;
159
159
}
160
160
}
161
161
@@ -165,7 +165,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
165
165
printer. region_highlight_mode = highlight;
166
166
}
167
167
let _ = ty. print ( printer) ;
168
- s
168
+ ( s , None )
169
169
}
170
170
171
171
pub fn need_type_info_err (
@@ -175,7 +175,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
175
175
ty : Ty < ' tcx > ,
176
176
) -> DiagnosticBuilder < ' tcx > {
177
177
let ty = self . resolve_vars_if_possible ( & ty) ;
178
- let name = self . extract_type_name ( & ty, None ) ;
178
+ let ( name, name_sp ) = self . extract_type_name ( & ty, None ) ;
179
179
180
180
let mut local_visitor = FindLocalByTypeVisitor :: new ( & self , ty, & self . tcx . hir ( ) ) ;
181
181
let ty_to_string = |ty : Ty < ' tcx > | -> String {
@@ -200,6 +200,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
200
200
}
201
201
let err_span = if let Some ( pattern) = local_visitor. found_arg_pattern {
202
202
pattern. span
203
+ } else if let Some ( span) = name_sp {
204
+ // `span` here lets us point at `sum` instead of the entire right hand side expr:
205
+ // error[E0282]: type annotations needed
206
+ // --> file2.rs:3:15
207
+ // |
208
+ // 3 | let _ = x.sum() as f64;
209
+ // | ^^^ cannot infer type for `S`
210
+ span
203
211
} else {
204
212
span
205
213
} ;
@@ -325,6 +333,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
325
333
} ;
326
334
err. span_label ( pattern. span , msg) ;
327
335
}
336
+ // Instead of the following:
337
+ // error[E0282]: type annotations needed
338
+ // --> file2.rs:3:15
339
+ // |
340
+ // 3 | let _ = x.sum() as f64;
341
+ // | --^^^--------- cannot infer type for `S`
342
+ // |
343
+ // = note: type must be known at this point
344
+ // We want:
345
+ // error[E0282]: type annotations needed
346
+ // --> file2.rs:3:15
347
+ // |
348
+ // 3 | let _ = x.sum() as f64;
349
+ // | ^^^ cannot infer type for `S`
350
+ // |
351
+ // = note: type must be known at this point
352
+ let span = name_sp. unwrap_or ( span) ;
328
353
if !err. span . span_labels ( ) . iter ( ) . any ( |span_label| {
329
354
span_label. label . is_some ( ) && span_label. span == span
330
355
} ) && local_visitor. found_arg_pattern . is_none ( )
@@ -342,7 +367,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
342
367
ty : Ty < ' tcx > ,
343
368
) -> DiagnosticBuilder < ' tcx > {
344
369
let ty = self . resolve_vars_if_possible ( & ty) ;
345
- let name = self . extract_type_name ( & ty, None ) ;
370
+ let name = self . extract_type_name ( & ty, None ) . 0 ;
346
371
let mut err = struct_span_err ! (
347
372
self . tcx. sess, span, E0698 , "type inside {} must be known in this context" , kind,
348
373
) ;
0 commit comments