about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-01-26 21:47:03 -0800
committerMichael Goulet <michael@errs.io>2022-02-19 10:59:00 -0800
commit773fa7adbca745e86c59503e17d9d4c5b7dcc275 (patch)
treeaea81d57653dd43f24651d053be522fb13a43903 /compiler/rustc_trait_selection/src
parente08d5693609a659e45025b8ea4dbd9efa342fa68 (diff)
downloadrust-773fa7adbca745e86c59503e17d9d4c5b7dcc275.tar.gz
rust-773fa7adbca745e86c59503e17d9d4c5b7dcc275.zip
Consolidate normalization in confirm_poly_trait_refs
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs103
1 files changed, 30 insertions, 73 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 84bc7cdff28..2579e4b3174 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -553,23 +553,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         )
         .map_bound(|(trait_ref, _)| trait_ref);
 
-        let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
-            normalize_with_depth(
-                self,
-                obligation.param_env,
-                obligation.cause.clone(),
-                obligation.recursion_depth + 1,
-                trait_ref,
-            )
-        });
-
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation.predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
-        Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested: obligations })
+        let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
+        Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
     }
 
     fn confirm_trait_alias_candidate(
@@ -616,26 +601,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
 
         let trait_ref = self.generator_trait_ref_unnormalized(obligation, substs);
-        let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
-            normalize_with_depth(
-                self,
-                obligation.param_env,
-                obligation.cause.clone(),
-                obligation.recursion_depth + 1,
-                trait_ref,
-            )
-        });
 
-        debug!(?trait_ref, ?obligations, "generator candidate obligations");
-
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation.predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
+        let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
+        debug!(?trait_ref, ?nested, "generator candidate obligations");
 
-        Ok(ImplSourceGeneratorData { generator_def_id, substs, nested: obligations })
+        Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -657,44 +627,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => bug!("closure candidate for non-closure {:?}", obligation),
         };
 
-        let obligation_predicate = obligation.predicate;
-        let Normalized { value: obligation_predicate, mut obligations } =
-            ensure_sufficient_stack(|| {
-                normalize_with_depth(
-                    self,
-                    obligation.param_env,
-                    obligation.cause.clone(),
-                    obligation.recursion_depth + 1,
-                    obligation_predicate,
-                )
-            });
-
         let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
-        let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
-            ensure_sufficient_stack(|| {
-                normalize_with_depth(
-                    self,
-                    obligation.param_env,
-                    obligation.cause.clone(),
-                    obligation.recursion_depth + 1,
-                    trait_ref,
-                )
-            });
+        let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
 
-        debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
-
-        obligations.extend(trait_ref_obligations);
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation_predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
+        debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
 
         // FIXME: Chalk
 
         if !self.tcx().sess.opts.debugging_opts.chalk {
-            obligations.push(Obligation::new(
+            nested.push(Obligation::new(
                 obligation.cause.clone(),
                 obligation.param_env,
                 ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
@@ -702,7 +643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ));
         }
 
-        Ok(ImplSourceClosureData { closure_def_id, substs, nested: obligations })
+        Ok(ImplSourceClosureData { closure_def_id, substs, nested })
     }
 
     /// In the case of closure types and fn pointers,
@@ -733,15 +674,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     #[instrument(skip(self), level = "trace")]
     fn confirm_poly_trait_refs(
         &mut self,
-        obligation_cause: ObligationCause<'tcx>,
-        obligation_param_env: ty::ParamEnv<'tcx>,
-        obligation_trait_ref: ty::PolyTraitRef<'tcx>,
+        obligation: &TraitObligation<'tcx>,
         expected_trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+        let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
+        // Normalize the obligation and expected trait refs together, because why not
+        let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
+            ensure_sufficient_stack(|| {
+                self.infcx.commit_unconditionally(|_| {
+                    normalize_with_depth(
+                        self,
+                        obligation.param_env,
+                        obligation.cause.clone(),
+                        obligation.recursion_depth + 1,
+                        (obligation_trait_ref, expected_trait_ref),
+                    )
+                })
+            });
+
         self.infcx
-            .at(&obligation_cause, obligation_param_env)
+            .at(&obligation.cause, obligation.param_env)
             .sup(obligation_trait_ref, expected_trait_ref)
-            .map(|InferOk { obligations, .. }| obligations)
+            .map(|InferOk { mut obligations, .. }| {
+                obligations.extend(nested);
+                obligations
+            })
             .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
     }