@@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
176
176
suggestion,
177
177
Applicability :: HasPlaceholders ,
178
178
) ;
179
- err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr, parent_name, parent_descr) ) ;
179
+ err. span_label (
180
+ span,
181
+ InferCtxt :: missing_type_msg ( "type" , & name, & descr, parent_name, parent_descr) ,
182
+ ) ;
180
183
}
181
184
182
185
/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -220,60 +223,119 @@ impl Into<rustc_errors::DiagnosticId> for TypeAnnotationNeeded {
220
223
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
221
224
pub fn extract_type_name (
222
225
& self ,
223
- ty : Ty < ' tcx > ,
226
+ arg : GenericArg < ' tcx > ,
224
227
highlight : Option < ty:: print:: RegionHighlightMode > ,
225
228
) -> ( String , Option < Span > , Cow < ' static , str > , Option < String > , Option < & ' static str > ) {
226
- if let ty:: Infer ( ty:: TyVar ( ty_vid) ) = * ty. kind ( ) {
227
- let mut inner = self . inner . borrow_mut ( ) ;
228
- let ty_vars = & inner. type_variables ( ) ;
229
- let var_origin = ty_vars. var_origin ( ty_vid) ;
230
- if let TypeVariableOriginKind :: TypeParameterDefinition ( name, def_id) = var_origin. kind {
231
- let parent_def_id = def_id. and_then ( |def_id| self . tcx . parent ( def_id) ) ;
232
- let ( parent_name, parent_desc) = if let Some ( parent_def_id) = parent_def_id {
233
- let parent_name = self
234
- . tcx
235
- . def_key ( parent_def_id)
236
- . disambiguated_data
237
- . data
238
- . get_opt_name ( )
239
- . map ( |parent_symbol| parent_symbol. to_string ( ) ) ;
240
-
241
- ( parent_name, Some ( self . tcx . def_kind ( parent_def_id) . descr ( parent_def_id) ) )
242
- } else {
243
- ( None , None )
244
- } ;
229
+ match arg. unpack ( ) {
230
+ GenericArgKind :: Type ( ty) => {
231
+ if let ty:: Infer ( ty:: TyVar ( ty_vid) ) = * ty. kind ( ) {
232
+ let mut inner = self . inner . borrow_mut ( ) ;
233
+ let ty_vars = & inner. type_variables ( ) ;
234
+ let var_origin = ty_vars. var_origin ( ty_vid) ;
235
+ if let TypeVariableOriginKind :: TypeParameterDefinition ( name, def_id) =
236
+ var_origin. kind
237
+ {
238
+ let parent_def_id = def_id. and_then ( |def_id| self . tcx . parent ( def_id) ) ;
239
+ let ( parent_name, parent_desc) = if let Some ( parent_def_id) = parent_def_id
240
+ {
241
+ let parent_name = self
242
+ . tcx
243
+ . def_key ( parent_def_id)
244
+ . disambiguated_data
245
+ . data
246
+ . get_opt_name ( )
247
+ . map ( |parent_symbol| parent_symbol. to_string ( ) ) ;
248
+
249
+ (
250
+ parent_name,
251
+ Some ( self . tcx . def_kind ( parent_def_id) . descr ( parent_def_id) ) ,
252
+ )
253
+ } else {
254
+ ( None , None )
255
+ } ;
256
+
257
+ if name != kw:: SelfUpper {
258
+ return (
259
+ name. to_string ( ) ,
260
+ Some ( var_origin. span ) ,
261
+ "type parameter" . into ( ) ,
262
+ parent_name,
263
+ parent_desc,
264
+ ) ;
265
+ }
266
+ }
267
+ }
245
268
246
- if name != kw:: SelfUpper {
247
- return (
248
- name. to_string ( ) ,
249
- Some ( var_origin. span ) ,
250
- "type parameter" . into ( ) ,
251
- parent_name,
252
- parent_desc,
253
- ) ;
269
+ let mut s = String :: new ( ) ;
270
+ let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , & mut s, Namespace :: TypeNS ) ;
271
+ if let Some ( highlight) = highlight {
272
+ printer. region_highlight_mode = highlight;
254
273
}
274
+ let _ = ty. print ( printer) ;
275
+ ( s, None , ty. prefix_string ( ) , None , None )
255
276
}
256
- }
277
+ GenericArgKind :: Const ( ct) => {
278
+ if let ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) = ct. val {
279
+ let origin =
280
+ self . inner . borrow_mut ( ) . const_unification_table ( ) . probe_value ( vid) . origin ;
281
+ if let ConstVariableOriginKind :: ConstParameterDefinition ( name, def_id) =
282
+ origin. kind
283
+ {
284
+ let parent_def_id = self . tcx . parent ( def_id) ;
285
+ let ( parent_name, parent_descr) = if let Some ( parent_def_id) = parent_def_id
286
+ {
287
+ let parent_name = self
288
+ . tcx
289
+ . def_key ( parent_def_id)
290
+ . disambiguated_data
291
+ . data
292
+ . get_opt_name ( )
293
+ . map ( |parent_symbol| parent_symbol. to_string ( ) ) ;
294
+
295
+ (
296
+ parent_name,
297
+ Some ( self . tcx . def_kind ( parent_def_id) . descr ( parent_def_id) ) ,
298
+ )
299
+ } else {
300
+ ( None , None )
301
+ } ;
302
+
303
+ return (
304
+ name. to_string ( ) ,
305
+ Some ( origin. span ) ,
306
+ "const parameter" . into ( ) ,
307
+ parent_name,
308
+ parent_descr,
309
+ ) ;
310
+ }
311
+ }
257
312
258
- let mut s = String :: new ( ) ;
259
- let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , & mut s, Namespace :: TypeNS ) ;
260
- if let Some ( highlight) = highlight {
261
- printer. region_highlight_mode = highlight;
313
+ let mut s = String :: new ( ) ;
314
+ let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , & mut s, Namespace :: TypeNS ) ;
315
+ if let Some ( highlight) = highlight {
316
+ printer. region_highlight_mode = highlight;
317
+ }
318
+ let _ = ct. print ( printer) ;
319
+ ( s, None , "<TODO>" . into ( ) , None , None )
320
+ }
321
+ GenericArgKind :: Lifetime ( _) => bug ! ( "unexpected lifetime" ) ,
262
322
}
263
- let _ = ty. print ( printer) ;
264
- ( s, None , ty. prefix_string ( ) , None , None )
265
323
}
266
324
267
- // FIXME(eddyb) generalize all of this to handle `ty::Const` inference variables as well.
268
325
pub fn need_type_info_err (
269
326
& self ,
270
327
body_id : Option < hir:: BodyId > ,
271
328
span : Span ,
272
- ty : Ty < ' tcx > ,
329
+ ty : GenericArg < ' tcx > ,
273
330
error_code : TypeAnnotationNeeded ,
274
331
) -> DiagnosticBuilder < ' tcx > {
275
332
let ty = self . resolve_vars_if_possible ( & ty) ;
276
- let ( name, name_sp, descr, parent_name, parent_descr) = self . extract_type_name ( & ty, None ) ;
333
+ let ( name, name_sp, descr, parent_name, parent_descr) = self . extract_type_name ( ty, None ) ;
334
+ let kind_str = match ty. unpack ( ) {
335
+ GenericArgKind :: Type ( _) => "type" ,
336
+ GenericArgKind :: Const ( _) => "the value" ,
337
+ GenericArgKind :: Lifetime ( _) => bug ! ( "unexpected lifetime" ) ,
338
+ } ;
277
339
278
340
let mut local_visitor = FindHirNodeVisitor :: new ( & self , ty. into ( ) , span) ;
279
341
let ty_to_string = |ty : Ty < ' tcx > | -> String {
@@ -545,55 +607,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
545
607
// Avoid multiple labels pointing at `span`.
546
608
err. span_label (
547
609
span,
548
- InferCtxt :: missing_type_msg ( & name, & descr, parent_name, parent_descr) ,
610
+ InferCtxt :: missing_type_msg ( kind_str , & name, & descr, parent_name, parent_descr) ,
549
611
) ;
550
612
}
551
613
552
614
err
553
615
}
554
616
555
- // FIXME(const_generics): We should either try and merge this with `need_type_info_err`
556
- // or improve the errors created here.
557
- //
558
- // Unlike for type inference variables, we don't yet store the origin of const inference variables.
559
- // This is needed for to get a more relevant error span.
560
- pub fn need_type_info_err_const (
561
- & self ,
562
- body_id : Option < hir:: BodyId > ,
563
- span : Span ,
564
- ct : & ' tcx ty:: Const < ' tcx > ,
565
- error_code : TypeAnnotationNeeded ,
566
- ) -> DiagnosticBuilder < ' tcx > {
567
- let mut local_visitor = FindHirNodeVisitor :: new ( & self , ct. into ( ) , span) ;
568
- if let Some ( body_id) = body_id {
569
- let expr = self . tcx . hir ( ) . expect_expr ( body_id. hir_id ) ;
570
- local_visitor. visit_expr ( expr) ;
571
- }
572
-
573
- let mut param_name = None ;
574
- let span = if let ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) = ct. val {
575
- let origin = self . inner . borrow_mut ( ) . const_unification_table ( ) . probe_value ( vid) . origin ;
576
- if let ConstVariableOriginKind :: ConstParameterDefinition ( param) = origin. kind {
577
- param_name = Some ( param) ;
578
- }
579
- origin. span
580
- } else {
581
- local_visitor. target_span
582
- } ;
583
-
584
- let error_code = error_code. into ( ) ;
585
- let mut err =
586
- self . tcx . sess . struct_span_err_with_code ( span, "type annotations needed" , error_code) ;
587
-
588
- if let Some ( param_name) = param_name {
589
- err. note ( & format ! ( "cannot infer the value of the const parameter `{}`" , param_name) ) ;
590
- } else {
591
- err. note ( "unable to infer the value of a const parameter" ) ;
592
- }
593
-
594
- err
595
- }
596
-
597
617
/// If the `FnSig` for the method call can be found and type arguments are identified as
598
618
/// needed, suggest annotating the call, otherwise point out the resulting type of the call.
599
619
fn annotate_method_call (
@@ -647,7 +667,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
647
667
ty : Ty < ' tcx > ,
648
668
) -> DiagnosticBuilder < ' tcx > {
649
669
let ty = self . resolve_vars_if_possible ( & ty) ;
650
- let ( name, _, descr, parent_name, parent_descr) = self . extract_type_name ( & ty , None ) ;
670
+ let ( name, _, descr, parent_name, parent_descr) = self . extract_type_name ( ty . into ( ) , None ) ;
651
671
652
672
let mut err = struct_span_err ! (
653
673
self . tcx. sess,
@@ -656,18 +676,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
656
676
"type inside {} must be known in this context" ,
657
677
kind,
658
678
) ;
659
- err. span_label ( span, InferCtxt :: missing_type_msg ( & name, & descr, parent_name, parent_descr) ) ;
679
+ err. span_label (
680
+ span,
681
+ InferCtxt :: missing_type_msg ( "type" , & name, & descr, parent_name, parent_descr) ,
682
+ ) ;
660
683
err
661
684
}
662
685
663
686
fn missing_type_msg (
687
+ kind_str : & str ,
664
688
type_name : & str ,
665
689
descr : & str ,
666
690
parent_name : Option < String > ,
667
691
parent_descr : Option < & str > ,
668
- ) -> Cow < ' static , str > {
692
+ ) -> String {
669
693
if type_name == "_" {
670
- "cannot infer type" . into ( )
694
+ format ! ( "cannot infer {}" , kind_str )
671
695
} else {
672
696
let parent_desc = if let Some ( parent_name) = parent_name {
673
697
let parent_type_descr = if let Some ( parent_descr) = parent_descr {
@@ -681,7 +705,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
681
705
"" . to_string ( )
682
706
} ;
683
707
684
- format ! ( "cannot infer type for {} `{}`{}" , descr, type_name, parent_desc) . into ( )
708
+ let preposition = if "value" == kind_str { "of" } else { "for" } ;
709
+ // For example: "cannot infer type for type parameter `T`"
710
+ format ! (
711
+ "cannot infer {} {} {} `{}`{}" ,
712
+ kind_str, preposition, descr, type_name, parent_desc
713
+ )
714
+ . into ( )
685
715
}
686
716
}
687
717
}
0 commit comments