@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMut
12
12
use rustc_middle:: ty:: print:: { FmtPrinter , PrettyPrinter , Print , Printer } ;
13
13
use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , Subst , SubstsRef } ;
14
14
use rustc_middle:: ty:: { self , DefIdTree , GenericParamDefKind , InferConst } ;
15
- use rustc_middle:: ty:: { Ty , TyCtxt } ;
15
+ use rustc_middle:: ty:: { Ty , TyCtxt , TypeckResults } ;
16
16
use rustc_span:: symbol:: { kw, Ident } ;
17
17
use rustc_span:: { BytePos , Span } ;
18
18
use std:: borrow:: Cow ;
@@ -272,7 +272,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
272
272
parent : None ,
273
273
}
274
274
} 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.
276
281
let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , Namespace :: ValueNS ) ;
277
282
if let Some ( highlight) = highlight {
278
283
printer. region_highlight_mode = highlight;
@@ -289,6 +294,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
289
294
}
290
295
}
291
296
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
+
292
315
pub fn emit_inference_failure_err (
293
316
& self ,
294
317
body_id : Option < hir:: BodyId > ,
@@ -301,25 +324,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
301
324
let arg = self . resolve_vars_if_possible ( arg) ;
302
325
let arg_data = self . extract_inference_diagnostics_data ( arg, None ) ;
303
326
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) ;
305
337
if let Some ( body_id) = body_id {
306
338
let expr = self . tcx . hir ( ) . expect_expr ( body_id. hir_id ) ;
307
339
debug ! ( ?expr) ;
308
340
local_visitor. visit_expr ( expr) ;
309
341
}
310
342
311
343
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)
323
345
} ;
324
346
325
347
let error_code = error_code. into ( ) ;
@@ -394,8 +416,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
394
416
) ;
395
417
}
396
418
InferSourceKind :: FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
397
- let typeck_results = self . in_progress_typeck_results . unwrap ( ) ;
398
- let typeck_results = typeck_results. borrow ( ) ;
399
419
let printer = fmt_printer ( self , Namespace :: ValueNS ) ;
400
420
let def_path = printer. print_def_path ( def_id, substs) . unwrap ( ) . into_buffer ( ) ;
401
421
@@ -548,6 +568,8 @@ struct InsertableGenericArgs<'tcx> {
548
568
/// For details on how we rank spots, see [Self::source_cost]
549
569
struct FindInferSourceVisitor < ' a , ' tcx > {
550
570
infcx : & ' a InferCtxt < ' a , ' tcx > ,
571
+ typeck_results : & ' a TypeckResults < ' tcx > ,
572
+
551
573
target : GenericArg < ' tcx > ,
552
574
553
575
attempt : usize ,
@@ -556,9 +578,15 @@ struct FindInferSourceVisitor<'a, 'tcx> {
556
578
}
557
579
558
580
impl < ' 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 {
560
586
FindInferSourceVisitor {
561
587
infcx,
588
+ typeck_results,
589
+
562
590
target,
563
591
564
592
attempt : 0 ,
@@ -603,7 +631,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
603
631
variant_cost + generic_args. iter ( ) . map ( |& arg| arg_cost ( arg) ) . sum :: < usize > ( )
604
632
}
605
633
InferSourceKind :: FullyQualifiedMethodCall { substs, .. } => {
606
- // FIXME: We should also consider the cost of lifetimes and constants here.
607
634
20 + substs. iter ( ) . map ( |arg| arg_cost ( arg) ) . sum :: < usize > ( )
608
635
}
609
636
InferSourceKind :: ClosureReturn { ty, should_wrap_expr, .. } => {
@@ -625,7 +652,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
625
652
}
626
653
627
654
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) ;
629
656
self . infcx . resolve_vars_if_possible ( ty)
630
657
}
631
658
@@ -698,10 +725,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
698
725
expr : & ' tcx hir:: Expr < ' tcx > ,
699
726
) -> Box < dyn Iterator < Item = InsertableGenericArgs < ' tcx > > + ' a > {
700
727
let tcx = self . infcx . tcx ;
701
- let typeck_results = self . infcx . in_progress_typeck_results . unwrap ( ) . borrow ( ) ;
702
728
match expr. kind {
703
729
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 ) {
705
731
return self . path_inferred_subst_iter ( expr. hir_id , substs, path) ;
706
732
}
707
733
}
@@ -713,13 +739,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
713
739
}
714
740
}
715
741
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 ) {
717
743
let generics = tcx. generics_of ( def_id) ;
718
744
let insertable: Option < _ > = try {
719
745
if generics. has_impl_trait ( ) {
720
746
None ?
721
747
}
722
- let substs = typeck_results. node_substs_opt ( expr. hir_id ) ?;
748
+ let substs = self . typeck_results . node_substs_opt ( expr. hir_id ) ?;
723
749
let span = tcx. hir ( ) . span ( segment. hir_id ?) ;
724
750
let insert_span = segment. ident . span . shrink_to_hi ( ) . with_hi ( span. hi ( ) ) ;
725
751
InsertableGenericArgs {
@@ -793,13 +819,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
793
819
qpath : & ' tcx hir:: QPath < ' tcx > ,
794
820
) -> Box < dyn Iterator < Item = InsertableGenericArgs < ' tcx > > + ' a > {
795
821
let tcx = self . infcx . tcx ;
796
- let typeck_results = self . infcx . in_progress_typeck_results . unwrap ( ) . borrow ( ) ;
797
822
match qpath {
798
823
hir:: QPath :: Resolved ( _self_ty, path) => {
799
824
Box :: new ( self . resolved_path_inferred_subst_iter ( path, substs) )
800
825
}
801
826
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 {
803
828
return Box :: new ( iter:: empty ( ) ) ;
804
829
} ;
805
830
@@ -996,10 +1021,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
996
1021
. any ( |generics| generics. has_impl_trait ( ) )
997
1022
} ;
998
1023
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 )
1001
1025
&& 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 )
1003
1027
&& self . infcx . tcx . trait_of_item ( def_id) . is_some ( )
1004
1028
&& !has_impl_trait ( def_id)
1005
1029
{
0 commit comments