Skip to content

Commit

Permalink
Auto merge of #80679 - jackh726:predicate-kind-take2, r=lcnr
Browse files Browse the repository at this point in the history
Remove PredicateKind and instead only use Binder<PredicateAtom>

Originally brought up in #76814 (comment)

r? `@lcnr`
  • Loading branch information
bors committed Jan 17, 2021
2 parents 1f0fc02 + c4376ba commit 4253153
Show file tree
Hide file tree
Showing 71 changed files with 655 additions and 759 deletions.
9 changes: 4 additions & 5 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
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
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
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
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
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
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
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
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
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
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
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>>,
}

0 comments on commit 4253153

Please sign in to comment.