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

Remove PredicateKind and instead only use Binder<PredicateAtom> #80679

Merged
merged 15 commits into from
Jan 17, 2021
9 changes: 4 additions & 5 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
@@ -530,19 +530,18 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {

let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2))
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
}
GenericArgKind::Type(t1) => {
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(t1, r2))
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(t1, r2))
}
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// encounter this branch.
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
};
let predicate =
predicate.rebind(atom).potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
let predicate = predicate.rebind(atom).to_predicate(self.tcx);

Obligation::new(cause.clone(), param_env, predicate)
})
@@ -664,7 +663,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
predicate: ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(sup, sub))
predicate: ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
.to_predicate(self.infcx.tcx),
recursion_depth: 0,
});
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
@@ -358,7 +358,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
ty::PredicateAtom::WellFormed(b_ty.into()).to_predicate(self.infcx.tcx),
ty::PredicateKind::WellFormed(b_ty.into()).to_predicate(self.infcx.tcx),
));
}

@@ -451,9 +451,9 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
b: &'tcx ty::Const<'tcx>,
) {
let predicate = if a_is_expected {
ty::PredicateAtom::ConstEquate(a, b)
ty::PredicateKind::ConstEquate(a, b)
} else {
ty::PredicateAtom::ConstEquate(b, a)
ty::PredicateKind::ConstEquate(b, a)
};
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -1706,8 +1706,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {

for (predicate, _) in bounds {
let predicate = predicate.subst(self.tcx, substs);
if let ty::PredicateAtom::Projection(projection_predicate) =
predicate.skip_binders()
if let ty::PredicateKind::Projection(projection_predicate) =
predicate.kind().skip_binder()
{
if projection_predicate.projection_ty.item_def_id == item_def_id {
// We don't account for multiple `Future::Output = Ty` contraints.
29 changes: 14 additions & 15 deletions compiler/rustc_infer/src/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@ pub mod verify;

use rustc_middle::traits::query::OutlivesBound;
use rustc_middle::ty;
use rustc_middle::ty::fold::TypeFoldable;

pub fn explicit_outlives_bounds<'tcx>(
param_env: ty::ParamEnv<'tcx>,
@@ -15,20 +14,20 @@ pub fn explicit_outlives_bounds<'tcx>(
param_env
.caller_bounds()
.into_iter()
.map(ty::Predicate::skip_binders)
.filter(|atom| !atom.has_escaping_bound_vars())
.filter_map(move |atom| match atom {
ty::PredicateAtom::Projection(..)
| ty::PredicateAtom::Trait(..)
| ty::PredicateAtom::Subtype(..)
| ty::PredicateAtom::WellFormed(..)
| ty::PredicateAtom::ObjectSafe(..)
| ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::TypeOutlives(..)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..)
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
.map(ty::Predicate::kind)
.filter_map(ty::Binder::no_bound_vars)
.filter_map(move |kind| match 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(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
}
})
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/sub.rs
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
self.fields.obligations.push(Obligation::new(
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::PredicateAtom::Subtype(ty::SubtypePredicate {
ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a,
b,
37 changes: 16 additions & 21 deletions compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
@@ -9,13 +9,8 @@ pub fn anonymize_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
pred: ty::Predicate<'tcx>,
) -> ty::Predicate<'tcx> {
match *pred.kind() {
ty::PredicateKind::ForAll(binder) => {
let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder));
tcx.reuse_or_mk_predicate(pred, new)
}
ty::PredicateKind::Atom(_) => pred,
}
let new = tcx.anonymize_late_bound_regions(pred.kind());
tcx.reuse_or_mk_predicate(pred, new)
}

struct PredicateSet<'tcx> {
@@ -126,9 +121,9 @@ impl Elaborator<'tcx> {
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx;

let bound_predicate = obligation.predicate.bound_atom();
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(data, _) => {
ty::PredicateKind::Trait(data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());

@@ -150,36 +145,36 @@ impl Elaborator<'tcx> {

self.stack.extend(obligations);
}
ty::PredicateAtom::WellFormed(..) => {
ty::PredicateKind::WellFormed(..) => {
// Currently, we do not elaborate WF predicates,
// although we easily could.
}
ty::PredicateAtom::ObjectSafe(..) => {
ty::PredicateKind::ObjectSafe(..) => {
// Currently, we do not elaborate object-safe
// predicates.
}
ty::PredicateAtom::Subtype(..) => {
ty::PredicateKind::Subtype(..) => {
// Currently, we do not "elaborate" predicates like `X <: Y`,
// though conceivably we might.
}
ty::PredicateAtom::Projection(..) => {
ty::PredicateKind::Projection(..) => {
// Nothing to elaborate in a projection predicate.
}
ty::PredicateAtom::ClosureKind(..) => {
ty::PredicateKind::ClosureKind(..) => {
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
ty::PredicateAtom::ConstEvaluatable(..) => {
ty::PredicateKind::ConstEvaluatable(..) => {
// Currently, we do not elaborate const-evaluatable
// predicates.
}
ty::PredicateAtom::ConstEquate(..) => {
ty::PredicateKind::ConstEquate(..) => {
// Currently, we do not elaborate const-equate
// predicates.
}
ty::PredicateAtom::RegionOutlives(..) => {
ty::PredicateKind::RegionOutlives(..) => {
// Nothing to elaborate from `'a: 'b`.
}
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
// 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
@@ -209,15 +204,15 @@ impl Elaborator<'tcx> {
if r.is_late_bound() {
None
} else {
Some(ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(
Some(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
r, r_min,
)))
}
}

Component::Param(p) => {
let ty = tcx.mk_ty_param(p.index, p.name);
Some(ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(
Some(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
ty, r_min,
)))
}
@@ -242,7 +237,7 @@ impl Elaborator<'tcx> {
}),
);
}
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
// Nothing to elaborate
}
}
12 changes: 6 additions & 6 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -1550,13 +1550,13 @@ declare_lint_pass!(
impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::PredicateAtom::*;
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.skip_binders() {
let predicate_kind_name = match predicate.kind().skip_binder() {
Trait(..) => "Trait",
TypeOutlives(..) |
RegionOutlives(..) => "Lifetime",
@@ -1936,8 +1936,8 @@ impl ExplicitOutlivesRequirements {
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred.skip_binders() {
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
_ => None,
},
@@ -1952,8 +1952,8 @@ impl ExplicitOutlivesRequirements {
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred.skip_binders() {
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
a.is_param(index).then_some(b)
}
_ => None,
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/traits.rs
Original file line number Diff line number Diff line change
@@ -45,12 +45,12 @@ declare_lint_pass!(

impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
use rustc_middle::ty::PredicateAtom::*;
use rustc_middle::ty::PredicateKind::*;

let def_id = cx.tcx.hir().local_def_id(item.hir_id);
let predicates = cx.tcx.explicit_predicates_of(def_id);
for &(predicate, span) in predicates.predicates {
let trait_predicate = match predicate.skip_binders() {
let trait_predicate = match predicate.kind().skip_binder() {
Trait(trait_predicate, _constness) => trait_predicate,
_ => continue,
};
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
@@ -202,8 +202,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
let mut has_emitted = false;
for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::PredicateAtom::Trait(ref poly_trait_predicate, _) =
predicate.skip_binders()
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
predicate.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;
let descr_pre =
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ pub(super) struct EncodeContext<'a, 'tcx> {

lazy_state: LazyState,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::PredicateKind<'tcx>, usize>,

interpret_allocs: FxIndexSet<interpret::AllocId>,

@@ -328,7 +328,7 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
&mut self.type_shorthands
}

fn predicate_shorthands(&mut self) -> &mut FxHashMap<rustc_middle::ty::Predicate<'tcx>, usize> {
fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize> {
&mut self.predicate_shorthands
}

59 changes: 49 additions & 10 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
@@ -43,10 +43,12 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
}
}

impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate<'tcx> {
impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
type Variant = ty::PredicateKind<'tcx>;

#[inline]
fn variant(&self) -> &Self::Variant {
self.kind()
self
}
}

@@ -55,7 +57,7 @@ pub trait TyEncoder<'tcx>: Encoder {

fn position(&self) -> usize;
fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::Predicate<'tcx>, usize>;
fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize>;
fn encode_alloc_id(&mut self, alloc_id: &AllocId) -> Result<(), Self::Error>;
}

@@ -118,9 +120,15 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
}
}

impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<ty::PredicateKind<'tcx>> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands)
}
}

impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
encode_with_shorthand(e, self, TyEncoder::predicate_shorthands)
self.kind().encode(e)
}
}

@@ -218,18 +226,24 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
}
}

impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error> {
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<ty::PredicateKind<'tcx>> {
fn decode(decoder: &mut D) -> Result<ty::Binder<ty::PredicateKind<'tcx>>, D::Error> {
// Handle shorthands first, if we have an usize > 0x80.
let predicate_kind = if decoder.positioned_at_shorthand() {
Ok(ty::Binder::bind(if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize()?;
assert!(pos >= SHORTHAND_OFFSET);
let shorthand = pos - SHORTHAND_OFFSET;

decoder.with_position(shorthand, ty::PredicateKind::decode)
decoder.with_position(shorthand, ty::PredicateKind::decode)?
} else {
ty::PredicateKind::decode(decoder)
}?;
ty::PredicateKind::decode(decoder)?
}))
}
}

impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error> {
let predicate_kind = Decodable::decode(decoder)?;
let predicate = decoder.tcx().mk_predicate(predicate_kind);
Ok(predicate)
}
@@ -457,3 +471,28 @@ macro_rules! implement_ty_decoder {
}
}
}

macro_rules! impl_binder_encode_decode {
($($t:ty),+ $(,)?) => {
$(
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<$t> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
self.as_ref().skip_binder().encode(e)
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<$t> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
Ok(ty::Binder::bind(Decodable::decode(decoder)?))
}
}
)*
}
}

impl_binder_encode_decode! {
&'tcx ty::List<Ty<'tcx>>,
ty::FnSig<'tcx>,
ty::ExistentialPredicate<'tcx>,
ty::TraitRef<'tcx>,
Vec<ty::GeneratorInteriorTypeCause<'tcx>>,
}
Loading