Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intern predicates #72055

Merged
merged 6 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/librustc_infer/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
use rustc_middle::ty::{self, BoundVar, Const, Ty, TyCtxt};
use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt};
use std::fmt::Debug;

impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
Expand Down Expand Up @@ -532,12 +532,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
cause.clone(),
param_env,
match k1.unpack() {
GenericArgKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
GenericArgKind::Lifetime(r1) => ty::PredicateKind::RegionOutlives(
ty::Binder::bind(ty::OutlivesPredicate(r1, r2)),
),
GenericArgKind::Type(t1) => {
ty::Predicate::TypeOutlives(ty::Binder::bind(ty::OutlivesPredicate(t1, r2)))
}
)
.to_predicate(self.tcx),
GenericArgKind::Type(t1) => ty::PredicateKind::TypeOutlives(ty::Binder::bind(
ty::OutlivesPredicate(t1, r2),
))
.to_predicate(self.tcx),
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// ecounter this branch.
Expand Down Expand Up @@ -664,9 +666,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
predicate: ty::Predicate::RegionOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
predicate: ty::PredicateKind::RegionOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
sup, sub,
))),
)))
.to_predicate(self.infcx.tcx),
recursion_depth: 0,
});
}
Expand Down
14 changes: 9 additions & 5 deletions src/librustc_infer/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::{Span, DUMMY_SP};

Expand Down Expand Up @@ -307,7 +307,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
ty::Predicate::WellFormed(b_ty),
ty::PredicateKind::WellFormed(b_ty).to_predicate(self.infcx.tcx),
));
}

Expand Down Expand Up @@ -398,11 +398,15 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
b: &'tcx ty::Const<'tcx>,
) {
let predicate = if a_is_expected {
ty::Predicate::ConstEquate(a, b)
ty::PredicateKind::ConstEquate(a, b)
} else {
ty::Predicate::ConstEquate(b, a)
ty::PredicateKind::ConstEquate(b, a)
};
self.obligations.push(Obligation::new(self.trace.cause.clone(), self.param_env, predicate));
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
predicate.to_predicate(self.tcx()),
));
}
}

Expand Down
22 changes: 11 additions & 11 deletions src/librustc_infer/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ pub fn explicit_outlives_bounds<'tcx>(
param_env: ty::ParamEnv<'tcx>,
) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
debug!("explicit_outlives_bounds()");
param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate {
ty::Predicate::Projection(..)
| ty::Predicate::Trait(..)
| ty::Predicate::Subtype(..)
| ty::Predicate::WellFormed(..)
| ty::Predicate::ObjectSafe(..)
| ty::Predicate::ClosureKind(..)
| ty::Predicate::TypeOutlives(..)
| ty::Predicate::ConstEvaluatable(..)
| ty::Predicate::ConstEquate(..) => None,
ty::Predicate::RegionOutlives(ref data) => data
param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate.kind() {
ty::PredicateKind::Projection(..)
| ty::PredicateKind::Trait(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => None,
ty::PredicateKind::RegionOutlives(ref data) => data
.no_bound_vars()
.map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)),
})
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_infer/infer/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::traits::Obligation;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use std::mem;

/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
Expand Down Expand Up @@ -100,11 +100,12 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
self.fields.obligations.push(Obligation::new(
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::Predicate::Subtype(ty::Binder::dummy(ty::SubtypePredicate {
ty::PredicateKind::Subtype(ty::Binder::dummy(ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a,
b,
})),
}))
.to_predicate(self.tcx()),
));

Ok(a)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
cause,
recursion_depth: 0,
param_env,
predicate: trait_ref.without_const().to_predicate(),
predicate: trait_ref.without_const().to_predicate(infcx.tcx),
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;

// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateObligation<'_>, 112);
static_assert_size!(PredicateObligation<'_>, 88);

pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
Expand Down
82 changes: 46 additions & 36 deletions src/librustc_infer/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,49 @@ pub fn anonymize_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
pred: &ty::Predicate<'tcx>,
) -> ty::Predicate<'tcx> {
match *pred {
ty::Predicate::Trait(ref data, constness) => {
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
match pred.kind() {
&ty::PredicateKind::Trait(ref data, constness) => {
ty::PredicateKind::Trait(tcx.anonymize_late_bound_regions(data), constness)
.to_predicate(tcx)
}

ty::Predicate::RegionOutlives(ref data) => {
ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::RegionOutlives(data) => {
ty::PredicateKind::RegionOutlives(tcx.anonymize_late_bound_regions(data))
.to_predicate(tcx)
}

ty::Predicate::TypeOutlives(ref data) => {
ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::TypeOutlives(data) => {
ty::PredicateKind::TypeOutlives(tcx.anonymize_late_bound_regions(data))
.to_predicate(tcx)
}

ty::Predicate::Projection(ref data) => {
ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::Projection(data) => {
ty::PredicateKind::Projection(tcx.anonymize_late_bound_regions(data)).to_predicate(tcx)
}

ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data),
&ty::PredicateKind::WellFormed(data) => {
ty::PredicateKind::WellFormed(data).to_predicate(tcx)
}

ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data),
&ty::PredicateKind::ObjectSafe(data) => {
ty::PredicateKind::ObjectSafe(data).to_predicate(tcx)
}

ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
&ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind).to_predicate(tcx)
}

ty::Predicate::Subtype(ref data) => {
ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::Subtype(data) => {
ty::PredicateKind::Subtype(tcx.anonymize_late_bound_regions(data)).to_predicate(tcx)
}

ty::Predicate::ConstEvaluatable(def_id, substs) => {
ty::Predicate::ConstEvaluatable(def_id, substs)
&ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
ty::PredicateKind::ConstEvaluatable(def_id, substs).to_predicate(tcx)
}

ty::Predicate::ConstEquate(c1, c2) => ty::Predicate::ConstEquate(c1, c2),
ty::PredicateKind::ConstEquate(c1, c2) => {
ty::PredicateKind::ConstEquate(c1, c2).to_predicate(tcx)
}
}
}

Expand Down Expand Up @@ -99,14 +108,14 @@ pub fn elaborate_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate()))
elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx)))
}

pub fn elaborate_trait_refs<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate());
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx));
elaborate_predicates(tcx, predicates)
}

Expand Down Expand Up @@ -145,8 +154,8 @@ impl Elaborator<'tcx> {

fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx;
match obligation.predicate {
ty::Predicate::Trait(ref data, _) => {
match obligation.predicate.kind() {
ty::PredicateKind::Trait(ref data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());

Expand All @@ -167,36 +176,36 @@ impl Elaborator<'tcx> {

self.stack.extend(obligations);
}
ty::Predicate::WellFormed(..) => {
ty::PredicateKind::WellFormed(..) => {
// Currently, we do not elaborate WF predicates,
// although we easily could.
}
ty::Predicate::ObjectSafe(..) => {
ty::PredicateKind::ObjectSafe(..) => {
// Currently, we do not elaborate object-safe
// predicates.
}
ty::Predicate::Subtype(..) => {
ty::PredicateKind::Subtype(..) => {
// Currently, we do not "elaborate" predicates like `X <: Y`,
// though conceivably we might.
}
ty::Predicate::Projection(..) => {
ty::PredicateKind::Projection(..) => {
// Nothing to elaborate in a projection predicate.
}
ty::Predicate::ClosureKind(..) => {
ty::PredicateKind::ClosureKind(..) => {
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
ty::Predicate::ConstEvaluatable(..) => {
ty::PredicateKind::ConstEvaluatable(..) => {
// Currently, we do not elaborate const-evaluatable
// predicates.
}
ty::Predicate::ConstEquate(..) => {
ty::PredicateKind::ConstEquate(..) => {
// Currently, we do not elaborate const-equate
// predicates.
}
ty::Predicate::RegionOutlives(..) => {
ty::PredicateKind::RegionOutlives(..) => {
// Nothing to elaborate from `'a: 'b`.
}
ty::Predicate::TypeOutlives(ref data) => {
ty::PredicateKind::TypeOutlives(ref data) => {
// We know that `T: 'a` for some type `T`. We can
// often elaborate this. For example, if we know that
// `[U]: 'a`, that implies that `U: 'a`. Similarly, if
Expand Down Expand Up @@ -228,15 +237,15 @@ impl Elaborator<'tcx> {
if r.is_late_bound() {
None
} else {
Some(ty::Predicate::RegionOutlives(ty::Binder::dummy(
Some(ty::PredicateKind::RegionOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(r, r_min),
)))
}
}

Component::Param(p) => {
let ty = tcx.mk_ty_param(p.index, p.name);
Some(ty::Predicate::TypeOutlives(ty::Binder::dummy(
Some(ty::PredicateKind::TypeOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(ty, r_min),
)))
}
Expand All @@ -250,8 +259,9 @@ impl Elaborator<'tcx> {
None
}
})
.filter(|p| visited.insert(p))
.map(|p| predicate_obligation(p, None)),
.map(|predicate_kind| predicate_kind.to_predicate(tcx))
.filter(|predicate| visited.insert(predicate))
.map(|predicate| predicate_obligation(predicate, None)),
);
}
}
Expand Down Expand Up @@ -317,7 +327,7 @@ impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToT

fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(obligation) = self.base_iterator.next() {
if let ty::Predicate::Trait(data, _) = obligation.predicate {
if let ty::PredicateKind::Trait(data, _) = obligation.predicate.kind() {
return Some(data.to_poly_trait_ref());
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,13 +1202,13 @@ declare_lint_pass!(
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'tcx>) {
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::Predicate::*;
use rustc_middle::ty::PredicateKind::*;

if cx.tcx.features().trivial_bounds {
let def_id = cx.tcx.hir().local_def_id(item.hir_id);
let predicates = cx.tcx.predicates_of(def_id);
for &(predicate, span) in predicates.predicates {
let predicate_kind_name = match predicate {
let predicate_kind_name = match predicate.kind() {
Trait(..) => "Trait",
TypeOutlives(..) |
RegionOutlives(..) => "Lifetime",
Expand Down Expand Up @@ -1497,8 +1497,8 @@ impl ExplicitOutlivesRequirements {
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred {
ty::Predicate::RegionOutlives(outlives) => {
.filter_map(|(pred, _)| match pred.kind() {
ty::PredicateKind::RegionOutlives(outlives) => {
let outlives = outlives.skip_binder();
match outlives.0 {
ty::ReEarlyBound(ebr) if ebr.index == index => Some(outlives.1),
Expand All @@ -1516,8 +1516,8 @@ impl ExplicitOutlivesRequirements {
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred {
ty::Predicate::TypeOutlives(outlives) => {
.filter_map(|(pred, _)| match pred.kind() {
ty::PredicateKind::TypeOutlives(outlives) => {
let outlives = outlives.skip_binder();
outlives.0.is_param(index).then_some(outlives.1)
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
ty::Opaque(def, _) => {
let mut has_emitted = false;
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
if let ty::Predicate::Trait(ref poly_trait_predicate, _) = predicate {
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
predicate.kind()
{
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
let def_id = trait_ref.def_id;
let descr_pre =
Expand Down
Loading