take predicates by value instead of by reference
This commit is contained in:
parent
7f940ef5d9
commit
647ae50ce6
@ -1011,7 +1011,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: &ty::PolySubtypePredicate<'tcx>,
|
||||
predicate: ty::PolySubtypePredicate<'tcx>,
|
||||
) -> Option<InferResult<'tcx, ()>> {
|
||||
// Subtle: it's ok to skip the binder here and resolve because
|
||||
// `shallow_resolve` just ignores anything that is not a type
|
||||
@ -1034,7 +1034,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
Some(self.commit_if_ok(|snapshot| {
|
||||
let (ty::SubtypePredicate { a_is_expected, a, b }, placeholder_map) =
|
||||
self.replace_bound_vars_with_placeholders(predicate);
|
||||
self.replace_bound_vars_with_placeholders(&predicate);
|
||||
|
||||
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
|
||||
|
||||
@ -1047,11 +1047,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn region_outlives_predicate(
|
||||
&self,
|
||||
cause: &traits::ObligationCause<'tcx>,
|
||||
predicate: &ty::PolyRegionOutlivesPredicate<'tcx>,
|
||||
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
|
||||
) -> UnitResult<'tcx> {
|
||||
self.commit_if_ok(|snapshot| {
|
||||
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
|
||||
self.replace_bound_vars_with_placeholders(predicate);
|
||||
self.replace_bound_vars_with_placeholders(&predicate);
|
||||
let origin = SubregionOrigin::from_obligation_cause(cause, || {
|
||||
RelateRegionParamBound(cause.span)
|
||||
});
|
||||
|
@ -223,7 +223,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||
// like `T` and `T::Item`. It may not work as well for things
|
||||
// like `<T as Foo<'a>>::Item`.
|
||||
let c_b = self.param_env.caller_bounds;
|
||||
let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter());
|
||||
let param_bounds =
|
||||
self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter().copied());
|
||||
|
||||
// Next, collect regions we scraped from the well-formedness
|
||||
// constraints in the fn signature. To do that, we walk the list
|
||||
@ -334,10 +335,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||
fn collect_outlives_from_predicate_list(
|
||||
&self,
|
||||
compare_ty: impl Fn(Ty<'tcx>) -> bool,
|
||||
predicates: impl Iterator<Item = impl AsRef<ty::Predicate<'tcx>>>,
|
||||
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
||||
) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
|
||||
predicates
|
||||
.filter_map(|p| p.as_ref().to_opt_type_outlives())
|
||||
.filter_map(|p| p.to_opt_type_outlives())
|
||||
.filter_map(|p| p.no_bound_vars())
|
||||
.filter(move |p| compare_ty(p.0))
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use rustc_span::Span;
|
||||
|
||||
pub fn anonymize_predicate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
pred: &ty::Predicate<'tcx>,
|
||||
pred: ty::Predicate<'tcx>,
|
||||
) -> ty::Predicate<'tcx> {
|
||||
match pred.kind() {
|
||||
&ty::PredicateKind::Trait(ref data, constness) => {
|
||||
@ -66,7 +66,7 @@ impl PredicateSet<'tcx> {
|
||||
Self { tcx, set: Default::default() }
|
||||
}
|
||||
|
||||
fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
|
||||
fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
|
||||
// We have to be careful here because we want
|
||||
//
|
||||
// for<'a> Foo<&'a int>
|
||||
@ -81,10 +81,10 @@ impl PredicateSet<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'tcx> {
|
||||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
||||
impl Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
|
||||
fn extend<I: IntoIterator<Item = ty::Predicate<'tcx>>>(&mut self, iter: I) {
|
||||
for pred in iter {
|
||||
self.insert(pred.as_ref());
|
||||
self.insert(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@ pub fn elaborate_obligations<'tcx>(
|
||||
mut obligations: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Elaborator<'tcx> {
|
||||
let mut visited = PredicateSet::new(tcx);
|
||||
obligations.retain(|obligation| visited.insert(&obligation.predicate));
|
||||
obligations.retain(|obligation| visited.insert(obligation.predicate));
|
||||
Elaborator { stack: obligations, visited }
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ impl Elaborator<'tcx> {
|
||||
// cases. One common case is when people define
|
||||
// `trait Sized: Sized { }` rather than `trait Sized { }`.
|
||||
let visited = &mut self.visited;
|
||||
let obligations = obligations.filter(|o| visited.insert(&o.predicate));
|
||||
let obligations = obligations.filter(|o| visited.insert(o.predicate));
|
||||
|
||||
self.stack.extend(obligations);
|
||||
}
|
||||
@ -260,7 +260,7 @@ impl Elaborator<'tcx> {
|
||||
}
|
||||
})
|
||||
.map(|predicate_kind| predicate_kind.to_predicate(tcx))
|
||||
.filter(|predicate| visited.insert(predicate))
|
||||
.filter(|&predicate| visited.insert(predicate))
|
||||
.map(|predicate| predicate_obligation(predicate, None)),
|
||||
);
|
||||
}
|
||||
|
@ -1094,12 +1094,6 @@ pub struct CratePredicatesMap<'tcx> {
|
||||
pub predicates: FxHashMap<DefId, &'tcx [(ty::Predicate<'tcx>, Span)]>,
|
||||
}
|
||||
|
||||
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
|
||||
fn as_ref(&self) -> &Predicate<'tcx> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Predicate<'tcx> {
|
||||
/// Performs a substitution suitable for going from a
|
||||
/// poly-trait-ref to supertraits that must hold if that
|
||||
@ -1214,17 +1208,17 @@ pub struct TraitPredicate<'tcx> {
|
||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> TraitPredicate<'tcx> {
|
||||
pub fn def_id(&self) -> DefId {
|
||||
pub fn def_id(self) -> DefId {
|
||||
self.trait_ref.def_id
|
||||
}
|
||||
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
pub fn self_ty(self) -> Ty<'tcx> {
|
||||
self.trait_ref.self_ty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
pub fn def_id(&self) -> DefId {
|
||||
pub fn def_id(self) -> DefId {
|
||||
// Ok to skip binder since trait `DefId` does not care about regions.
|
||||
self.skip_binder().def_id()
|
||||
}
|
||||
|
@ -768,12 +768,12 @@ impl AutoTraitFinder<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::RegionOutlives(ref binder) => {
|
||||
&ty::PredicateKind::RegionOutlives(binder) => {
|
||||
if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::TypeOutlives(ref binder) => {
|
||||
&ty::PredicateKind::TypeOutlives(binder) => {
|
||||
match (
|
||||
binder.no_bound_vars(),
|
||||
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
|
||||
|
@ -146,9 +146,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
|
||||
if self.error_implies(&error2.predicate, &error.predicate)
|
||||
if self.error_implies(error2.predicate, error.predicate)
|
||||
&& !(error2.index >= error.index
|
||||
&& self.error_implies(&error.predicate, &error2.predicate))
|
||||
&& self.error_implies(error.predicate, error2.predicate))
|
||||
{
|
||||
info!("skipping {:?} (implied by {:?})", error, error2);
|
||||
is_suppressed[index] = true;
|
||||
@ -500,7 +500,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
ty::PredicateKind::RegionOutlives(ref predicate) => {
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
let err = self
|
||||
.region_outlives_predicate(&obligation.cause, &predicate)
|
||||
.region_outlives_predicate(&obligation.cause, predicate)
|
||||
.err()
|
||||
.unwrap();
|
||||
struct_span_err!(
|
||||
@ -955,7 +955,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
trait InferCtxtPrivExt<'tcx> {
|
||||
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
|
||||
// `error` occurring implies that `cond` occurs.
|
||||
fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool;
|
||||
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
|
||||
|
||||
fn report_fulfillment_error(
|
||||
&self,
|
||||
@ -1042,7 +1042,7 @@ trait InferCtxtPrivExt<'tcx> {
|
||||
impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
|
||||
// `error` occurring implies that `cond` occurs.
|
||||
fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool {
|
||||
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
|
||||
if cond == error {
|
||||
return true;
|
||||
}
|
||||
@ -1055,7 +1055,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(*cond)) {
|
||||
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
|
||||
if let ty::PredicateKind::Trait(implication, _) = obligation.predicate.kind() {
|
||||
let error = error.to_poly_trait_ref();
|
||||
let implication = implication.to_poly_trait_ref();
|
||||
|
@ -378,7 +378,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::RegionOutlives(ref binder) => {
|
||||
&ty::PredicateKind::RegionOutlives(binder) => {
|
||||
match infcx.region_outlives_predicate(&obligation.cause, binder) {
|
||||
Ok(()) => ProcessResult::Changed(vec![]),
|
||||
Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)),
|
||||
@ -481,7 +481,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(subtype) => {
|
||||
&ty::PredicateKind::Subtype(subtype) => {
|
||||
match self.selcx.infcx().subtype_predicate(
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
|
@ -1541,14 +1541,14 @@ fn assoc_ty_def(
|
||||
crate trait ProjectionCacheKeyExt<'tcx>: Sized {
|
||||
fn from_poly_projection_predicate(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
predicate: &ty::PolyProjectionPredicate<'tcx>,
|
||||
predicate: ty::PolyProjectionPredicate<'tcx>,
|
||||
) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl<'tcx> ProjectionCacheKeyExt<'tcx> for ProjectionCacheKey<'tcx> {
|
||||
fn from_poly_projection_predicate(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
predicate: &ty::PolyProjectionPredicate<'tcx>,
|
||||
predicate: ty::PolyProjectionPredicate<'tcx>,
|
||||
) -> Option<Self> {
|
||||
let infcx = selcx.infcx();
|
||||
// We don't do cross-snapshot caching of obligations with escaping regions,
|
||||
|
@ -415,13 +415,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
match obligation.predicate.kind() {
|
||||
ty::PredicateKind::Trait(t, _) => {
|
||||
&ty::PredicateKind::Trait(t, _) => {
|
||||
debug_assert!(!t.has_escaping_bound_vars());
|
||||
let obligation = obligation.with(*t);
|
||||
let obligation = obligation.with(t);
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(p) => {
|
||||
&ty::PredicateKind::Subtype(p) => {
|
||||
// Does this code ever run?
|
||||
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
|
||||
Some(Ok(InferOk { mut obligations, .. })) => {
|
||||
@ -463,8 +463,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let project_obligation = obligation.with(*data);
|
||||
&ty::PredicateKind::Projection(data) => {
|
||||
let project_obligation = obligation.with(data);
|
||||
match project::poly_project_and_unify_type(self, &project_obligation) {
|
||||
Ok(Some(mut subobligations)) => {
|
||||
self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
|
||||
@ -962,7 +962,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars());
|
||||
|
||||
if let Some(c) =
|
||||
self.check_candidate_cache(stack.obligation.param_env, &cache_fresh_trait_pred)
|
||||
self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred)
|
||||
{
|
||||
debug!("CACHE HIT: SELECT({:?})={:?}", cache_fresh_trait_pred, c);
|
||||
return c;
|
||||
@ -1247,7 +1247,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn check_candidate_cache(
|
||||
&mut self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cache_fresh_trait_pred: &ty::PolyTraitPredicate<'tcx>,
|
||||
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
|
||||
let tcx = self.tcx();
|
||||
let trait_ref = &cache_fresh_trait_pred.skip_binder().trait_ref;
|
||||
|
@ -108,9 +108,9 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||
}
|
||||
|
||||
// Don't recurse if this trait alias is already on the stack for the DFS search.
|
||||
let anon_pred = anonymize_predicate(tcx, &pred);
|
||||
let anon_pred = anonymize_predicate(tcx, pred);
|
||||
if item.path.iter().rev().skip(1).any(|(tr, _)| {
|
||||
anonymize_predicate(tcx, &tr.without_const().to_predicate(tcx)) == anon_pred
|
||||
anonymize_predicate(tcx, tr.without_const().to_predicate(tcx)) == anon_pred
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ pub fn predicate_obligations<'a, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body_id: hir::HirId,
|
||||
predicate: &ty::Predicate<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
span: Span,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![], item: None };
|
||||
|
@ -179,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Dynamic(ref object_type, ..) => {
|
||||
let sig = object_type.projection_bounds().find_map(|pb| {
|
||||
let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self);
|
||||
self.deduce_sig_from_projection(None, &pb)
|
||||
self.deduce_sig_from_projection(None, pb)
|
||||
});
|
||||
let kind = object_type
|
||||
.principal_def_id()
|
||||
@ -206,8 +206,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
obligation.predicate
|
||||
);
|
||||
|
||||
if let ty::PredicateKind::Projection(ref proj_predicate) =
|
||||
obligation.predicate.kind()
|
||||
if let &ty::PredicateKind::Projection(proj_predicate) = obligation.predicate.kind()
|
||||
{
|
||||
// Given a Projection predicate, we can potentially infer
|
||||
// the complete signature.
|
||||
@ -238,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn deduce_sig_from_projection(
|
||||
&self,
|
||||
cause_span: Option<Span>,
|
||||
projection: &ty::PolyProjectionPredicate<'tcx>,
|
||||
projection: ty::PolyProjectionPredicate<'tcx>,
|
||||
) -> Option<ExpectedSig<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
@ -644,7 +643,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// where R is the return type we are expecting. This type `T`
|
||||
// will be our output.
|
||||
let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
|
||||
if let ty::PredicateKind::Projection(ref proj_predicate) = obligation.predicate.kind() {
|
||||
if let &ty::PredicateKind::Projection(proj_predicate) = obligation.predicate.kind() {
|
||||
self.deduce_future_output_from_projection(obligation.cause.span, proj_predicate)
|
||||
} else {
|
||||
None
|
||||
@ -665,7 +664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn deduce_future_output_from_projection(
|
||||
&self,
|
||||
cause_span: Span,
|
||||
predicate: &ty::PolyProjectionPredicate<'tcx>,
|
||||
predicate: ty::PolyProjectionPredicate<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
debug!("deduce_future_output_from_projection(predicate={:?})", predicate);
|
||||
|
||||
|
@ -205,7 +205,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||
// just to look for all the predicates directly.
|
||||
|
||||
assert_eq!(dtor_predicates.parent, None);
|
||||
for (predicate, predicate_sp) in dtor_predicates.predicates {
|
||||
for &(predicate, predicate_sp) in dtor_predicates.predicates {
|
||||
// (We do not need to worry about deep analysis of type
|
||||
// expressions etc because the Drop impls are already forced
|
||||
// to take on a structure that is roughly an alpha-renaming of
|
||||
@ -228,7 +228,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||
// This implementation solves (Issue #59497) and (Issue #58311).
|
||||
// It is unclear to me at the moment whether the approach based on `relate`
|
||||
// could be extended easily also to the other `Predicate`.
|
||||
let predicate_matches_closure = |p: &'_ Predicate<'tcx>| {
|
||||
let predicate_matches_closure = |p: Predicate<'tcx>| {
|
||||
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
|
||||
match (predicate.kind(), p.kind()) {
|
||||
(ty::PredicateKind::Trait(a, _), ty::PredicateKind::Trait(b, _)) => {
|
||||
@ -241,12 +241,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
if !assumptions_in_impl_context.iter().any(predicate_matches_closure) {
|
||||
if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) {
|
||||
let item_span = tcx.hir().span(self_type_hir_id);
|
||||
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id());
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
*predicate_sp,
|
||||
predicate_sp,
|
||||
E0367,
|
||||
"`Drop` impl requires `{}` but the {} it is implemented for does not",
|
||||
predicate,
|
||||
|
@ -819,8 +819,8 @@ fn check_where_clauses<'tcx, 'fcx>(
|
||||
debug!("check_where_clauses: predicates={:?}", predicates.predicates);
|
||||
assert_eq!(predicates.predicates.len(), predicates.spans.len());
|
||||
let wf_obligations =
|
||||
predicates.predicates.iter().zip(predicates.spans.iter()).flat_map(|(p, sp)| {
|
||||
traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, *sp)
|
||||
predicates.predicates.iter().zip(predicates.spans.iter()).flat_map(|(&p, &sp)| {
|
||||
traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, sp)
|
||||
});
|
||||
|
||||
for obligation in wf_obligations.chain(default_obligations) {
|
||||
|
@ -329,16 +329,13 @@ fn check_predicates<'tcx>(
|
||||
// which is sound because we forbid impls like the following
|
||||
//
|
||||
// impl<D: Debug> AlwaysApplicable for D { }
|
||||
let always_applicable_traits = impl1_predicates
|
||||
.predicates
|
||||
.iter()
|
||||
.filter(|predicate| {
|
||||
let always_applicable_traits =
|
||||
impl1_predicates.predicates.iter().copied().filter(|&predicate| {
|
||||
matches!(
|
||||
trait_predicate_kind(tcx, predicate),
|
||||
Some(TraitSpecializationKind::AlwaysApplicable)
|
||||
)
|
||||
})
|
||||
.copied();
|
||||
});
|
||||
|
||||
// Include the well-formed predicates of the type parameters of the impl.
|
||||
for ty in tcx.impl_trait_ref(impl1_def_id).unwrap().substs.types() {
|
||||
@ -361,12 +358,12 @@ fn check_predicates<'tcx>(
|
||||
|
||||
for predicate in impl1_predicates.predicates {
|
||||
if !impl2_predicates.predicates.contains(&predicate) {
|
||||
check_specialization_on(tcx, &predicate, span)
|
||||
check_specialization_on(tcx, predicate, span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: &ty::Predicate<'tcx>, span: Span) {
|
||||
fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
|
||||
debug!("can_specialize_on(predicate = {:?})", predicate);
|
||||
match predicate.kind() {
|
||||
// Global predicates are either always true or always false, so we
|
||||
@ -399,7 +396,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: &ty::Predicate<'t
|
||||
|
||||
fn trait_predicate_kind<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicate: &ty::Predicate<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
) -> Option<TraitSpecializationKind> {
|
||||
match predicate.kind() {
|
||||
ty::PredicateKind::Trait(pred, hir::Constness::NotConst) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user