@@ -8,6 +8,7 @@ use rustc_data_structures::unord::ExtendUnord;
8
8
use rustc_errors:: ErrorGuaranteed ;
9
9
use rustc_hir:: intravisit:: { self , InferKind , Visitor } ;
10
10
use rustc_hir:: { self as hir, AmbigArg , HirId } ;
11
+ use rustc_infer:: traits:: solve:: Goal ;
11
12
use rustc_middle:: span_bug;
12
13
use rustc_middle:: traits:: ObligationCause ;
13
14
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , PointerCoercion } ;
@@ -730,8 +731,36 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
730
731
T : TypeFoldable < TyCtxt < ' tcx > > ,
731
732
{
732
733
let value = self . fcx . resolve_vars_if_possible ( value) ;
733
- let value =
734
- value. fold_with ( & mut Resolver :: new ( self . fcx , span, self . body , should_normalize) ) ;
734
+ let mut goals = vec ! [ ] ;
735
+ let value = value. fold_with ( & mut Resolver :: new (
736
+ self . fcx ,
737
+ span,
738
+ self . body ,
739
+ should_normalize,
740
+ & mut goals,
741
+ ) ) ;
742
+
743
+ // Ensure that we resolve goals we get from normalizing coroutine interiors,
744
+ // but we shouldn't expect those goals to need normalizing (or else we'd get
745
+ // into a somewhat awkward fixpoint situation, and we don't need it anyways).
746
+ let mut unexpected_goals = vec ! [ ] ;
747
+ self . typeck_results . coroutine_stalled_predicates . extend (
748
+ goals
749
+ . into_iter ( )
750
+ . map ( |pred| {
751
+ self . fcx . resolve_vars_if_possible ( pred) . fold_with ( & mut Resolver :: new (
752
+ self . fcx ,
753
+ span,
754
+ self . body ,
755
+ false ,
756
+ & mut unexpected_goals,
757
+ ) )
758
+ } )
759
+ // FIXME: throwing away the param-env :(
760
+ . map ( |goal| ( goal. predicate , self . fcx . misc ( span. to_span ( self . fcx . tcx ) ) ) ) ,
761
+ ) ;
762
+ assert_eq ! ( unexpected_goals, vec![ ] ) ;
763
+
735
764
assert ! ( !value. has_infer( ) ) ;
736
765
737
766
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
@@ -768,6 +797,7 @@ struct Resolver<'cx, 'tcx> {
768
797
/// Whether we should normalize using the new solver, disabled
769
798
/// both when using the old solver and when resolving predicates.
770
799
should_normalize : bool ,
800
+ nested_goals : & ' cx mut Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
771
801
}
772
802
773
803
impl < ' cx , ' tcx > Resolver < ' cx , ' tcx > {
@@ -776,8 +806,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
776
806
span : & ' cx dyn Locatable ,
777
807
body : & ' tcx hir:: Body < ' tcx > ,
778
808
should_normalize : bool ,
809
+ nested_goals : & ' cx mut Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
779
810
) -> Resolver < ' cx , ' tcx > {
780
- Resolver { fcx, span, body, should_normalize }
811
+ Resolver { fcx, span, body, nested_goals , should_normalize }
781
812
}
782
813
783
814
fn report_error ( & self , p : impl Into < ty:: GenericArg < ' tcx > > ) -> ErrorGuaranteed {
@@ -814,12 +845,18 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
814
845
let cause = ObligationCause :: misc ( self . span . to_span ( tcx) , body_id) ;
815
846
let at = self . fcx . at ( & cause, self . fcx . param_env ) ;
816
847
let universes = vec ! [ None ; outer_exclusive_binder( value) . as_usize( ) ] ;
817
- solve:: deeply_normalize_with_skipped_universes ( at, value, universes) . unwrap_or_else (
818
- |errors| {
848
+ match solve:: deeply_normalize_with_skipped_universes_and_ambiguous_goals (
849
+ at, value, universes,
850
+ ) {
851
+ Ok ( ( value, goals) ) => {
852
+ self . nested_goals . extend ( goals) ;
853
+ value
854
+ }
855
+ Err ( errors) => {
819
856
let guar = self . fcx . err_ctxt ( ) . report_fulfillment_errors ( errors) ;
820
857
new_err ( tcx, guar)
821
- } ,
822
- )
858
+ }
859
+ }
823
860
} else {
824
861
value
825
862
} ;
0 commit comments