Skip to content

Commit

Permalink
Generalize the kinds of predicates we stash in the generator interior
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 28, 2022
1 parent 87d1317 commit 8e1cabc
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 133 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,19 +381,19 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVaria
}
}

impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::ProjectionPredicate<'tcx>> {
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::GeneratorPredicate<'tcx>> {
fn decode(decoder: &mut D) -> &'tcx Self {
let len = decoder.read_usize();
decoder.tcx().mk_projection_predicates(
(0..len).map::<ty::ProjectionPredicate<'tcx>, _>(|_| Decodable::decode(decoder)),
decoder.tcx().mk_generator_predicates(
(0..len).map::<ty::GeneratorPredicate<'tcx>, _>(|_| Decodable::decode(decoder)),
)
}
}

impl_decodable_via_ref! {
&'tcx ty::TypeckResults<'tcx>,
&'tcx ty::List<Ty<'tcx>>,
&'tcx ty::List<ty::ProjectionPredicate<'tcx>>,
&'tcx ty::List<ty::GeneratorPredicate<'tcx>>,
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
&'tcx Allocation,
&'tcx mir::Body<'tcx>,
Expand Down Expand Up @@ -514,7 +514,7 @@ macro_rules! impl_binder_encode_decode {

impl_binder_encode_decode! {
&'tcx ty::List<Ty<'tcx>>,
&'tcx ty::List<ty::ProjectionPredicate<'tcx>>,
&'tcx ty::List<ty::GeneratorPredicate<'tcx>>,
ty::GeneratorWitnessInner<'tcx>,
ty::FnSig<'tcx>,
ty::ExistentialPredicate<'tcx>,
Expand Down
30 changes: 15 additions & 15 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ use crate::ty::TyKind::*;
use crate::ty::{
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
FloatVid, GeneratorWitnessInner, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar,
IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
ProjectionPredicate, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
FloatVid, GeneratorPredicate, GeneratorWitnessInner, GenericParamDefKind, InferConst, InferTy,
IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner,
PredicateKind, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
TyS, TyVar, TyVid, TypeAndMut, UintTy,
};
use rustc_ast as ast;
use rustc_attr as attr;
Expand Down Expand Up @@ -103,7 +103,7 @@ pub struct CtxtInterners<'tcx> {
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
region: InternedSet<'tcx, RegionKind>,
projection_predicates: InternedSet<'tcx, List<ProjectionPredicate<'tcx>>>,
generator_predicates: InternedSet<'tcx, List<GeneratorPredicate<'tcx>>>,
poly_existential_predicates:
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
Expand Down Expand Up @@ -131,7 +131,7 @@ impl<'tcx> CtxtInterners<'tcx> {
type_list: Default::default(),
substs: Default::default(),
region: Default::default(),
projection_predicates: Default::default(),
generator_predicates: Default::default(),
poly_existential_predicates: Default::default(),
canonical_var_infos: Default::default(),
predicate: Default::default(),
Expand Down Expand Up @@ -1657,7 +1657,7 @@ nop_lift! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}

nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
nop_list_lift! {projection_predicates; ProjectionPredicate<'a> => ProjectionPredicate<'tcx>}
nop_list_lift! {generator_predicates; GeneratorPredicate<'a> => GeneratorPredicate<'tcx>}
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
Expand Down Expand Up @@ -2119,7 +2119,7 @@ slice_interners!(
type_list: _intern_type_list(Ty<'tcx>),
substs: _intern_substs(GenericArg<'tcx>),
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
projection_predicates: _intern_projection_predicates(ProjectionPredicate<'tcx>),
generator_predicates: _intern_generator_predicates(GeneratorPredicate<'tcx>),
poly_existential_predicates:
_intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>),
predicates: _intern_predicates(Predicate<'tcx>),
Expand Down Expand Up @@ -2517,14 +2517,14 @@ impl<'tcx> TyCtxt<'tcx> {
Place { local: place.local, projection: self.intern_place_elems(&projection) }
}

pub fn intern_projection_predicates(
pub fn intern_generator_predicates(
self,
predicates: &[ProjectionPredicate<'tcx>],
) -> &'tcx List<ProjectionPredicate<'tcx>> {
predicates: &[GeneratorPredicate<'tcx>],
) -> &'tcx List<GeneratorPredicate<'tcx>> {
if predicates.is_empty() {
List::empty()
} else {
self._intern_projection_predicates(predicates)
self._intern_generator_predicates(predicates)
}
}

Expand Down Expand Up @@ -2602,13 +2602,13 @@ impl<'tcx> TyCtxt<'tcx> {
})
}

pub fn mk_projection_predicates<
I: InternAs<[ProjectionPredicate<'tcx>], &'tcx List<ProjectionPredicate<'tcx>>>,
pub fn mk_generator_predicates<
I: InternAs<[GeneratorPredicate<'tcx>], &'tcx List<GeneratorPredicate<'tcx>>>,
>(
self,
iter: I,
) -> I::Output {
iter.intern_with(|xs| self.intern_projection_predicates(xs))
iter.intern_with(|xs| self.intern_generator_predicates(xs))
}

pub fn mk_poly_existential_predicates<
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ impl FlagComputation {
&ty::GeneratorWitness(inner) => {
self.bound_computation(inner, |computation, inner| {
computation.add_tys(&inner.tys);
for predicate in inner.structural_predicates {
computation.add_predicate_atom(ty::PredicateKind::Projection(predicate));
for predicate in inner.predicates {
computation.add_predicate_atom(predicate.to_predicate_atom());
}
});
}
Expand Down
50 changes: 36 additions & 14 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,8 @@ pub struct ImplHeader<'tcx> {
pub predicates: Vec<Predicate<'tcx>>,
}

#[derive(
Copy,
Clone,
PartialEq,
Eq,
Hash,
TyEncodable,
TyDecodable,
HashStable,
Debug,
TypeFoldable
)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(TyEncodable, TyDecodable, HashStable, Debug, TypeFoldable)]
pub enum ImplPolarity {
/// `impl Trait for Type`
Positive,
Expand Down Expand Up @@ -225,7 +215,8 @@ pub enum Visibility {
Invisible,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Hash, HashStable, TyEncodable, TyDecodable)]
pub enum BoundConstness {
/// `T: Trait`
NotConst,
Expand Down Expand Up @@ -744,7 +735,7 @@ impl<'tcx> Predicate<'tcx> {
}
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>,
Expand Down Expand Up @@ -997,6 +988,37 @@ impl<'tcx> Predicate<'tcx> {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Hash, HashStable, TyEncodable, TyDecodable, TypeFoldable)]
pub enum GeneratorPredicate<'tcx> {
Trait(TraitPredicate<'tcx>),
RegionOutlives(RegionOutlivesPredicate<'tcx>),
TypeOutlives(TypeOutlivesPredicate<'tcx>),
Projection(ProjectionPredicate<'tcx>),
}

impl<'tcx> GeneratorPredicate<'tcx> {
pub fn to_predicate_atom(self) -> PredicateKind<'tcx> {
match self {
GeneratorPredicate::Trait(p) => PredicateKind::Trait(p),
GeneratorPredicate::RegionOutlives(p) => PredicateKind::RegionOutlives(p),
GeneratorPredicate::TypeOutlives(p) => PredicateKind::TypeOutlives(p),
GeneratorPredicate::Projection(p) => PredicateKind::Projection(p),
}
}
}

impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, GeneratorPredicate<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
match self.skip_binder() {
GeneratorPredicate::Trait(p) => self.rebind(p).to_predicate(tcx),
GeneratorPredicate::RegionOutlives(p) => self.rebind(p).to_predicate(tcx),
GeneratorPredicate::TypeOutlives(p) => self.rebind(p).to_predicate(tcx),
GeneratorPredicate::Projection(p) => self.rebind(p).to_predicate(tcx),
}
}
}

/// Represents the bounds declared on a particular set of type
/// parameters. Should eventually be generalized into a flag list of
/// where-clauses. You can obtain an `InstantiatedPredicates` list from a
Expand Down
48 changes: 42 additions & 6 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,16 +347,13 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorWitnessInner<'tcx> {
b: ty::GeneratorWitnessInner<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorWitnessInner<'tcx>> {
assert_eq!(a.tys.len(), b.tys.len());
assert_eq!(a.structural_predicates.len(), b.structural_predicates.len());
assert_eq!(a.predicates.len(), b.predicates.len());
Ok(ty::GeneratorWitnessInner {
tys: relation
.tcx()
.mk_type_list(a.tys.iter().zip(b.tys).map(|(a, b)| relation.relate(a, b)))?,
structural_predicates: relation.tcx().mk_projection_predicates(
a.structural_predicates
.iter()
.zip(b.structural_predicates)
.map(|(a, b)| relation.relate(a, b)),
predicates: relation.tcx().mk_generator_predicates(
a.predicates.iter().zip(b.predicates).map(|(a, b)| relation.relate(a, b)),
)?,
})
}
Expand Down Expand Up @@ -860,6 +857,45 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
}
}

impl<'tcx> Relate<'tcx> for ty::GeneratorPredicate<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::GeneratorPredicate<'tcx>,
b: ty::GeneratorPredicate<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorPredicate<'tcx>> {
Ok(match (a, b) {
(ty::GeneratorPredicate::Trait(a), ty::GeneratorPredicate::Trait(b)) => {
ty::GeneratorPredicate::Trait(relation.relate(a, b)?)
}
(
ty::GeneratorPredicate::RegionOutlives(a),
ty::GeneratorPredicate::RegionOutlives(b),
) => ty::GeneratorPredicate::RegionOutlives(relation.relate(a, b)?),
(ty::GeneratorPredicate::TypeOutlives(a), ty::GeneratorPredicate::TypeOutlives(b)) => {
ty::GeneratorPredicate::TypeOutlives(relation.relate(a, b)?)
}
(ty::GeneratorPredicate::Projection(a), ty::GeneratorPredicate::Projection(b)) => {
ty::GeneratorPredicate::Projection(relation.relate(a, b)?)
}
_ => bug!("cannot relate {:?} and {:?}", a, b),
})
}
}

impl<'tcx, A, B> Relate<'tcx> for ty::OutlivesPredicate<A, B>
where
A: Relate<'tcx>,
B: Relate<'tcx>,
{
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::OutlivesPredicate<A, B>,
b: ty::OutlivesPredicate<A, B>,
) -> RelateResult<'tcx, Self> {
Ok(ty::OutlivesPredicate(relation.relate(a.0, b.0)?, relation.relate(a.1, b.1)?))
}
}

///////////////////////////////////////////////////////////////////////////
// Error handling

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,12 +908,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
}
}

impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ProjectionPredicate<'tcx>> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::GeneratorPredicate<'tcx>> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projection_predicates(v))
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_generator_predicates(v))
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2313,5 +2313,5 @@ impl<'tcx> VarianceDiagInfo<'tcx> {
#[derive(TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
pub struct GeneratorWitnessInner<'tcx> {
pub tys: &'tcx List<Ty<'tcx>>,
pub structural_predicates: &'tcx List<ty::ProjectionPredicate<'tcx>>,
pub predicates: &'tcx List<ty::GeneratorPredicate<'tcx>>,
}
1 change: 1 addition & 0 deletions compiler/rustc_monomorphize/src/polymorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
self.visit_child_body(def_id, substs);
ControlFlow::CONTINUE
}
ty::GeneratorWitness(inner) => inner.map_bound(|inner| inner.tys).visit_with(self),
ty::Param(param) => {
debug!(?param);
self.unused_parameters.clear(param.index);
Expand Down
Loading

0 comments on commit 8e1cabc

Please sign in to comment.