@@ -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};
@@ -763,7 +764,32 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
763
764
T: TypeFoldable<TyCtxt<'tcx>>,
764
765
{
765
766
let value = self.fcx.resolve_vars_if_possible(value);
766
- let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body, true));
767
+
768
+ let mut goals = vec![];
769
+ let value =
770
+ value.fold_with(&mut Resolver::new(self.fcx, span, self.body, true, &mut goals));
771
+
772
+ // Ensure that we resolve goals we get from normalizing coroutine interiors,
773
+ // but we shouldn't expect those goals to need normalizing (or else we'd get
774
+ // into a somewhat awkward fixpoint situation, and we don't need it anyways).
775
+ let mut unexpected_goals = vec![];
776
+ self.typeck_results.coroutine_stalled_predicates.extend(
777
+ goals
778
+ .into_iter()
779
+ .map(|pred| {
780
+ self.fcx.resolve_vars_if_possible(pred).fold_with(&mut Resolver::new(
781
+ self.fcx,
782
+ span,
783
+ self.body,
784
+ false,
785
+ &mut unexpected_goals,
786
+ ))
787
+ })
788
+ // FIXME: throwing away the param-env :(
789
+ .map(|goal| (goal.predicate, self.fcx.misc(span.to_span(self.fcx.tcx)))),
790
+ );
791
+ assert_eq!(unexpected_goals, vec![]);
792
+
767
793
assert!(!value.has_infer());
768
794
769
795
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
@@ -781,7 +807,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
781
807
T: TypeFoldable<TyCtxt<'tcx>>,
782
808
{
783
809
let value = self.fcx.resolve_vars_if_possible(value);
784
- let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body, false));
810
+
811
+ let mut goals = vec![];
812
+ let value =
813
+ value.fold_with(&mut Resolver::new(self.fcx, span, self.body, false, &mut goals));
814
+ assert_eq!(goals, vec![]);
815
+
785
816
assert!(!value.has_infer());
786
817
787
818
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
@@ -818,6 +849,7 @@ struct Resolver<'cx, 'tcx> {
818
849
/// Whether we should normalize using the new solver, disabled
819
850
/// both when using the old solver and when resolving predicates.
820
851
should_normalize: bool,
852
+ nested_goals: &'cx mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
821
853
}
822
854
823
855
impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
@@ -826,8 +858,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
826
858
span: &'cx dyn Locatable,
827
859
body: &'tcx hir::Body<'tcx>,
828
860
should_normalize: bool,
861
+ nested_goals: &'cx mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
829
862
) -> Resolver<'cx, 'tcx> {
830
- Resolver { fcx, span, body, should_normalize }
863
+ Resolver { fcx, span, body, nested_goals, should_normalize }
831
864
}
832
865
833
866
fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
@@ -864,12 +897,18 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
864
897
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
865
898
let at = self.fcx.at(&cause, self.fcx.param_env);
866
899
let universes = vec![None; outer_exclusive_binder(value).as_usize()];
867
- solve::deeply_normalize_with_skipped_universes(at, value, universes).unwrap_or_else(
868
- |errors| {
900
+ match solve::deeply_normalize_with_skipped_universes_and_ambiguous_goals(
901
+ at, value, universes,
902
+ ) {
903
+ Ok((value, goals)) => {
904
+ self.nested_goals.extend(goals);
905
+ value
906
+ }
907
+ Err(errors) => {
869
908
let guar = self.fcx.err_ctxt().report_fulfillment_errors(errors);
870
909
new_err(tcx, guar)
871
- },
872
- )
910
+ }
911
+ }
873
912
} else {
874
913
value
875
914
};
0 commit comments