Skip to content

Refactor WhereClauseAtom into WhereClause. #142

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 2 commits into from
May 28, 2018
Merged
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
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,
@@ -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>,
@@ -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>,
@@ -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 {
@@ -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,
@@ -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,
@@ -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),
@@ -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>),
@@ -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
@@ -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> ")",
};

@@ -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,
},
};
@@ -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> ">" =>
@@ -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 = {
@@ -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)];
Loading