diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 1546c9ccff2..d7d1b5fa218 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -840,18 +840,6 @@ fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) { self.inner.borrow_mut().commit(undo_snapshot); } - /// Executes `f` and commit the bindings. - #[instrument(skip(self, f), level = "debug")] - pub fn commit_unconditionally(&self, f: F) -> R - where - F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, - { - let snapshot = self.start_snapshot(); - let r = f(&snapshot); - self.commit_from(snapshot); - r - } - /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`. #[instrument(skip(self, f), level = "debug")] pub fn commit_if_ok(&self, f: F) -> Result diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 672c9b7b088..2a1099fc82a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -144,67 +144,65 @@ fn confirm_projection_candidate( obligation: &TraitObligation<'tcx>, idx: usize, ) -> Result>, SelectionError<'tcx>> { - self.infcx.commit_unconditionally(|_| { - let tcx = self.tcx(); + let tcx = self.tcx(); - let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); - let placeholder_trait_predicate = - self.infcx().replace_bound_vars_with_placeholders(trait_predicate).trait_ref; - let placeholder_self_ty = placeholder_trait_predicate.self_ty(); - let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); - let (def_id, substs) = match *placeholder_self_ty.kind() { - ty::Projection(proj) => (proj.item_def_id, proj.substs), - ty::Opaque(def_id, substs) => (def_id, substs), - _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), - }; + let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); + let placeholder_trait_predicate = + self.infcx().replace_bound_vars_with_placeholders(trait_predicate).trait_ref; + let placeholder_self_ty = placeholder_trait_predicate.self_ty(); + let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); + let (def_id, substs) = match *placeholder_self_ty.kind() { + ty::Projection(proj) => (proj.item_def_id, proj.substs), + ty::Opaque(def_id, substs) => (def_id, substs), + _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), + }; - let candidate_predicate = - tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); - let candidate = candidate_predicate - .to_opt_poly_trait_pred() - .expect("projection candidate is not a trait predicate") - .map_bound(|t| t.trait_ref); - let mut obligations = Vec::new(); - let candidate = normalize_with_depth_to( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - candidate, - &mut obligations, - ); + let candidate_predicate = + tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); + let candidate = candidate_predicate + .to_opt_poly_trait_pred() + .expect("projection candidate is not a trait predicate") + .map_bound(|t| t.trait_ref); + let mut obligations = Vec::new(); + let candidate = normalize_with_depth_to( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + candidate, + &mut obligations, + ); - obligations.extend(self.infcx.commit_if_ok(|_| { - self.infcx - .at(&obligation.cause, obligation.param_env) - .sup(placeholder_trait_predicate, candidate) - .map(|InferOk { obligations, .. }| obligations) - .map_err(|_| Unimplemented) - })?); + obligations.extend(self.infcx.commit_if_ok(|_| { + self.infcx + .at(&obligation.cause, obligation.param_env) + .sup(placeholder_trait_predicate, candidate) + .map(|InferOk { obligations, .. }| obligations) + .map_err(|_| Unimplemented) + })?); - if let ty::Projection(..) = placeholder_self_ty.kind() { - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates; - debug!(?predicates, "projection predicates"); - for predicate in predicates { - let normalized = normalize_with_depth_to( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - predicate, - &mut obligations, - ); - obligations.push(Obligation::with_depth( - obligation.cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - normalized, - )); - } + if let ty::Projection(..) = placeholder_self_ty.kind() { + let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates; + debug!(?predicates, "projection predicates"); + for predicate in predicates { + let normalized = normalize_with_depth_to( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + predicate, + &mut obligations, + ); + obligations.push(Obligation::with_depth( + obligation.cause.clone(), + obligation.recursion_depth + 1, + obligation.param_env, + normalized, + )); } + } - Ok(obligations) - }) + Ok(obligations) } fn confirm_param_candidate( @@ -347,19 +345,16 @@ fn vtable_auto_impl( ensure_sufficient_stack(|| { let cause = obligation.derived_cause(BuiltinDerivedObligation); - let trait_obligations: Vec> = - self.infcx.commit_unconditionally(|_| { - let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); - let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref); - self.impl_or_trait_obligations( - &cause, - obligation.recursion_depth + 1, - obligation.param_env, - trait_def_id, - &trait_ref.substs, - obligation.predicate, - ) - }); + let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); + let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref); + let trait_obligations: Vec> = self.impl_or_trait_obligations( + &cause, + obligation.recursion_depth + 1, + obligation.param_env, + trait_def_id, + &trait_ref.substs, + obligation.predicate, + ); let mut obligations = self.collect_predicates_for_types( obligation.param_env, @@ -388,19 +383,17 @@ fn confirm_impl_candidate( // First, create the substitutions by matching the impl again, // this time not in a probe. - self.infcx.commit_unconditionally(|_| { - let substs = self.rematch_impl(impl_def_id, obligation); - debug!(?substs, "impl substs"); - ensure_sufficient_stack(|| { - self.vtable_impl( - impl_def_id, - substs, - &obligation.cause, - obligation.recursion_depth + 1, - obligation.param_env, - obligation.predicate, - ) - }) + let substs = self.rematch_impl(impl_def_id, obligation); + debug!(?substs, "impl substs"); + ensure_sufficient_stack(|| { + self.vtable_impl( + impl_def_id, + substs, + &obligation.cause, + obligation.recursion_depth + 1, + obligation.param_env, + obligation.predicate, + ) }) } @@ -647,25 +640,23 @@ fn confirm_trait_alias_candidate( ) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> { debug!(?obligation, ?alias_def_id, "confirm_trait_alias_candidate"); - self.infcx.commit_unconditionally(|_| { - let predicate = self.infcx().replace_bound_vars_with_placeholders(obligation.predicate); - let trait_ref = predicate.trait_ref; - let trait_def_id = trait_ref.def_id; - let substs = trait_ref.substs; + let predicate = self.infcx().replace_bound_vars_with_placeholders(obligation.predicate); + let trait_ref = predicate.trait_ref; + let trait_def_id = trait_ref.def_id; + let substs = trait_ref.substs; - let trait_obligations = self.impl_or_trait_obligations( - &obligation.cause, - obligation.recursion_depth, - obligation.param_env, - trait_def_id, - &substs, - obligation.predicate, - ); + let trait_obligations = self.impl_or_trait_obligations( + &obligation.cause, + obligation.recursion_depth, + obligation.param_env, + trait_def_id, + &substs, + obligation.predicate, + ); - debug!(?trait_def_id, ?trait_obligations, "trait alias obligations"); + debug!(?trait_def_id, ?trait_obligations, "trait alias obligations"); - ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations } - }) + ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations } } fn confirm_generator_candidate( @@ -763,15 +754,13 @@ fn confirm_poly_trait_refs( // 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), - ) - }) + normalize_with_depth( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + (obligation_trait_ref, expected_trait_ref), + ) }); self.infcx @@ -1147,32 +1136,30 @@ fn confirm_const_destruct_candidate( // first check it like a regular impl candidate. // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand. if let Some(impl_def_id) = impl_def_id { - let obligations = self.infcx.commit_unconditionally(|_| { - let mut new_obligation = obligation.clone(); - new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.def_id = drop_trait; - trait_pred - }); - let substs = self.rematch_impl(impl_def_id, &new_obligation); - debug!(?substs, "impl substs"); + let mut new_obligation = obligation.clone(); + new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { + trait_pred.trait_ref.def_id = drop_trait; + trait_pred + }); + let substs = self.rematch_impl(impl_def_id, &new_obligation); + debug!(?substs, "impl substs"); - let cause = obligation.derived_cause(|derived| { - ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_def_id, - span: obligation.cause.span, - })) - }); - ensure_sufficient_stack(|| { - self.vtable_impl( - impl_def_id, - substs, - &cause, - new_obligation.recursion_depth + 1, - new_obligation.param_env, - obligation.predicate, - ) - }) + let cause = obligation.derived_cause(|derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_def_id, + span: obligation.cause.span, + })) + }); + let obligations = ensure_sufficient_stack(|| { + self.vtable_impl( + impl_def_id, + substs, + &cause, + new_obligation.recursion_depth + 1, + new_obligation.param_env, + obligation.predicate, + ) }); nested.extend(obligations.nested); } @@ -1223,34 +1210,30 @@ fn confirm_const_destruct_candidate( // If we have a projection type, make sure to normalize it so we replace it // with a fresh infer variable ty::Projection(..) => { - self.infcx.commit_unconditionally(|_| { - let predicate = normalize_with_depth_to( - self, - obligation.param_env, - cause.clone(), - obligation.recursion_depth + 1, - self_ty - .rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: self - .tcx() - .require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), - }, - constness: ty::BoundConstness::ConstIfConst, - polarity: ty::ImplPolarity::Positive, - }) - .to_predicate(tcx), - &mut nested, - ); + let predicate = normalize_with_depth_to( + self, + obligation.param_env, + cause.clone(), + obligation.recursion_depth + 1, + self_ty + .rebind(ty::TraitPredicate { + trait_ref: ty::TraitRef { + def_id: self.tcx().require_lang_item(LangItem::Destruct, None), + substs: self.tcx().mk_substs_trait(nested_ty, &[]), + }, + constness: ty::BoundConstness::ConstIfConst, + polarity: ty::ImplPolarity::Positive, + }) + .to_predicate(tcx), + &mut nested, + ); - nested.push(Obligation::with_depth( - cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - predicate, - )); - }); + nested.push(Obligation::with_depth( + cause.clone(), + obligation.recursion_depth + 1, + obligation.param_env, + predicate, + )); } // If we have any other type (e.g. an ADT), just register a nested obligation diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9ca23228b98..d7d29005f80 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2084,30 +2084,28 @@ fn collect_predicates_for_types( .flat_map(|ty| { let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/ - self.infcx.commit_unconditionally(|_| { - let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); - let Normalized { value: normalized_ty, mut obligations } = - ensure_sufficient_stack(|| { - project::normalize_with_depth( - self, - param_env, - cause.clone(), - recursion_depth, - placeholder_ty, - ) - }); - let placeholder_obligation = predicate_for_trait_def( - self.tcx(), - param_env, - cause.clone(), - trait_def_id, - recursion_depth, - normalized_ty, - &[], - ); - obligations.push(placeholder_obligation); - obligations - }) + let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); + let Normalized { value: normalized_ty, mut obligations } = + ensure_sufficient_stack(|| { + project::normalize_with_depth( + self, + param_env, + cause.clone(), + recursion_depth, + placeholder_ty, + ) + }); + let placeholder_obligation = predicate_for_trait_def( + self.tcx(), + param_env, + cause.clone(), + trait_def_id, + recursion_depth, + normalized_ty, + &[], + ); + obligations.push(placeholder_obligation); + obligations }) .collect() } diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 639cab98f17..2ed5f569b4f 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -737,7 +737,7 @@ fn coerce_from_safe_fn( F: FnOnce(Ty<'tcx>) -> Vec>, G: FnOnce(Ty<'tcx>) -> Vec>, { - self.commit_unconditionally(|snapshot| { + self.commit_if_ok(|snapshot| { let result = if let ty::FnPtr(fn_ty_b) = b.kind() && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = (fn_ty_a.unsafety(), fn_ty_b.unsafety())