@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMut
1212use rustc_middle:: ty:: print:: { FmtPrinter , PrettyPrinter , Print , Printer } ;
1313use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , Subst , SubstsRef } ;
1414use rustc_middle:: ty:: { self , DefIdTree , GenericParamDefKind , InferConst } ;
15- use rustc_middle:: ty:: { Ty , TyCtxt } ;
15+ use rustc_middle:: ty:: { Ty , TyCtxt , TypeckResults } ;
1616use rustc_span:: symbol:: { kw, Ident } ;
1717use rustc_span:: { BytePos , Span } ;
1818use std:: borrow:: Cow ;
@@ -272,7 +272,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
272272 parent : None ,
273273 }
274274 } else {
275- // FIXME: This code seems a bit wrong, idk.
275+ // If we end up here the `FindInferSourceVisitor`
276+ // won't work, as its expected argument isn't an inference variable.
277+ //
278+ // FIXME: Ideally we should look into the generic constant
279+ // to figure out which inference var is actually unresolved so that
280+ // this path is unreachable.
276281 let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , Namespace :: ValueNS ) ;
277282 if let Some ( highlight) = highlight {
278283 printer. region_highlight_mode = highlight;
@@ -289,6 +294,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
289294 }
290295 }
291296
297+ /// Used as a fallback in [InferCtxt::emit_inference_failure_err]
298+ /// in case we weren't able to get a better error.
299+ fn bad_inference_failure_err (
300+ & self ,
301+ span : Span ,
302+ arg_data : InferenceDiagnosticsData ,
303+ error_code : TypeAnnotationNeeded ,
304+ ) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > {
305+ let error_code = error_code. into ( ) ;
306+ let mut err = self . tcx . sess . struct_span_err_with_code (
307+ span,
308+ & format ! ( "type annotations needed" ) ,
309+ error_code,
310+ ) ;
311+ err. span_label ( span, arg_data. cannot_infer_msg ( ) ) ;
312+ err
313+ }
314+
292315 pub fn emit_inference_failure_err (
293316 & self ,
294317 body_id : Option < hir:: BodyId > ,
@@ -301,25 +324,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
301324 let arg = self . resolve_vars_if_possible ( arg) ;
302325 let arg_data = self . extract_inference_diagnostics_data ( arg, None ) ;
303326
304- let mut local_visitor = FindInferSourceVisitor :: new ( & self , arg) ;
327+ let Some ( typeck_results) = self . in_progress_typeck_results else {
328+ // If we don't have any typeck results we're outside
329+ // of a body, so we won't be able to get better info
330+ // here.
331+ return self . bad_inference_failure_err ( span, arg_data, error_code) ;
332+ } ;
333+ let typeck_results = typeck_results. borrow ( ) ;
334+ let typeck_results = & typeck_results;
335+
336+ let mut local_visitor = FindInferSourceVisitor :: new ( & self , typeck_results, arg) ;
305337 if let Some ( body_id) = body_id {
306338 let expr = self . tcx . hir ( ) . expect_expr ( body_id. hir_id ) ;
307339 debug ! ( ?expr) ;
308340 local_visitor. visit_expr ( expr) ;
309341 }
310342
311343 let Some ( InferSource { span, kind } ) = local_visitor. infer_source else {
312- let error_code = error_code. into ( ) ;
313- let mut err = self . tcx . sess . struct_span_err_with_code (
314- span,
315- & format ! ( "type annotations needed" ) ,
316- error_code,
317- ) ;
318- err. span_label (
319- span,
320- arg_data. cannot_infer_msg ( ) ,
321- ) ;
322- return err;
344+ return self . bad_inference_failure_err ( span, arg_data, error_code)
323345 } ;
324346
325347 let error_code = error_code. into ( ) ;
@@ -394,8 +416,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
394416 ) ;
395417 }
396418 InferSourceKind :: FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
397- let typeck_results = self . in_progress_typeck_results . unwrap ( ) ;
398- let typeck_results = typeck_results. borrow ( ) ;
399419 let printer = fmt_printer ( self , Namespace :: ValueNS ) ;
400420 let def_path = printer. print_def_path ( def_id, substs) . unwrap ( ) . into_buffer ( ) ;
401421
@@ -548,6 +568,8 @@ struct InsertableGenericArgs<'tcx> {
548568/// For details on how we rank spots, see [Self::source_cost]
549569struct FindInferSourceVisitor < ' a , ' tcx > {
550570 infcx : & ' a InferCtxt < ' a , ' tcx > ,
571+ typeck_results : & ' a TypeckResults < ' tcx > ,
572+
551573 target : GenericArg < ' tcx > ,
552574
553575 attempt : usize ,
@@ -556,9 +578,15 @@ struct FindInferSourceVisitor<'a, 'tcx> {
556578}
557579
558580impl < ' a , ' tcx > FindInferSourceVisitor < ' a , ' tcx > {
559- fn new ( infcx : & ' a InferCtxt < ' a , ' tcx > , target : GenericArg < ' tcx > ) -> Self {
581+ fn new (
582+ infcx : & ' a InferCtxt < ' a , ' tcx > ,
583+ typeck_results : & ' a TypeckResults < ' tcx > ,
584+ target : GenericArg < ' tcx > ,
585+ ) -> Self {
560586 FindInferSourceVisitor {
561587 infcx,
588+ typeck_results,
589+
562590 target,
563591
564592 attempt : 0 ,
@@ -603,7 +631,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
603631 variant_cost + generic_args. iter ( ) . map ( |& arg| arg_cost ( arg) ) . sum :: < usize > ( )
604632 }
605633 InferSourceKind :: FullyQualifiedMethodCall { substs, .. } => {
606- // FIXME: We should also consider the cost of lifetimes and constants here.
607634 20 + substs. iter ( ) . map ( |arg| arg_cost ( arg) ) . sum :: < usize > ( )
608635 }
609636 InferSourceKind :: ClosureReturn { ty, should_wrap_expr, .. } => {
@@ -625,7 +652,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
625652 }
626653
627654 fn opt_node_type ( & self , hir_id : HirId ) -> Option < Ty < ' tcx > > {
628- let ty = self . infcx . in_progress_typeck_results ? . borrow ( ) . node_type_opt ( hir_id) ;
655+ let ty = self . typeck_results . node_type_opt ( hir_id) ;
629656 self . infcx . resolve_vars_if_possible ( ty)
630657 }
631658
@@ -698,10 +725,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
698725 expr : & ' tcx hir:: Expr < ' tcx > ,
699726 ) -> Box < dyn Iterator < Item = InsertableGenericArgs < ' tcx > > + ' a > {
700727 let tcx = self . infcx . tcx ;
701- let typeck_results = self . infcx . in_progress_typeck_results . unwrap ( ) . borrow ( ) ;
702728 match expr. kind {
703729 hir:: ExprKind :: Path ( ref path) => {
704- if let Some ( substs) = typeck_results. node_substs_opt ( expr. hir_id ) {
730+ if let Some ( substs) = self . typeck_results . node_substs_opt ( expr. hir_id ) {
705731 return self . path_inferred_subst_iter ( expr. hir_id , substs, path) ;
706732 }
707733 }
@@ -713,13 +739,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
713739 }
714740 }
715741 hir:: ExprKind :: MethodCall ( segment, _, _) => {
716- if let Some ( def_id) = typeck_results. type_dependent_def_id ( expr. hir_id ) {
742+ if let Some ( def_id) = self . typeck_results . type_dependent_def_id ( expr. hir_id ) {
717743 let generics = tcx. generics_of ( def_id) ;
718744 let insertable: Option < _ > = try {
719745 if generics. has_impl_trait ( ) {
720746 None ?
721747 }
722- let substs = typeck_results. node_substs_opt ( expr. hir_id ) ?;
748+ let substs = self . typeck_results . node_substs_opt ( expr. hir_id ) ?;
723749 let span = tcx. hir ( ) . span ( segment. hir_id ?) ;
724750 let insert_span = segment. ident . span . shrink_to_hi ( ) . with_hi ( span. hi ( ) ) ;
725751 InsertableGenericArgs {
@@ -793,13 +819,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
793819 qpath : & ' tcx hir:: QPath < ' tcx > ,
794820 ) -> Box < dyn Iterator < Item = InsertableGenericArgs < ' tcx > > + ' a > {
795821 let tcx = self . infcx . tcx ;
796- let typeck_results = self . infcx . in_progress_typeck_results . unwrap ( ) . borrow ( ) ;
797822 match qpath {
798823 hir:: QPath :: Resolved ( _self_ty, path) => {
799824 Box :: new ( self . resolved_path_inferred_subst_iter ( path, substs) )
800825 }
801826 hir:: QPath :: TypeRelative ( ty, segment) => {
802- let Some ( def_id) = typeck_results. type_dependent_def_id ( hir_id) else {
827+ let Some ( def_id) = self . typeck_results . type_dependent_def_id ( hir_id) else {
803828 return Box :: new ( iter:: empty ( ) ) ;
804829 } ;
805830
@@ -996,10 +1021,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
9961021 . any ( |generics| generics. has_impl_trait ( ) )
9971022 } ;
9981023 if let ExprKind :: MethodCall ( path, args, span) = expr. kind
999- && let Some ( typeck_results) = self . infcx . in_progress_typeck_results
1000- && let Some ( substs) = typeck_results. borrow ( ) . node_substs_opt ( expr. hir_id )
1024+ && let Some ( substs) = self . typeck_results . node_substs_opt ( expr. hir_id )
10011025 && substs. iter ( ) . any ( |arg| self . generic_arg_contains_target ( arg) )
1002- && let Some ( def_id) = typeck_results . borrow ( ) . type_dependent_def_id ( expr. hir_id )
1026+ && let Some ( def_id) = self . typeck_results . type_dependent_def_id ( expr. hir_id )
10031027 && self . infcx . tcx . trait_of_item ( def_id) . is_some ( )
10041028 && !has_impl_trait ( def_id)
10051029 {
0 commit comments