@@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
176176 suggestion,
177177 Applicability :: HasPlaceholders ,
178178 ) ;
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+ ) ;
180183}
181184
182185/// 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 {
220223impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
221224 pub fn extract_type_name (
222225 & self ,
223- ty : Ty < ' tcx > ,
226+ arg : GenericArg < ' tcx > ,
224227 highlight : Option < ty:: print:: RegionHighlightMode > ,
225228 ) -> ( 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+ }
245268
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;
254273 }
274+ let _ = ty. print ( printer) ;
275+ ( s, None , ty. prefix_string ( ) , None , None )
255276 }
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+ }
257312
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" ) ,
262322 }
263- let _ = ty. print ( printer) ;
264- ( s, None , ty. prefix_string ( ) , None , None )
265323 }
266324
267- // FIXME(eddyb) generalize all of this to handle `ty::Const` inference variables as well.
268325 pub fn need_type_info_err (
269326 & self ,
270327 body_id : Option < hir:: BodyId > ,
271328 span : Span ,
272- ty : Ty < ' tcx > ,
329+ ty : GenericArg < ' tcx > ,
273330 error_code : TypeAnnotationNeeded ,
274331 ) -> DiagnosticBuilder < ' tcx > {
275332 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+ } ;
277339
278340 let mut local_visitor = FindHirNodeVisitor :: new ( & self , ty. into ( ) , span) ;
279341 let ty_to_string = |ty : Ty < ' tcx > | -> String {
@@ -545,55 +607,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
545607 // Avoid multiple labels pointing at `span`.
546608 err. span_label (
547609 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) ,
549611 ) ;
550612 }
551613
552614 err
553615 }
554616
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-
597617 /// If the `FnSig` for the method call can be found and type arguments are identified as
598618 /// needed, suggest annotating the call, otherwise point out the resulting type of the call.
599619 fn annotate_method_call (
@@ -647,7 +667,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
647667 ty : Ty < ' tcx > ,
648668 ) -> DiagnosticBuilder < ' tcx > {
649669 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 ) ;
651671
652672 let mut err = struct_span_err ! (
653673 self . tcx. sess,
@@ -656,18 +676,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
656676 "type inside {} must be known in this context" ,
657677 kind,
658678 ) ;
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+ ) ;
660683 err
661684 }
662685
663686 fn missing_type_msg (
687+ kind_str : & str ,
664688 type_name : & str ,
665689 descr : & str ,
666690 parent_name : Option < String > ,
667691 parent_descr : Option < & str > ,
668- ) -> Cow < ' static , str > {
692+ ) -> String {
669693 if type_name == "_" {
670- "cannot infer type" . into ( )
694+ format ! ( "cannot infer {}" , kind_str )
671695 } else {
672696 let parent_desc = if let Some ( parent_name) = parent_name {
673697 let parent_type_descr = if let Some ( parent_descr) = parent_descr {
@@ -681,7 +705,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
681705 "" . to_string ( )
682706 } ;
683707
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 ( )
685715 }
686716 }
687717}
0 commit comments