Skip to content

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

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

Merged
merged 15 commits into from
Jan 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Remove PredicateKind::Atom
  • Loading branch information
jackh726 committed Jan 16, 2021
commit 8278314a8bf76c9d56072d294ee1d5ba76551cb6
3 changes: 1 addition & 2 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
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).potentially_quantified(self.tcx);

Obligation::new(cause.clone(), param_env, predicate)
})
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub fn anonymize_predicate<'tcx>(
let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder));
tcx.reuse_or_mk_predicate(pred, new)
}
ty::PredicateKind::Atom(_) => pred,
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ impl FlagComputation {
computation.add_predicate_atom(atom)
});
}
ty::PredicateKind::Atom(atom) => self.add_predicate_atom(atom),
}
}

Expand Down
45 changes: 10 additions & 35 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ crate struct PredicateInner<'tcx> {
}

#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateInner<'_>, 48);
static_assert_size!(PredicateInner<'_>, 40);

#[derive(Clone, Copy, Lift)]
pub struct Predicate<'tcx> {
Expand Down Expand Up @@ -1074,10 +1074,6 @@ impl<'tcx> Predicate<'tcx> {
pub fn skip_binders(self) -> PredicateAtom<'tcx> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder(),
&PredicateKind::Atom(atom) => {
debug_assert!(!atom.has_escaping_bound_vars());
atom
}
}
}

Expand All @@ -1090,7 +1086,6 @@ impl<'tcx> Predicate<'tcx> {
pub fn skip_binders_unchecked(self) -> PredicateAtom<'tcx> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder(),
&PredicateKind::Atom(atom) => atom,
}
}

Expand All @@ -1099,19 +1094,14 @@ impl<'tcx> Predicate<'tcx> {
pub fn bound_atom(self) -> Binder<PredicateAtom<'tcx>> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder,
&PredicateKind::Atom(atom) => {
debug_assert!(!atom.has_escaping_bound_vars());
Binder::dummy(atom)
}
}
}

/// Allows using a `Binder<PredicateAtom<'tcx>>` even if the given predicate previously
/// contained unbound variables by shifting these variables outwards.
pub fn bound_atom_with_opt_escaping(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
pub fn bound_atom_with_opt_escaping(self, _tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder,
&PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom),
}
}
}
Expand All @@ -1136,7 +1126,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
pub enum PredicateKind<'tcx> {
/// `for<'a>: ...`
ForAll(Binder<PredicateAtom<'tcx>>),
Atom(PredicateAtom<'tcx>),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
Expand Down Expand Up @@ -1189,16 +1178,8 @@ pub enum PredicateAtom<'tcx> {

impl<'tcx> Binder<PredicateAtom<'tcx>> {
/// Wraps `self` with the given qualifier if this predicate has any unbound variables.
pub fn potentially_quantified(
self,
tcx: TyCtxt<'tcx>,
qualifier: impl FnOnce(Binder<PredicateAtom<'tcx>>) -> PredicateKind<'tcx>,
) -> Predicate<'tcx> {
match self.no_bound_vars() {
Some(atom) => PredicateKind::Atom(atom),
None => qualifier(self),
}
.to_predicate(tcx)
pub fn potentially_quantified(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateKind::ForAll(self).to_predicate(tcx)
}
}

Expand Down Expand Up @@ -1289,11 +1270,7 @@ impl<'tcx> Predicate<'tcx> {
let substs = trait_ref.skip_binder().substs;
let pred = self.skip_binders();
let new = pred.subst(tcx, substs);
if new != pred {
ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll)
} else {
self
}
if new != pred { ty::Binder::bind(new).potentially_quantified(tcx) } else { self }
}
}

Expand Down Expand Up @@ -1425,7 +1402,7 @@ impl ToPredicate<'tcx> for PredicateAtom<'tcx> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
debug_assert!(!self.has_escaping_bound_vars(), "escaping bound vars for {:?}", self);
tcx.mk_predicate(PredicateKind::Atom(self))
tcx.mk_predicate(PredicateKind::ForAll(Binder::dummy(self)))
}
}

Expand All @@ -1450,27 +1427,25 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitPredicate<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
.map_bound(|value| PredicateAtom::Trait(value, self.constness))
.potentially_quantified(tcx, PredicateKind::ForAll)
.potentially_quantified(tcx)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::RegionOutlives)
.potentially_quantified(tcx, PredicateKind::ForAll)
self.map_bound(PredicateAtom::RegionOutlives).potentially_quantified(tcx)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::TypeOutlives)
.potentially_quantified(tcx, PredicateKind::ForAll)
self.map_bound(PredicateAtom::TypeOutlives).potentially_quantified(tcx)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx, PredicateKind::ForAll)
self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx)
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2069,7 +2069,6 @@ define_print_and_forward_display! {

ty::Predicate<'tcx> {
match self.kind() {
&ty::PredicateKind::Atom(atom) => p!(print(atom)),
ty::PredicateKind::ForAll(binder) => p!(print(binder)),
}
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::PredicateKind::ForAll(binder) => write!(f, "ForAll({:?})", binder),
ty::PredicateKind::Atom(atom) => write!(f, "{:?}", atom),
}
}
}
Expand Down Expand Up @@ -486,7 +485,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
match self {
ty::PredicateKind::ForAll(binder) => tcx.lift(binder).map(ty::PredicateKind::ForAll),
ty::PredicateKind::Atom(atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
}
}
}
Expand Down
76 changes: 39 additions & 37 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,45 +346,47 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
let infcx = self.selcx.infcx();

match *obligation.predicate.kind() {
ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
// Evaluation will discard candidates using the leak check.
// This means we need to pass it the bound version of our
// predicate.
ty::PredicateAtom::Trait(trait_ref, _constness) => {
let trait_obligation = obligation.with(binder.rebind(trait_ref));

self.process_trait_obligation(
obligation,
trait_obligation,
&mut pending_obligation.stalled_on,
)
}
ty::PredicateAtom::Projection(data) => {
let project_obligation = obligation.with(binder.rebind(data));
ty::PredicateKind::ForAll(binder) if binder.skip_binder().has_escaping_bound_vars() => {
match binder.skip_binder() {
// Evaluation will discard candidates using the leak check.
// This means we need to pass it the bound version of our
// predicate.
ty::PredicateAtom::Trait(trait_ref, _constness) => {
let trait_obligation = obligation.with(binder.rebind(trait_ref));

self.process_trait_obligation(
obligation,
trait_obligation,
&mut pending_obligation.stalled_on,
)
}
ty::PredicateAtom::Projection(data) => {
let project_obligation = obligation.with(binder.rebind(data));

self.process_projection_obligation(
project_obligation,
&mut pending_obligation.stalled_on,
)
}
ty::PredicateAtom::RegionOutlives(_)
| ty::PredicateAtom::TypeOutlives(_)
| ty::PredicateAtom::WellFormed(_)
| ty::PredicateAtom::ObjectSafe(_)
| ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::Subtype(_)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => {
let pred = infcx.replace_bound_vars_with_placeholders(binder);
ProcessResult::Changed(mk_pending(vec![
obligation.with(pred.to_predicate(self.selcx.tcx())),
]))
}
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk")
self.process_projection_obligation(
project_obligation,
&mut pending_obligation.stalled_on,
)
}
ty::PredicateAtom::RegionOutlives(_)
| ty::PredicateAtom::TypeOutlives(_)
| ty::PredicateAtom::WellFormed(_)
| ty::PredicateAtom::ObjectSafe(_)
| ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::Subtype(_)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => {
let pred = infcx.replace_bound_vars_with_placeholders(binder);
ProcessResult::Changed(mk_pending(vec![
obligation.with(pred.to_predicate(self.selcx.tcx())),
]))
}
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk")
}
}
},
ty::PredicateKind::Atom(atom) => match atom {
}
ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
ty::PredicateAtom::Trait(data, _) => {
let trait_obligation = obligation.with(Binder::dummy(data));

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_traits/src/implied_outlives_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,12 @@ fn compute_implied_outlives_bounds<'tcx>(
implied_bounds.extend(obligations.into_iter().flat_map(|obligation| {
assert!(!obligation.has_escaping_bound_vars());
match obligation.predicate.kind() {
&ty::PredicateKind::ForAll(..) => vec![],
&ty::PredicateKind::Atom(atom) => match atom {
&ty::PredicateKind::ForAll(binder)
if binder.skip_binder().has_escaping_bound_vars() =>
{
vec![]
}
&ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
ty::PredicateAtom::Trait(..)
| ty::PredicateAtom::Subtype(..)
| ty::PredicateAtom::Projection(..)
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1949,10 +1949,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
let predicate = ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, re_root_empty),
));
predicates.insert((
predicate.potentially_quantified(tcx, ty::PredicateKind::ForAll),
span,
));
predicates.insert((predicate.potentially_quantified(tcx), span));
}
}

Expand Down Expand Up @@ -1996,7 +1993,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, region),
))
.potentially_quantified(tcx, ty::PredicateKind::ForAll),
.potentially_quantified(tcx),
lifetime.span,
));
}
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_typeck/src/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate
let mut pred: Vec<String> = predicates
.iter()
.map(|(out_pred, _)| match out_pred.kind() {
ty::PredicateKind::Atom(ty::PredicateAtom::RegionOutlives(p)) => {
p.to_string()
}
ty::PredicateKind::Atom(ty::PredicateAtom::TypeOutlives(p)) => {
p.to_string()
}
err => bug!("unexpected predicate {:?}", err),
ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
ty::PredicateAtom::RegionOutlives(p) => p.to_string(),
ty::PredicateAtom::TypeOutlives(p) => p.to_string(),
err => bug!("unexpected predicate {:?}", err),
},
})
.collect();
pred.sort();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: cannot specialize on `ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))`
error: cannot specialize on `ForAll(Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))))`
--> $DIR/repeated_projection_type.rs:19:1
|
LL | / impl<I, V: Id<This = (I,)>> X for V {
Expand Down
14 changes: 8 additions & 6 deletions src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
.filter(|p| !p.is_global())
.filter_map(|obligation| {
// Note that we do not want to deal with qualified predicates here.
if let ty::PredicateKind::Atom(ty::PredicateAtom::Trait(pred, _)) = obligation.predicate.kind() {
if pred.def_id() == sized_trait {
return None;
let ty::PredicateKind::ForAll(binder) = obligation.predicate.kind();
match binder.skip_binder() {
ty::PredicateAtom::Trait(pred, _) if !binder.has_escaping_bound_vars() => {
if pred.def_id() == sized_trait {
return None;
}
Some(pred)
}
Some(pred)
} else {
None
_ => None,
}
})
.collect::<Vec<_>>();
Expand Down