Skip to content

Commit

Permalink
Merge pull request #142 from scalexm/wc-atom
Browse files Browse the repository at this point in the history
Refactor `WhereClauseAtom` into `WhereClause`.
  • Loading branch information
nikomatsakis authored May 28, 2018
2 parents 733f12f + 5607fc9 commit d67e569
Show file tree
Hide file tree
Showing 11 changed files with 448 additions and 419 deletions.
53 changes: 44 additions & 9 deletions chalk-parse/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use lalrpop_intern::InternedString;
use std::fmt;

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Span {
pub lo: usize,
pub hi: usize,
Expand All @@ -13,17 +13,20 @@ impl Span {
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Program {
pub items: Vec<Item>
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Item {
StructDefn(StructDefn),
TraitDefn(TraitDefn),
Impl(Impl),
Clause(Clause),
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct StructDefn {
pub name: Identifier,
pub parameter_kinds: Vec<ParameterKind>,
Expand All @@ -32,11 +35,13 @@ pub struct StructDefn {
pub flags: StructFlags,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct StructFlags {
pub external: bool,
pub fundamental: bool,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TraitDefn {
pub name: Identifier,
pub parameter_kinds: Vec<ParameterKind>,
Expand All @@ -45,43 +50,50 @@ pub struct TraitDefn {
pub flags: TraitFlags,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TraitFlags {
pub auto: bool,
pub marker: bool,
pub external: bool,
pub deref: bool,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct AssocTyDefn {
pub name: Identifier,
pub parameter_kinds: Vec<ParameterKind>,
pub bounds: Vec<InlineBound>,
pub where_clauses: Vec<QuantifiedWhereClause>,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ParameterKind {
Ty(Identifier),
Lifetime(Identifier),
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Parameter {
Ty(Ty),
Lifetime(Lifetime),
}

#[derive(Clone, PartialEq, Eq, Debug)]
/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
pub enum InlineBound {
TraitBound(TraitBound),
ProjectionEqBound(ProjectionEqBound),
}

#[derive(Clone, PartialEq, Eq, Debug)]
/// Represents a trait bound on e.g. a type or type parameter.
/// Does not know anything about what it's binding.
pub struct TraitBound {
pub trait_name: Identifier,
pub args_no_self: Vec<Parameter>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
/// Represents a projection equality bound on e.g. a type or type parameter.
/// Does not know anything about what it's binding.
pub struct ProjectionEqBound {
Expand All @@ -91,7 +103,7 @@ pub struct ProjectionEqBound {
pub value: Ty,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Kind {
Ty,
Lifetime,
Expand Down Expand Up @@ -130,19 +142,22 @@ impl Kinded for Parameter {
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Impl {
pub parameter_kinds: Vec<ParameterKind>,
pub trait_ref: PolarizedTraitRef,
pub where_clauses: Vec<QuantifiedWhereClause>,
pub assoc_ty_values: Vec<AssocTyValue>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct AssocTyValue {
pub name: Identifier,
pub parameter_kinds: Vec<ParameterKind>,
pub value: Ty,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Ty {
Id {
name: Identifier,
Expand All @@ -163,28 +178,33 @@ pub enum Ty {
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Lifetime {
Id {
name: Identifier,
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ProjectionTy {
pub trait_ref: TraitRef,
pub name: Identifier,
pub args: Vec<Parameter>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct UnselectedProjectionTy {
pub name: Identifier,
pub args: Vec<Parameter>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TraitRef {
pub trait_name: Identifier,
pub args: Vec<Parameter>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum PolarizedTraitRef {
Positive(TraitRef),
Negative(TraitRef),
Expand All @@ -200,45 +220,60 @@ impl PolarizedTraitRef {
}
}

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Identifier {
pub str: InternedString,
pub span: Span,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum WhereClause {
Implemented { trait_ref: TraitRef },
Normalize { projection: ProjectionTy, ty: Ty },
ProjectionEq { projection: ProjectionTy, ty: Ty },
TyWellFormed { ty: Ty },
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum DomainGoal {
Holds { where_clause: WhereClause },
Normalize { projection: ProjectionTy, ty: Ty },
TraitRefWellFormed { trait_ref: TraitRef },
TyWellFormed { ty: Ty },
TyFromEnv { ty: Ty },
TraitRefFromEnv { trait_ref: TraitRef },
UnifyTys { a: Ty, b: Ty },
UnifyLifetimes { a: Lifetime, b: Lifetime },
TraitInScope { trait_name: Identifier },
Derefs { source: Ty, target: Ty },
IsLocal { ty: Ty },
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum LeafGoal {
DomainGoal { goal: DomainGoal },
UnifyTys { a: Ty, b: Ty },
UnifyLifetimes { a: Lifetime, b: Lifetime },
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct QuantifiedWhereClause {
pub parameter_kinds: Vec<ParameterKind>,
pub where_clause: WhereClause,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Field {
pub name: Identifier,
pub ty: Ty,
}

#[derive(Clone, PartialEq, Eq, Debug)]
/// This allows users to add arbitrary `A :- B` clauses into the
/// logic; it has no equivalent in Rust, but it's useful for testing.
pub struct Clause {
pub parameter_kinds: Vec<ParameterKind>,
pub consequence: WhereClause,
pub consequence: DomainGoal,
pub conditions: Vec<Box<Goal>>,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Goal {
ForAll(Vec<ParameterKind>, Box<Goal>),
Exists(Vec<ParameterKind>, Box<Goal>),
Expand All @@ -247,5 +282,5 @@ pub enum Goal {
Not(Box<Goal>),

// Additional kinds of goals:
Leaf(WhereClause),
Leaf(LeafGoal),
}
79 changes: 44 additions & 35 deletions chalk-parse/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ pub Goal: Box<Goal> = {
Goal1: Box<Goal> = {
"forall" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::ForAll(p, g)),
"exists" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::Exists(p, g)),
"if" "(" <w:SemiColon<InlineClause>> ")" "{" <g:Goal> "}" => Box::new(Goal::Implies(w, g)),
"if" "(" <h:SemiColon<InlineClause>> ")" "{" <g:Goal> "}" => Box::new(Goal::Implies(h, g)),
"not" "{" <g:Goal> "}" => Box::new(Goal::Not(g)),
<w:WhereClause> => Box::new(Goal::Leaf(w)),
<leaf:LeafGoal> => Box::new(Goal::Leaf(leaf)),
"(" <Goal> ")",
};

Expand Down Expand Up @@ -199,29 +199,29 @@ Field: Field = {
};

Clause: Clause = {
"forall" <pk:Angle<ParameterKind>> "{" <wc:WhereClause> "if" <g:Comma<Goal1>> "}" => Clause {
"forall" <pk:Angle<ParameterKind>> "{" <dg:DomainGoal> "if" <g:Comma<Goal1>> "}" => Clause {
parameter_kinds: pk,
consequence: wc,
consequence: dg,
conditions: g,
},

"forall" <pk:Angle<ParameterKind>> "{" <wc:WhereClause> "}" => Clause {
"forall" <pk:Angle<ParameterKind>> "{" <dg:DomainGoal> "}" => Clause {
parameter_kinds: pk,
consequence: wc,
consequence: dg,
conditions: vec![],
},
};

InlineClause1: Clause = {
<wc:WhereClause> => Clause {
<dg:DomainGoal> => Clause {
parameter_kinds: vec![],
consequence: wc,
consequence: dg,
conditions: vec![],
},

<wc:WhereClause> ":" "-" <g:Comma<Goal1>> => Clause {
<dg:DomainGoal> ":" "-" <g:Comma<Goal1>> => Clause {
parameter_kinds: vec![],
consequence: wc,
consequence: dg,
conditions: g,
},
};
Expand All @@ -236,29 +236,9 @@ InlineClause: Clause = {
}
};

QuantifiedWhereClauses: Vec<QuantifiedWhereClause> = {
"where" <Comma<QuantifiedWhereClause>>,
() => vec![],
};

WhereClause: WhereClause = {
<t:TraitRef<":">> => WhereClause::Implemented { trait_ref: t },

"WellFormed" "(" <t:Ty> ")" => WhereClause::TyWellFormed { ty: t },

"WellFormed" "(" <t:TraitRef<":">> ")" => WhereClause::TraitRefWellFormed { trait_ref: t },

"FromEnv" "(" <t:Ty> ")" => WhereClause::TyFromEnv { ty: t },

"FromEnv" "(" <t:TraitRef<":">> ")" => WhereClause::TraitRefFromEnv { trait_ref: t },

<a:Ty> "=" <b:Ty> => WhereClause::UnifyTys { a, b },

<a:Lifetime> "=" <b:Lifetime> => WhereClause::UnifyLifetimes { a, b },

// `<T as Foo>::U -> Bar` -- a normalization
"Normalize" "(" <s:ProjectionTy> "->" <t:Ty> ")" => WhereClause::Normalize { projection: s, ty: t },

// `T: Foo<U = Bar>` -- projection equality
<s:Ty> ":" <t:Id> "<" <a:(<Comma<Parameter>> ",")?> <name:Id> <a2:Angle<Parameter>>
"=" <ty:Ty> ">" =>
Expand All @@ -269,11 +249,6 @@ WhereClause: WhereClause = {
let projection = ProjectionTy { trait_ref, name, args: a2 };
WhereClause::ProjectionEq { projection, ty }
},

"InScope" "(" <t:Id> ")" => WhereClause::TraitInScope { trait_name: t },
"Derefs" "(" <source:Ty> "," <target:Ty> ")" => WhereClause::Derefs { source, target },

"IsLocal" "(" <ty:Ty> ")" => WhereClause::IsLocal { ty },
};

QuantifiedWhereClause: QuantifiedWhereClause = {
Expand All @@ -288,6 +263,40 @@ QuantifiedWhereClause: QuantifiedWhereClause = {
},
};

QuantifiedWhereClauses: Vec<QuantifiedWhereClause> = {
"where" <Comma<QuantifiedWhereClause>>,
() => vec![],
};

DomainGoal: DomainGoal = {
<wc: WhereClause> => DomainGoal::Holds { where_clause: wc },

"WellFormed" "(" <t:Ty> ")" => DomainGoal::TyWellFormed { ty: t },

"WellFormed" "(" <t:TraitRef<":">> ")" => DomainGoal::TraitRefWellFormed { trait_ref: t },

"FromEnv" "(" <t:Ty> ")" => DomainGoal::TyFromEnv { ty: t },

"FromEnv" "(" <t:TraitRef<":">> ")" => DomainGoal::TraitRefFromEnv { trait_ref: t },

// `<T as Foo>::U -> Bar` -- a normalization
"Normalize" "(" <s:ProjectionTy> "->" <t:Ty> ")" => DomainGoal::Normalize { projection: s, ty: t },

"InScope" "(" <t:Id> ")" => DomainGoal::TraitInScope { trait_name: t },

"Derefs" "(" <source:Ty> "," <target:Ty> ")" => DomainGoal::Derefs { source, target },

"IsLocal" "(" <ty:Ty> ")" => DomainGoal::IsLocal { ty },
};

LeafGoal: LeafGoal = {
<dg: DomainGoal> => LeafGoal::DomainGoal { goal: dg },

<a:Ty> "=" <b:Ty> => LeafGoal::UnifyTys { a, b },

<a:Lifetime> "=" <b:Lifetime> => LeafGoal::UnifyLifetimes { a, b },
};

TraitRef<S>: TraitRef = {
<s:Ty> S <t:Id> <a:Angle<Parameter>> => {
let mut args = vec![Parameter::Ty(s)];
Expand Down
Loading

0 comments on commit d67e569

Please sign in to comment.