Auto merge of #99509 - lcnr:commit_unconditionally, r=jackh726

remove `commit_unconditionally`

`commit_unconditionally` is a noop unless we somehow inspect the current state of our snapshot. The only thing which does that is the leak check which was only used in one place where `commit_if_ok` is probably at least as, or even more, correct.

r? rust-lang/types
This commit is contained in:
bors 2022-08-03 01:55:20 +00:00
commit b759b2efad
4 changed files with 164 additions and 195 deletions

View File

@ -840,18 +840,6 @@ fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
self.inner.borrow_mut().commit(undo_snapshot); self.inner.borrow_mut().commit(undo_snapshot);
} }
/// Executes `f` and commit the bindings.
#[instrument(skip(self, f), level = "debug")]
pub fn commit_unconditionally<R, F>(&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(_)`. /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`.
#[instrument(skip(self, f), level = "debug")] #[instrument(skip(self, f), level = "debug")]
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>

View File

@ -144,67 +144,65 @@ fn confirm_projection_candidate(
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
idx: usize, idx: usize,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
self.infcx.commit_unconditionally(|_| { let tcx = self.tcx();
let tcx = self.tcx();
let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
let placeholder_trait_predicate = let placeholder_trait_predicate =
self.infcx().replace_bound_vars_with_placeholders(trait_predicate).trait_ref; self.infcx().replace_bound_vars_with_placeholders(trait_predicate).trait_ref;
let placeholder_self_ty = placeholder_trait_predicate.self_ty(); let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() { let (def_id, substs) = match *placeholder_self_ty.kind() {
ty::Projection(proj) => (proj.item_def_id, proj.substs), ty::Projection(proj) => (proj.item_def_id, proj.substs),
ty::Opaque(def_id, substs) => (def_id, substs), ty::Opaque(def_id, substs) => (def_id, substs),
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
}; };
let candidate_predicate = let candidate_predicate =
tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
let candidate = candidate_predicate let candidate = candidate_predicate
.to_opt_poly_trait_pred() .to_opt_poly_trait_pred()
.expect("projection candidate is not a trait predicate") .expect("projection candidate is not a trait predicate")
.map_bound(|t| t.trait_ref); .map_bound(|t| t.trait_ref);
let mut obligations = Vec::new(); let mut obligations = Vec::new();
let candidate = normalize_with_depth_to( let candidate = normalize_with_depth_to(
self, self,
obligation.param_env, obligation.param_env,
obligation.cause.clone(), obligation.cause.clone(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
candidate, candidate,
&mut obligations, &mut obligations,
); );
obligations.extend(self.infcx.commit_if_ok(|_| { obligations.extend(self.infcx.commit_if_ok(|_| {
self.infcx self.infcx
.at(&obligation.cause, obligation.param_env) .at(&obligation.cause, obligation.param_env)
.sup(placeholder_trait_predicate, candidate) .sup(placeholder_trait_predicate, candidate)
.map(|InferOk { obligations, .. }| obligations) .map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented) .map_err(|_| Unimplemented)
})?); })?);
if let ty::Projection(..) = placeholder_self_ty.kind() { if let ty::Projection(..) = placeholder_self_ty.kind() {
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates; let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
debug!(?predicates, "projection predicates"); debug!(?predicates, "projection predicates");
for predicate in predicates { for predicate in predicates {
let normalized = normalize_with_depth_to( let normalized = normalize_with_depth_to(
self, self,
obligation.param_env, obligation.param_env,
obligation.cause.clone(), obligation.cause.clone(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
predicate, predicate,
&mut obligations, &mut obligations,
); );
obligations.push(Obligation::with_depth( obligations.push(Obligation::with_depth(
obligation.cause.clone(), obligation.cause.clone(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
obligation.param_env, obligation.param_env,
normalized, normalized,
)); ));
}
} }
}
Ok(obligations) Ok(obligations)
})
} }
fn confirm_param_candidate( fn confirm_param_candidate(
@ -347,19 +345,16 @@ fn vtable_auto_impl(
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
let cause = obligation.derived_cause(BuiltinDerivedObligation); let cause = obligation.derived_cause(BuiltinDerivedObligation);
let trait_obligations: Vec<PredicateObligation<'_>> = let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
self.infcx.commit_unconditionally(|_| { let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref);
let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations(
let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref); &cause,
self.impl_or_trait_obligations( obligation.recursion_depth + 1,
&cause, obligation.param_env,
obligation.recursion_depth + 1, trait_def_id,
obligation.param_env, &trait_ref.substs,
trait_def_id, obligation.predicate,
&trait_ref.substs, );
obligation.predicate,
)
});
let mut obligations = self.collect_predicates_for_types( let mut obligations = self.collect_predicates_for_types(
obligation.param_env, obligation.param_env,
@ -388,19 +383,17 @@ fn confirm_impl_candidate(
// First, create the substitutions by matching the impl again, // First, create the substitutions by matching the impl again,
// this time not in a probe. // this time not in a probe.
self.infcx.commit_unconditionally(|_| { let substs = self.rematch_impl(impl_def_id, obligation);
let substs = self.rematch_impl(impl_def_id, obligation); debug!(?substs, "impl substs");
debug!(?substs, "impl substs"); ensure_sufficient_stack(|| {
ensure_sufficient_stack(|| { self.vtable_impl(
self.vtable_impl( impl_def_id,
impl_def_id, substs,
substs, &obligation.cause,
&obligation.cause, obligation.recursion_depth + 1,
obligation.recursion_depth + 1, obligation.param_env,
obligation.param_env, obligation.predicate,
obligation.predicate, )
)
})
}) })
} }
@ -647,25 +640,23 @@ fn confirm_trait_alias_candidate(
) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> { ) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> {
debug!(?obligation, ?alias_def_id, "confirm_trait_alias_candidate"); 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 predicate = self.infcx().replace_bound_vars_with_placeholders(obligation.predicate); let trait_ref = predicate.trait_ref;
let trait_ref = predicate.trait_ref; let trait_def_id = trait_ref.def_id;
let trait_def_id = trait_ref.def_id; let substs = trait_ref.substs;
let substs = trait_ref.substs;
let trait_obligations = self.impl_or_trait_obligations( let trait_obligations = self.impl_or_trait_obligations(
&obligation.cause, &obligation.cause,
obligation.recursion_depth, obligation.recursion_depth,
obligation.param_env, obligation.param_env,
trait_def_id, trait_def_id,
&substs, &substs,
obligation.predicate, 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( fn confirm_generator_candidate(
@ -763,15 +754,13 @@ fn confirm_poly_trait_refs(
// Normalize the obligation and expected trait refs together, because why not // Normalize the obligation and expected trait refs together, because why not
let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } = let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
self.infcx.commit_unconditionally(|_| { normalize_with_depth(
normalize_with_depth( self,
self, obligation.param_env,
obligation.param_env, obligation.cause.clone(),
obligation.cause.clone(), obligation.recursion_depth + 1,
obligation.recursion_depth + 1, (obligation_trait_ref, expected_trait_ref),
(obligation_trait_ref, expected_trait_ref), )
)
})
}); });
self.infcx self.infcx
@ -1147,32 +1136,30 @@ fn confirm_const_destruct_candidate(
// first check it like a regular impl candidate. // first check it like a regular impl candidate.
// This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand. // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
if let Some(impl_def_id) = impl_def_id { if let Some(impl_def_id) = impl_def_id {
let obligations = self.infcx.commit_unconditionally(|_| { let mut new_obligation = obligation.clone();
let mut new_obligation = obligation.clone(); new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| {
new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { trait_pred.trait_ref.def_id = drop_trait;
trait_pred.trait_ref.def_id = drop_trait; trait_pred
trait_pred });
}); let substs = self.rematch_impl(impl_def_id, &new_obligation);
let substs = self.rematch_impl(impl_def_id, &new_obligation); debug!(?substs, "impl substs");
debug!(?substs, "impl substs");
let cause = obligation.derived_cause(|derived| { let cause = obligation.derived_cause(|derived| {
ImplDerivedObligation(Box::new(ImplDerivedObligationCause { ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
derived, derived,
impl_def_id, impl_def_id,
span: obligation.cause.span, span: obligation.cause.span,
})) }))
}); });
ensure_sufficient_stack(|| { let obligations = ensure_sufficient_stack(|| {
self.vtable_impl( self.vtable_impl(
impl_def_id, impl_def_id,
substs, substs,
&cause, &cause,
new_obligation.recursion_depth + 1, new_obligation.recursion_depth + 1,
new_obligation.param_env, new_obligation.param_env,
obligation.predicate, obligation.predicate,
) )
})
}); });
nested.extend(obligations.nested); 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 // If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable // with a fresh infer variable
ty::Projection(..) => { ty::Projection(..) => {
self.infcx.commit_unconditionally(|_| { let predicate = normalize_with_depth_to(
let predicate = normalize_with_depth_to( self,
self, obligation.param_env,
obligation.param_env, cause.clone(),
cause.clone(), obligation.recursion_depth + 1,
obligation.recursion_depth + 1, self_ty
self_ty .rebind(ty::TraitPredicate {
.rebind(ty::TraitPredicate { trait_ref: ty::TraitRef {
trait_ref: ty::TraitRef { def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
def_id: self substs: self.tcx().mk_substs_trait(nested_ty, &[]),
.tcx() },
.require_lang_item(LangItem::Destruct, None), constness: ty::BoundConstness::ConstIfConst,
substs: self.tcx().mk_substs_trait(nested_ty, &[]), polarity: ty::ImplPolarity::Positive,
}, })
constness: ty::BoundConstness::ConstIfConst, .to_predicate(tcx),
polarity: ty::ImplPolarity::Positive, &mut nested,
}) );
.to_predicate(tcx),
&mut nested,
);
nested.push(Obligation::with_depth( nested.push(Obligation::with_depth(
cause.clone(), cause.clone(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
obligation.param_env, obligation.param_env,
predicate, predicate,
)); ));
});
} }
// If we have any other type (e.g. an ADT), just register a nested obligation // If we have any other type (e.g. an ADT), just register a nested obligation

View File

@ -2084,30 +2084,28 @@ fn collect_predicates_for_types(
.flat_map(|ty| { .flat_map(|ty| {
let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*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 placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); let Normalized { value: normalized_ty, mut obligations } =
let Normalized { value: normalized_ty, mut obligations } = ensure_sufficient_stack(|| {
ensure_sufficient_stack(|| { project::normalize_with_depth(
project::normalize_with_depth( self,
self, param_env,
param_env, cause.clone(),
cause.clone(), recursion_depth,
recursion_depth, placeholder_ty,
placeholder_ty, )
) });
}); let placeholder_obligation = predicate_for_trait_def(
let placeholder_obligation = predicate_for_trait_def( self.tcx(),
self.tcx(), param_env,
param_env, cause.clone(),
cause.clone(), trait_def_id,
trait_def_id, recursion_depth,
recursion_depth, normalized_ty,
normalized_ty, &[],
&[], );
); obligations.push(placeholder_obligation);
obligations.push(placeholder_obligation); obligations
obligations
})
}) })
.collect() .collect()
} }

View File

@ -737,7 +737,7 @@ fn coerce_from_safe_fn<F, G>(
F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>, F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>, G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
{ {
self.commit_unconditionally(|snapshot| { self.commit_if_ok(|snapshot| {
let result = if let ty::FnPtr(fn_ty_b) = b.kind() let result = if let ty::FnPtr(fn_ty_b) = b.kind()
&& let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
(fn_ty_a.unsafety(), fn_ty_b.unsafety()) (fn_ty_a.unsafety(), fn_ty_b.unsafety())