no leak_check -> commit_unconditionally is noop
This commit is contained in:
parent
748cb1f01d
commit
c12f5fc006
2 changed files with 163 additions and 182 deletions
|
@ -158,67 +158,65 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
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(
|
||||||
|
@ -314,19 +312,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
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,
|
||||||
|
@ -355,19 +350,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
// 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,
|
)
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,25 +607,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
) -> 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(
|
||||||
|
@ -730,15 +721,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// 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
|
||||||
|
@ -1114,32 +1103,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
@ -1190,34 +1177,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// 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
|
||||||
|
|
|
@ -2081,30 +2081,28 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue