Skip to content

[chalkify] Small refactoring and WF/FromEnv rules for types #51433

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 4 commits into from
Jun 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
45 changes: 35 additions & 10 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,16 +1382,46 @@ impl_stable_hash_for!(enum infer::canonical::Certainty {
Proven, Ambiguous
});

impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClauseAtom<'tcx> {
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClause<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::WhereClauseAtom::*;
use traits::WhereClause::*;

mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
TypeOutlives(ty_outlives) => ty_outlives.hash_stable(hcx, hasher),
RegionOutlives(region_outlives) => region_outlives.hash_stable(hcx, hasher),
}
}
}

impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WellFormed<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::WellFormed::*;

mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
Ty(ty) => ty.hash_stable(hcx, hasher),
}
}
}

impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::FromEnv<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::FromEnv::*;

mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
Ty(ty) => ty.hash_stable(hcx, hasher),
}
}
}
Expand All @@ -1404,15 +1434,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx>

mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Holds(where_clause) |
WellFormed(where_clause) |
FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher),

WellFormedTy(ty) => ty.hash_stable(hcx, hasher),
Holds(wc) => wc.hash_stable(hcx, hasher),
WellFormed(wf) => wf.hash_stable(hcx, hasher),
FromEnv(from_env) => from_env.hash_stable(hcx, hasher),
Normalize(projection) => projection.hash_stable(hcx, hasher),
FromEnvTy(ty) => ty.hash_stable(hcx, hasher),
RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher),
TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher),
}
}
}
Expand Down
46 changes: 29 additions & 17 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,29 +269,41 @@ pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;

/// The following types:
/// * `WhereClauseAtom`
/// * `WhereClause`
/// * `WellFormed`
/// * `FromEnv`
/// * `DomainGoal`
/// * `Goal`
/// * `Clause`
/// are used for representing the trait system in the form of
/// logic programming clauses. They are part of the interface
/// for the chalk SLG solver.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum WhereClauseAtom<'tcx> {
pub enum WhereClause<'tcx> {
Implemented(ty::TraitPredicate<'tcx>),
ProjectionEq(ty::ProjectionPredicate<'tcx>),
RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum WellFormed<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum FromEnv<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum DomainGoal<'tcx> {
Holds(WhereClauseAtom<'tcx>),
WellFormed(WhereClauseAtom<'tcx>),
FromEnv(WhereClauseAtom<'tcx>),
WellFormedTy(Ty<'tcx>),
Holds(WhereClause<'tcx>),
WellFormed(WellFormed<'tcx>),
FromEnv(FromEnv<'tcx>),
Normalize(ty::ProjectionPredicate<'tcx>),
FromEnvTy(Ty<'tcx>),
RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
}

pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
Expand All @@ -314,27 +326,27 @@ pub enum Goal<'tcx> {

pub type Goals<'tcx> = &'tcx Slice<Goal<'tcx>>;

impl<'tcx> DomainGoal<'tcx> {
pub fn into_goal(self) -> Goal<'tcx> {
Goal::DomainGoal(self)
}
}

impl<'tcx> Goal<'tcx> {
pub fn from_poly_domain_goal<'a>(
domain_goal: PolyDomainGoal<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
) -> Goal<'tcx> {
match domain_goal.no_late_bound_regions() {
Some(p) => p.into(),
Some(p) => p.into_goal(),
None => Goal::Quantified(
QuantifierKind::Universal,
domain_goal.map_bound(|p| tcx.mk_goal(Goal::from(p)))
domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
),
}
}
}

impl<'tcx> From<DomainGoal<'tcx>> for Goal<'tcx> {
fn from(domain_goal: DomainGoal<'tcx>) -> Self {
Goal::DomainGoal(domain_goal)
}
}

/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
/// Harrop Formulas".
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
Expand Down
103 changes: 73 additions & 30 deletions src/librustc/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,33 +405,50 @@ BraceStructTypeFoldableImpl! {
} where T: TypeFoldable<'tcx>
}

impl<'tcx> fmt::Display for traits::WhereClauseAtom<'tcx> {
impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use traits::WhereClauseAtom::*;
use traits::WhereClause::*;

match self {
Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
}
}
}

impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use traits::WellFormed::*;

match self {
Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
Ty(ty) => write!(fmt, "WellFormed({})", ty),
}
}
}

impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use traits::FromEnv::*;

match self {
Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
Ty(ty) => write!(fmt, "FromEnv({})", ty),
}
}
}

impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use traits::DomainGoal::*;
use traits::WhereClauseAtom::*;

match self {
Holds(wc) => write!(fmt, "{}", wc),
WellFormed(Implemented(trait_ref)) => write!(fmt, "WellFormed({})", trait_ref),
WellFormed(ProjectionEq(projection)) => write!(fmt, "WellFormed({})", projection),
FromEnv(Implemented(trait_ref)) => write!(fmt, "FromEnv({})", trait_ref),
FromEnv(ProjectionEq(projection)) => write!(fmt, "FromEnv({})", projection),
WellFormedTy(ty) => write!(fmt, "WellFormed({})", ty),
WellFormed(wf) => write!(fmt, "{}", wf),
FromEnv(from_env) => write!(fmt, "{}", from_env),
Normalize(projection) => write!(fmt, "Normalize({})", projection),
FromEnvTy(ty) => write!(fmt, "FromEnv({})", ty),
RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
}
}
}
Expand Down Expand Up @@ -506,44 +523,70 @@ impl<'tcx> fmt::Display for traits::Clause<'tcx> {
}

EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> {
(traits::WhereClauseAtom::Implemented)(trait_ref),
(traits::WhereClauseAtom::ProjectionEq)(projection),
impl<'tcx> TypeFoldable<'tcx> for traits::WhereClause<'tcx> {
(traits::WhereClause::Implemented)(trait_ref),
(traits::WhereClause::ProjectionEq)(projection),
(traits::WhereClause::TypeOutlives)(ty_outlives),
(traits::WhereClause::RegionOutlives)(region_outlives),
}
}

EnumLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for traits::WhereClause<'a> {
type Lifted = traits::WhereClause<'tcx>;
(traits::WhereClause::Implemented)(trait_ref),
(traits::WhereClause::ProjectionEq)(projection),
(traits::WhereClause::TypeOutlives)(ty_outlives),
(traits::WhereClause::RegionOutlives)(region_outlives),
}
}

EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::WellFormed<'tcx> {
(traits::WellFormed::Trait)(trait_ref),
(traits::WellFormed::Ty)(ty),
}
}

EnumLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for traits::WellFormed<'a> {
type Lifted = traits::WellFormed<'tcx>;
(traits::WellFormed::Trait)(trait_ref),
(traits::WellFormed::Ty)(ty),
}
}

EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::FromEnv<'tcx> {
(traits::FromEnv::Trait)(trait_ref),
(traits::FromEnv::Ty)(ty),
}
}

EnumLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for traits::WhereClauseAtom<'a> {
type Lifted = traits::WhereClauseAtom<'tcx>;
(traits::WhereClauseAtom::Implemented)(trait_ref),
(traits::WhereClauseAtom::ProjectionEq)(projection),
impl<'a, 'tcx> Lift<'tcx> for traits::FromEnv<'a> {
type Lifted = traits::FromEnv<'tcx>;
(traits::FromEnv::Trait)(trait_ref),
(traits::FromEnv::Ty)(ty),
}
}

EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
(traits::DomainGoal::Holds)(wc),
(traits::DomainGoal::WellFormed)(wc),
(traits::DomainGoal::FromEnv)(wc),
(traits::DomainGoal::WellFormedTy)(ty),
(traits::DomainGoal::WellFormed)(wf),
(traits::DomainGoal::FromEnv)(from_env),
(traits::DomainGoal::Normalize)(projection),
(traits::DomainGoal::FromEnvTy)(ty),
(traits::DomainGoal::RegionOutlives)(predicate),
(traits::DomainGoal::TypeOutlives)(predicate),
}
}

EnumLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for traits::DomainGoal<'a> {
type Lifted = traits::DomainGoal<'tcx>;
(traits::DomainGoal::Holds)(wc),
(traits::DomainGoal::WellFormed)(wc),
(traits::DomainGoal::FromEnv)(wc),
(traits::DomainGoal::WellFormedTy)(ty),
(traits::DomainGoal::WellFormed)(wf),
(traits::DomainGoal::FromEnv)(from_env),
(traits::DomainGoal::Normalize)(projection),
(traits::DomainGoal::FromEnvTy)(ty),
(traits::DomainGoal::RegionOutlives)(predicate),
(traits::DomainGoal::TypeOutlives)(predicate),
}
}

Expand Down
42 changes: 25 additions & 17 deletions src/librustc_traits/chalk_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@ use rustc::infer::canonical::{
Canonical, CanonicalVarValues, Canonicalize, QueryRegionConstraint, QueryResult,
};
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use rustc::traits::{DomainGoal, ExClauseFold, ExClauseLift, Goal, ProgramClause, QuantifierKind};
use rustc::traits::{
WellFormed,
FromEnv,
DomainGoal,
ExClauseFold,
ExClauseLift,
Goal,
ProgramClause,
QuantifierKind
};
use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc::ty::subst::Kind;
use rustc::ty::{self, TyCtxt};
Expand Down Expand Up @@ -314,43 +323,42 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
_environment: &ty::ParamEnv<'tcx>,
goal: &DomainGoal<'tcx>,
) -> Vec<ProgramClause<'tcx>> {
use rustc::traits::DomainGoal::*;
use rustc::traits::WhereClauseAtom::*;
use rustc::traits::WhereClause::*;

match goal {
Holds(Implemented(_trait_predicate)) => {
DomainGoal::Holds(Implemented(_trait_predicate)) => {
// These come from:
//
// - Trait definitions (implied bounds)
// - Implementations of the trait itself
panic!()
}

Holds(ProjectionEq(_projection_predicate)) => {
DomainGoal::Holds(ProjectionEq(_projection_predicate)) => {
// These come from:
panic!()
}

WellFormed(Implemented(_trait_predicate)) => {
// These come from -- the trait decl.
DomainGoal::Holds(RegionOutlives(_region_outlives)) => {
panic!()
}

WellFormed(ProjectionEq(_projection_predicate)) => panic!(),

FromEnv(Implemented(_trait_predicate)) => panic!(),

FromEnv(ProjectionEq(_projection_predicate)) => panic!(),
DomainGoal::Holds(TypeOutlives(_type_outlives)) => {
panic!()
}

WellFormedTy(_ty) => panic!(),
DomainGoal::WellFormed(WellFormed::Trait(_trait_predicate)) => {
// These come from -- the trait decl.
panic!()
}

FromEnvTy(_ty) => panic!(),
DomainGoal::WellFormed(WellFormed::Ty(_ty)) => panic!(),

RegionOutlives(_region_outlives) => panic!(),
DomainGoal::FromEnv(FromEnv::Trait(_trait_predicate)) => panic!(),

TypeOutlives(_type_outlives) => panic!(),
DomainGoal::FromEnv(FromEnv::Ty(_ty)) => panic!(),

Normalize(_) => panic!(),
DomainGoal::Normalize(_) => panic!(),
}
}

Expand Down
Loading