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
Expand Up @@ -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)
})
Expand Down Expand Up @@ -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,
});
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
));
}

Expand Down Expand Up @@ -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(),
Expand Down
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
Expand Up @@ -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.
Expand Down
29 changes: 14 additions & 15 deletions compiler/rustc_infer/src/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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))
}
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
37 changes: 16 additions & 21 deletions compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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());

Expand All @@ -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
Expand Down Expand Up @@ -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,
)))
}
Expand All @@ -242,7 +237,7 @@ impl Elaborator<'tcx> {
}),
);
}
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
// Nothing to elaborate
}
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
},
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,

Expand Down Expand Up @@ -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
}

Expand Down
59 changes: 49 additions & 10 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand All @@ -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>;
}

Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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