flp-0.1.0.0: src/Language/Rust/Syntax/AST.hs
{-|
Module : Language.Rust.Syntax.AST
Description : Non-token AST definitions
Copyright : (c) Alec Theriault, 2017-2018
License : BSD-style
Maintainer : alec.theriault@gmail.com
Stability : experimental
Portability : GHC
-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
module Language.Rust.Syntax.AST (
-- ** Top level
SourceFile(..),
-- ** General
Mutability(..),
Unsafety(..),
Arg(..),
FnDecl(..),
-- ** Paths
Path(..),
PathParameters(..),
PathSegment(..),
QSelf(..),
-- ** Attributes
Attribute(..),
AttrStyle(..),
-- ** Literals
Lit(..),
byteStr,
Suffix(..),
suffix,
IntRep(..),
StrStyle(..),
-- ** Expressions
Expr(..),
Abi(..),
Arm(..),
UnOp(..),
BinOp(..),
Label(..),
CaptureBy(..),
Movability(..),
Field(..),
RangeLimits(..),
-- ** Types and lifetimes
Ty(..),
Generics(..),
Lifetime(..),
LifetimeDef(..),
TyParam(..),
TyParamBound(..),
partitionTyParamBounds,
WhereClause(..),
whereClause,
WherePredicate(..),
PolyTraitRef(..),
TraitRef(..),
TraitBoundModifier(..),
-- ** Patterns
Pat(..),
BindingMode(..),
FieldPat(..),
-- ** Statements
Stmt(..),
-- ** Items
Item(..),
ForeignItem(..),
ImplItem(..),
TraitItem(..),
Defaultness(..),
ImplPolarity(..),
StructField(..),
Variant(..),
VariantData(..),
UseTree(..),
Visibility(..),
Constness(..),
MethodSig(..),
-- ** Blocks
Block(..),
-- ** Token trees
TokenTree(..),
TokenStream(..),
unconsTokenStream,
Nonterminal(..),
Mac(..),
MacStmtStyle(..),
) where
import Language.Rust.Data.Ident ( Ident, Name )
import Language.Rust.Data.Position
import {-# SOURCE #-} Language.Rust.Syntax.Token ( Delim, Token )
import GHC.Generics ( Generic, Generic1 )
import Control.DeepSeq ( NFData )
import Data.Data ( Data )
import Data.Typeable ( Typeable )
import Data.Char ( ord )
import Data.List ( partition )
import Language.Rust.Parser.NonEmpty ( NonEmpty(..) )
import Data.Semigroup as Sem ( Semigroup(..) )
import Data.Word ( Word8 )
-- | ABIs support by Rust's foreign function interface (@syntax::abi::Abi@). Note that of these,
-- only 'Rust', 'C', 'System', 'RustIntrinsic', 'RustCall', and 'PlatformIntrinsic' and 'Unadjusted'
-- are cross-platform - all the rest are platform-specific.
--
-- Example: @\"C\"@ as in @extern \"C\" fn foo(x: i32);@
data Abi
-- Platform-specific ABIs
= Cdecl
| Stdcall
| Fastcall
| Vectorcall
| Aapcs
| Win64
| SysV64
| PtxKernel
| Msp430Interrupt
| X86Interrupt
-- Cross-platform ABIs
| Rust
| C
| System
| RustIntrinsic
| RustCall
| PlatformIntrinsic
| Unadjusted
deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic, NFData)
-- | An argument in a function header (@syntax::ast::Arg@, except with @SelfKind@ and @ExplicitSelf@
-- inlined).
--
-- Example: @x: usize@, @self@, @mut self@, @&self@, @&'lt mut self@, @mut self: Foo@ as in
--
-- @
-- trait Foo {
-- // Regular argument
-- fn new(x: usize) -> Foo;
--
-- // Self argument, by value
-- fn foo(self) -> i32;
-- fn bar(mut self);
--
-- // Self argument, by reference
-- fn baz(&self) -> Bar\<'lt\>;
-- fn qux(&'lt mut self) -> Bar\<'lt\>;
--
-- // Explicit self argument
-- fn quux(mut self: Foo);
-- }
-- @
data Arg a
= Arg (Maybe (Pat a)) (Ty a) a -- ^ Regular argument
| SelfValue Mutability a -- ^ Self argument, by value
| SelfRegion (Maybe (Lifetime a)) Mutability a -- ^ Self argument, by reference
| SelfExplicit (Ty a) Mutability a -- ^ Explicit self argument
deriving (Eq, Ord, Show, Functor, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Arg a) where
spanOf (Arg _ _ s) = spanOf s
spanOf (SelfValue _ s) = spanOf s
spanOf (SelfRegion _ _ s) = spanOf s
spanOf (SelfExplicit _ _ s) = spanOf s
-- | An arm of a 'Match' expression (@syntax::ast::Arm@). An arm has at least one patten, possibly a
-- guard expression, and a body expression.
--
-- Example: @n if n % 4 == 3 => { println!("{} % 4 = 3", n) }@ as in
--
-- @
-- match n {
-- n if n % 4 == 3 => { println!("{} % 4 = 3", n) }
-- n if n % 4 == 1 => { println!("{} % 4 = 1", n) }
-- _ => println!("{} % 2 = 0", n)
-- }
-- @
data Arm a = Arm [Attribute a] (NonEmpty (Pat a)) (Maybe (Expr a)) (Expr a) a
deriving (Eq, Ord, Show, Functor, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Arm a) where spanOf (Arm _ _ _ _ s) = spanOf s
-- | 'Attribute's are annotations for other AST nodes (@syntax::ast::Attribute@). Note that
-- doc-comments are promoted to attributes.
--
-- Example: @#[derive(Copy,Clone)]@ as in
--
-- @
-- #[derive(Clone, Copy)]
-- struct Complex { re: f32, im: f32 }
-- @
data Attribute a
-- | Regular attributes of the form @#[...]@
= Attribute AttrStyle (Path a) TokenStream a
-- | Doc comment attributes. The 'Bool' argument identifies if the comment is inline or not, and
-- the 'Name' contains the actual doc comment content.
| SugaredDoc AttrStyle Bool Name a
deriving (Eq, Ord, Show, Functor, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Attribute a) where
spanOf (Attribute _ _ _ s) = spanOf s
spanOf (SugaredDoc _ _ _ s) = spanOf s
-- | Distinguishes between attributes that are associated with the node that follows them and
-- attributes that are associated with the node that contains them (@syntax::ast::AttrStyle@).
-- These two cases need to be distinguished only for pretty printing - they are otherwise
-- fundamentally equivalent.
--
-- Example: @#[repr(C)]@ is an outer attribute while @#![feature(slice_patterns)]@ is an inner one
data AttrStyle = Outer | Inner deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Binary operators, used in the 'Binary' and 'AssignOp' constructors of 'Expr'
-- (@syntax::ast::BinOp@).
--
-- Example: @+@ as in @1 + 1@ or @1 += 1@
data BinOp
= AddOp -- ^ @+@ operator (addition)
| SubOp -- ^ @-@ operator (subtraction)
| MulOp -- ^ @*@ operator (multiplication)
| DivOp -- ^ @/@ operator (division)
| RemOp -- ^ @%@ operator (modulus)
| AndOp -- ^ @&&@ operator (logical and)
| OrOp -- ^ @||@ operator (logical or)
| BitXorOp -- ^ @^@ operator (bitwise xor)
| BitAndOp -- ^ @&@ operator (bitwise and)
| BitOrOp -- ^ @|@ operator (bitwise or)
| ShlOp -- ^ @<<@ operator (shift left)
| ShrOp -- ^ @>>@ operator (shift right)
| EqOp -- ^ @==@ operator (equality)
| LtOp -- ^ @< @operator (less than)
| LeOp -- ^ @<=@ operator (less than or equal to)
| NeOp -- ^ @!=@ operator (not equal to)
| GeOp -- ^ @>=@ operator (greater than or equal to)
| GtOp -- ^ @>@ operator (greater than)
deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Describes how a value bound to an identifier in a pattern is going to be borrowed
-- (@syntax::ast::BindingMode@).
--
-- Example: @&mut@ in @|&mut x: i32| -> { x += 1 }@
data BindingMode
= ByRef Mutability
| ByValue Mutability
deriving (Eq, Ord, Show, Typeable, Data, Generic, NFData)
-- | A curly brace delimited sequence of statements (@syntax::ast::Block@). The last statement in
-- the block can always be a 'NoSemi' expression.
--
-- Example: @{ let x = 1; return x + y }@ as in @fn foo() { let x = 1; return x + y }@
data Block a = Block [Stmt a] Unsafety a
deriving (Eq, Ord, Show, Functor, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Block a) where spanOf (Block _ _ s) = spanOf s
-- | Describes how a 'Closure' should close over its free variables (@syntax::ast::CaptureBy@).
data CaptureBy
= Value -- ^ make copies of free variables closed over (@move@ closures)
| Ref -- ^ borrow free variables closed over
deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Const annotation to specify if a function or method is allowed to be called in constants
-- context with constant arguments (@syntax::ast::Constness@). [Relevant
-- RFC](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md)
--
-- Example: @const@ in @const fn inc(x: i32) -> i32 { x + 1 }@
data Constness = Const | NotConst deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | An 'ImplItem' can be marked @default@ (@syntax::ast::Defaultness@).
data Defaultness = Default | Final deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Expression (@syntax::ast::Expr@). Note that Rust pushes into expressions an unusual number
-- of constructs including @if@, @while@, @match@, etc.
data Expr a
-- | box expression (example: @box x@)
= Box [Attribute a] (Expr a) a
-- | in-place expression - first 'Expr' is the place, second one is the value (example: @x <- y@)
| InPlace [Attribute a] (Expr a) (Expr a) a
-- | array literal (example: @[a, b, c, d]@)
| Vec [Attribute a] [Expr a] a
-- | function call where the first 'Expr' is the function itself, and the @['Expr']@ is the list of
-- arguments (example: @foo(1,2,x)@)
| Call [Attribute a] (Expr a) [Expr a] a
-- | method call where the first 'Expr' is the receiver, 'Ident' is the method name, @Maybe ['Ty']@
-- the list of type arguments and '[Expr]' the arguments to the method.
-- (example: @x.foo::\<Bar, Baz\>(a, b, c, d)@
| MethodCall [Attribute a] (Expr a) Ident (Maybe [Ty a]) [Expr a] a
-- | tuple (example: @(a, b, c ,d)@)
| TupExpr [Attribute a] [Expr a] a
-- | binary operation (example: @a + b@, @a * b@)
| Binary [Attribute a] BinOp (Expr a) (Expr a) a
-- | unary operation (example: @!x@, @*x@)
| Unary [Attribute a] UnOp (Expr a) a
-- | literal (example: @1@, @"foo"@)
| Lit [Attribute a] (Lit a) a
-- | cast (example: @foo as f64@)
| Cast [Attribute a] (Expr a) (Ty a) a
-- | type annotation (example: @x: i32@)
| TypeAscription [Attribute a] (Expr a) (Ty a) a
-- | if expression, with an optional @else@ block. In the case the @else@ block is missing, the
-- type of the @if@ is inferred to be @()@. (example: @if 1 == 2 { (1,1) } else { (2,2) }@
| If [Attribute a] (Expr a) (Block a) (Maybe (Expr a)) a
-- | if-let expression with an optional else block (example: @if let Some(x) = None { () }@)
| IfLet [Attribute a] (NonEmpty (Pat a)) (Expr a) (Block a) (Maybe (Expr a)) a
-- | while loop, with an optional label (example: @'lbl: while 1 == 1 { break 'lbl }@)
| While [Attribute a] (Expr a) (Block a) (Maybe (Label a)) a
-- | while-let loop, with an optional label (example: @while let Some(x) = None { x }@)
| WhileLet [Attribute a] (NonEmpty (Pat a)) (Expr a) (Block a) (Maybe (Label a)) a
-- | for loop, with an optional label (example: @for i in 1..10 { println!("{}",i) }@)
| ForLoop [Attribute a] (Pat a) (Expr a) (Block a) (Maybe (Label a)) a
-- | conditionless loop (can be exited with 'Break', 'Continue', or 'Ret')
| Loop [Attribute a] (Block a) (Maybe (Label a)) a
-- | match block
| Match [Attribute a] (Expr a) [Arm a] a
-- | closure (example: @move |a, b, c| { a + b + c }@)
| Closure [Attribute a] Movability CaptureBy (FnDecl a) (Expr a) a
-- | (possibly unsafe) block (example: @unsafe { 1 }@)
| BlockExpr [Attribute a] (Block a) a
-- | a catch block (example: @do catch { 1 }@)
| Catch [Attribute a] (Block a) a
-- | assignment (example: @a = foo()@)
| Assign [Attribute a] (Expr a) (Expr a) a
-- | assignment with an operator (example: @a += 1@)
| AssignOp [Attribute a] BinOp (Expr a) (Expr a) a
-- | access of a named struct field (example: @obj.foo@)
| FieldAccess [Attribute a] (Expr a) Ident a
-- | access of an unnamed field of a struct or tuple-struct (example: @foo.0@)
| TupField [Attribute a] (Expr a) Int a
-- | indexing operation (example: @foo[2]@)
| Index [Attribute a] (Expr a) (Expr a) a
-- | range (examples: @1..2@, @1..@, @..2@, @1...2@, @1...@, @...2@)
| Range [Attribute a] (Maybe (Expr a)) (Maybe (Expr a)) RangeLimits a
-- | variable reference
| PathExpr [Attribute a] (Maybe (QSelf a)) (Path a) a
-- | referencing operation (example: @&a or &mut a@)
| AddrOf [Attribute a] Mutability (Expr a) a
-- | @break@ with an optional label and expression denoting what to break out of and what to
-- return (example: @break 'lbl 1@)
| Break [Attribute a] (Maybe (Label a)) (Maybe (Expr a)) a
-- | @continue@ with an optional label (example: @continue@)
| Continue [Attribute a] (Maybe (Label a)) a
-- | @return@ with an optional value to be returned (example: @return 1@)
| Ret [Attribute a] (Maybe (Expr a)) a
-- | macro invocation before expansion
| MacExpr [Attribute a] (Mac a) a
-- | struct literal expression (examples: @Foo { x: 1, y: 2 }@ or @Foo { x: 1, ..base }@)
| Struct [Attribute a] (Path a) [Field a] (Maybe (Expr a)) a
-- | array literal constructed from one repeated element (example: @[1; 5]@)
| Repeat [Attribute a] (Expr a) (Expr a) a
-- | no-op: used solely so we can pretty print faithfully
| ParenExpr [Attribute a] (Expr a) a
-- | sugar for error handling with @Result@ (example: @parsed_result?@)
| Try [Attribute a] (Expr a) a
-- | @yield@ with an optional value to yield (example: @yield 1@)
| Yield [Attribute a] (Maybe (Expr a)) a
-- | embedded Haskell expressions for use by quasiquoters
| EmbeddedExpr [Attribute a] String a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Expr a) where
spanOf (Box _ _ s) = spanOf s
spanOf (InPlace _ _ _ s) = spanOf s
spanOf (Vec _ _ s) = spanOf s
spanOf (Call _ _ _ s) = spanOf s
spanOf (MethodCall _ _ _ _ _ s) = spanOf s
spanOf (TupExpr _ _ s) = spanOf s
spanOf (Binary _ _ _ _ s) = spanOf s
spanOf (Unary _ _ _ s) = spanOf s
spanOf (Lit _ _ s) = spanOf s
spanOf (Cast _ _ _ s) = spanOf s
spanOf (TypeAscription _ _ _ s) = spanOf s
spanOf (If _ _ _ _ s) = spanOf s
spanOf (IfLet _ _ _ _ _ s) = spanOf s
spanOf (While _ _ _ _ s) = spanOf s
spanOf (WhileLet _ _ _ _ _ s) = spanOf s
spanOf (ForLoop _ _ _ _ _ s) = spanOf s
spanOf (Loop _ _ _ s) = spanOf s
spanOf (Match _ _ _ s) = spanOf s
spanOf (Closure _ _ _ _ _ s) = spanOf s
spanOf (BlockExpr _ _ s) = spanOf s
spanOf (Catch _ _ s) = spanOf s
spanOf (Assign _ _ _ s) = spanOf s
spanOf (AssignOp _ _ _ _ s) = spanOf s
spanOf (FieldAccess _ _ _ s) = spanOf s
spanOf (TupField _ _ _ s) = spanOf s
spanOf (Index _ _ _ s) = spanOf s
spanOf (Range _ _ _ _ s) = spanOf s
spanOf (PathExpr _ _ _ s) = spanOf s
spanOf (AddrOf _ _ _ s) = spanOf s
spanOf (Break _ _ _ s) = spanOf s
spanOf (Continue _ _ s) = spanOf s
spanOf (Ret _ _ s) = spanOf s
spanOf (MacExpr _ _ s) = spanOf s
spanOf (Struct _ _ _ _ s) = spanOf s
spanOf (Repeat _ _ _ s) = spanOf s
spanOf (ParenExpr _ _ s) = spanOf s
spanOf (Try _ _ s) = spanOf s
spanOf (Yield _ _ s) = spanOf s
spanOf (EmbeddedExpr _ _ s) = spanOf s
-- | Field in a struct literal expression (@syntax::ast::Field@).
--
-- Example: @x: 1@ in @Point { x: 1, y: 2 }@
data Field a = Field Ident (Maybe (Expr a)) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Field a) where spanOf (Field _ _ s) = spanOf s
-- | Field in a struct literal pattern (@syntax::ast::FieldPat@). The field name 'Ident' is optional
-- but, when it is 'Nothing', the pattern the field is destructured to must be 'IdentP'.
--
-- Example: @x@ in @Point { x, y }@
data FieldPat a = FieldPat (Maybe Ident) (Pat a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (FieldPat a) where spanOf (FieldPat _ _ s) = spanOf s
-- | Header (not the body) of a function declaration (@syntax::ast::FnDecl@). The 'Bool' argument
-- indicates whether the header is variadic (so whether the argument list ends in @...@).
--
-- Example: @(bar: i32) -> i32@ as in
--
-- @
-- fn foo(bar: i32) -> i32 {
-- bar + 2
-- }
-- @
data FnDecl a = FnDecl [Arg a] (Maybe (Ty a)) Bool a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (FnDecl a) where spanOf (FnDecl _ _ _ s) = spanOf s
-- | An item within an extern block (@syntax::ast::ForeignItem@ with @syntax::ast::ForeignItemKind@
-- inlined).
--
-- Example: @static ext: u8@ in @extern \"C\" { static ext: u8 }@
data ForeignItem a
-- | Foreign function
--
-- Example: @fn foo(x: i32);@ in @extern \"C\" { fn foo(x: i32); }@
= ForeignFn [Attribute a] (Visibility a) Ident (FnDecl a) (Generics a) a
-- | Foreign static variable, optionally mutable
--
-- Example: @static mut bar: i32;@ in @extern \"C\" { static mut bar: i32; }@
| ForeignStatic [Attribute a] (Visibility a) Ident (Ty a) Mutability a
-- | Foreign type
--
-- Example: @type Boo;@
| ForeignTy [Attribute a] (Visibility a) Ident a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (ForeignItem a) where
spanOf (ForeignFn _ _ _ _ _ s) = spanOf s
spanOf (ForeignStatic _ _ _ _ _ s) = spanOf s
spanOf (ForeignTy _ _ _ s) = spanOf s
-- | Represents lifetimes and type parameters attached to a declaration of a functions, enums,
-- traits, etc. (@syntax::ast::Generics@). Note that lifetime definitions are always required to be
-- before the type parameters.
--
-- This one AST node is also a bit weird: it is the only node whose source representation is not
-- compact - the lifetimes and type parameters occur by themselves between @\<@ and @\>@ then a
-- bit further the where clause occurs after a @where@.
--
-- Example: @\<\'a, \'b: \'c, T: \'a\>@ and @where Option\<T\>: Copy@ as in
--
-- @
-- fn nonsense\<\'a, \'b: \'c, T: \'a\>(x: i32) -\> i32
-- where Option\<T\>: Copy {
-- 1
-- }@.
data Generics a = Generics [LifetimeDef a] [TyParam a] (WhereClause a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | Extract the where clause from a 'Generics'.
whereClause :: Generics a -> WhereClause a
whereClause (Generics _ _ wc _) = wc
instance Located a => Located (Generics a) where spanOf (Generics _ _ _ s) = spanOf s
instance Sem.Semigroup a => Sem.Semigroup (Generics a) where
Generics lt1 tp1 wc1 x1 <> Generics lt2 tp2 wc2 x2 = Generics lts tps wcs xs
where lts = lt1 ++ lt2
tps = tp1 ++ tp2
wcs = wc1 <> wc2
xs = x1 <> x2
instance (Sem.Semigroup a, Monoid a) => Monoid (Generics a) where
mappend = (<>)
mempty = Generics [] [] mempty mempty
-- | An item within an impl (@syntax::ast::ImplItem@ with @syntax::ast::ImplItemKind@ inlined).
--
-- Examples:
--
-- @
-- impl MyTrait {
-- // Associated constant
-- const ID: i32 = 1;
--
-- // Method
-- fn area(&self) -> f64 { 1f64 }
--
-- // Associated type
-- type N = i32;
--
-- // Call to a macro
-- foo!{}
-- }
-- @
data ImplItem a
-- | Associated constant
= ConstI [Attribute a] (Visibility a) Defaultness Ident (Ty a) (Expr a) a
-- | Method
| MethodI [Attribute a] (Visibility a) Defaultness Ident (Generics a) (MethodSig a) (Block a) a
-- | Associated type
| TypeI [Attribute a] (Visibility a) Defaultness Ident (Ty a) a
-- | Macro call
| MacroI [Attribute a] Defaultness (Mac a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (ImplItem a) where
spanOf (ConstI _ _ _ _ _ _ s) = spanOf s
spanOf (MethodI _ _ _ _ _ _ _ s) = spanOf s
spanOf (TypeI _ _ _ _ _ s) = spanOf s
spanOf (MacroI _ _ _ s) = spanOf s
-- | For traits with a default impl, one can "opt out" of that impl with a negative impl, by adding
-- @!@ mark before the trait name. [RFC on builtin
-- traits](https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md)
--
-- Example: @!@ as in @impl !Trait for Foo { }@
data ImplPolarity = Positive | Negative deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | A top-level item, possibly in a 'Mod' or a 'ItemStmt' (@syntax::ast::Item@ with
-- @syntax::ast::ItemKind@ inlined).
--
-- Example: @fn main() { return; }@
data Item a
-- | extern crate item, with optional original crate name.
-- Examples: @extern crate foo@ or @extern crate foo_bar as foo@
= ExternCrate [Attribute a] (Visibility a) Ident (Maybe Ident) a
-- | use declaration (@use@ or @pub use@) item.
-- Examples: @use foo;@, @use foo::bar;@, or @use foo::bar as FooBar;@
| Use [Attribute a] (Visibility a) (UseTree a) a
-- | static item (@static@ or @pub static@).
-- Examples: @static FOO: i32 = 42;@ or @static FOO: &'static str = "bar";@
| Static [Attribute a] (Visibility a) Ident (Ty a) Mutability (Expr a) a
-- | constant item (@const@ or @pub const@).
-- Example: @const FOO: i32 = 42;@
| ConstItem [Attribute a] (Visibility a) Ident (Ty a) (Expr a) a
-- | function declaration (@fn@ or @pub fn@).
-- Example: @fn foo(bar: usize) -\> usize { .. }@
| Fn [Attribute a] (Visibility a) Ident (FnDecl a) Unsafety Constness Abi (Generics a) (Block a) a
-- | module declaration (@mod@ or @pub mod@) (@syntax::ast::Mod@).
-- Example: @mod foo;@ or @mod foo { .. }@
| Mod [Attribute a] (Visibility a) Ident (Maybe [Item a]) a
-- | external module (@extern@ or @pub extern@) (@syntax::ast::ForeignMod@).
-- Example: @extern { .. }@ or @extern \"C\" { .. }@
| ForeignMod [Attribute a] (Visibility a) Abi [ForeignItem a] a
-- | type alias (@type@ or @pub type@).
-- Example: @type Foo = Bar\<u8\>;@
| TyAlias [Attribute a] (Visibility a) Ident (Ty a) (Generics a) a
-- | enum definition (@enum@ or @pub enum@) (@syntax::ast::EnumDef@).
-- Example: @enum Foo\<A, B\> { C(A), D(B) }@
| Enum [Attribute a] (Visibility a) Ident [Variant a] (Generics a) a
-- | struct definition (@struct@ or @pub struct@).
-- Example: @struct Foo\<A\> { x: A }@
| StructItem [Attribute a] (Visibility a) Ident (VariantData a) (Generics a) a
-- | union definition (@union@ or @pub union@).
-- Example: @union Foo\<A, B\> { x: A, y: B }@
| Union [Attribute a] (Visibility a) Ident (VariantData a) (Generics a) a
-- | trait declaration (@trait@ or @pub trait@).
-- Example: @trait Foo { .. }@ or @trait Foo\<T\> { .. }@
| Trait [Attribute a] (Visibility a) Ident Bool Unsafety (Generics a) [TyParamBound a] [TraitItem a] a
-- | trait alias
-- Example: @trait Foo = Bar + Quux;@
| TraitAlias [Attribute a] (Visibility a) Ident (Generics a) (NonEmpty (TyParamBound a)) a
-- | implementation
-- Example: @impl\<A\> Foo\<A\> { .. }@ or @impl\<A\> Trait for Foo\<A\> { .. }@
| Impl [Attribute a] (Visibility a) Defaultness Unsafety ImplPolarity (Generics a) (Maybe (TraitRef a)) (Ty a) [ImplItem a] a
-- | generated from a call to a macro
-- Example: @foo!{ .. }@
| MacItem [Attribute a] (Maybe Ident) (Mac a) a
-- | definition of a macro via @macro_rules@
-- Example: @macro_rules! foo { .. }@
| MacroDef [Attribute a] Ident TokenStream a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Item a) where
spanOf (ExternCrate _ _ _ _ s) = spanOf s
spanOf (Use _ _ _ s) = spanOf s
spanOf (Static _ _ _ _ _ _ s) = spanOf s
spanOf (ConstItem _ _ _ _ _ s) = spanOf s
spanOf (Fn _ _ _ _ _ _ _ _ _ s) = spanOf s
spanOf (Mod _ _ _ _ s) = spanOf s
spanOf (ForeignMod _ _ _ _ s) = spanOf s
spanOf (TyAlias _ _ _ _ _ s) = spanOf s
spanOf (Enum _ _ _ _ _ s) = spanOf s
spanOf (StructItem _ _ _ _ _ s) = spanOf s
spanOf (Union _ _ _ _ _ s) = spanOf s
spanOf (Trait _ _ _ _ _ _ _ _ s) = spanOf s
spanOf (TraitAlias _ _ _ _ _ s) = spanOf s
spanOf (Impl _ _ _ _ _ _ _ _ _ s) = spanOf s
spanOf (MacItem _ _ _ s) = spanOf s
spanOf (MacroDef _ _ _ s) = spanOf s
-- | Used to annotate loops, breaks, continues, etc.
data Label a = Label Name a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Label a) where spanOf (Label _ s) = spanOf s
-- | A lifetime is a name for a scope in a program (@syntax::ast::Lifetime@). One of the novel
-- features of Rust is that code can be parametrized over lifetimes. Syntactically, they are like
-- regular identifiers, but start with a tick @\'@ mark. The 'Name' argument is /not/ supposed to
-- include that tick.
--
-- Examples: @\'a@ or @\'static@
data Lifetime a = Lifetime Name a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Lifetime a) where spanOf (Lifetime _ s) = spanOf s
-- | A lifetime definition, introducing a lifetime and the other lifetimes that bound it
-- (@syntax::ast::LifetimeDef@).
--
-- Example: @\'a: \'b + \'c + \'d@
data LifetimeDef a = LifetimeDef [Attribute a] (Lifetime a) [Lifetime a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (LifetimeDef a) where spanOf (LifetimeDef _ _ _ s) = spanOf s
-- | This is the fundamental unit of parsing - it represents the contents of one source file. It is
-- composed of an optional shebang line, inner attributes that follow, and then the module items.
--
-- Example:
--
-- @
-- #!\/usr\/bin/env rust
--
-- #![allow(dead_code)]
--
-- fn main() {
-- println!("Hello world")
-- }
-- @
data SourceFile a
= SourceFile (Maybe Name) [Attribute a] [Item a]
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | The suffix on a literal (unifies @syntax::ast::LitIntType@, @syntax::ast::IntTy@,
-- @syntax::ast::UintTy@, and @syntax::ast::FloatTy@). As of today, only numeric types can have
-- suffixes, but the possibility of adding more (possibly arbitrary) suffixes to literals in general
-- is being kept open intentionally. [RFC about future-proofing literal
-- suffixes](https://github.com/rust-lang/rfcs/blob/master/text/0463-future-proof-literal-suffixes.md)
--
-- Examples: @i32@, @isize@, and @f32@
data Suffix
= Unsuffixed
| Is | I8 | I16 | I32 | I64 | I128
| Us | U8 | U16 | U32 | U64 | U128
| F32 | F64
deriving (Eq, Ord, Show, Enum, Bounded, Typeable, Data, Generic, NFData)
-- | Literals in Rust (@syntax::ast::Lit@). As discussed in 'Suffix', Rust AST is designed to parse
-- suffixes for all literals, even if they are currently only valid on 'Int' and 'Float' literals.
data Lit a
= Str String StrStyle Suffix a -- ^ string (example: @"foo"@)
| ByteStr [Word8] StrStyle Suffix a -- ^ byte string (example: @b"foo"@)
| Char Char Suffix a -- ^ character (example: @\'a\'@)
| Byte Word8 Suffix a -- ^ byte (example: @b\'f\'@)
| Int IntRep Integer String Suffix a -- ^ integer (example: @1i32@)
| Float Double Suffix a -- ^ float (example: @1.12e4@)
| Bool Bool Suffix a -- ^ boolean (example: @true@)
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Lit a) where
spanOf (Str _ _ _ s) = spanOf s
spanOf (ByteStr _ _ _ s) = spanOf s
spanOf (Char _ _ s) = spanOf s
spanOf (Byte _ _ s) = spanOf s
spanOf (Int _ _ _ _ s) = spanOf s
spanOf (Float _ _ s) = spanOf s
spanOf (Bool _ _ s) = spanOf s
-- | Smart constructor for 'ByteStr'.
byteStr :: String -> StrStyle -> Suffix -> a -> Lit a
byteStr s = ByteStr (map (fromIntegral . ord) s)
-- | Extract the suffix from a 'Lit'.
suffix :: Lit a -> Suffix
suffix (Str _ _ s _) = s
suffix (ByteStr _ _ s _) = s
suffix (Char _ s _) = s
suffix (Byte _ s _) = s
suffix (Int _ _ _ s _) = s
suffix (Float _ s _) = s
suffix (Bool _ s _) = s
-- | The base of the number in an @Int@ literal can be binary (e.g. @0b1100@), octal (e.g. @0o14@),
-- decimal (e.g. @12@), or hexadecimal (e.g. @0xc@).
data IntRep
= Bin
| Oct
| Dec
| Hex
deriving (Eq, Ord, Show, Enum, Bounded, Typeable, Data, Generic, NFData)
-- | Represents a macro invocation (@syntax::ast::Mac@). The 'Path' indicates which macro is being
-- invoked, and the 'TokenStream' contains the source of the macro invocation.
data Mac a = Mac (Path a) TokenStream a deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Mac a) where spanOf (Mac _ _ s) = spanOf s
-- | Style of the macro statement (@syntax::ast::MacStmtStyle@).
data MacStmtStyle
= SemicolonMac -- ^ trailing semicolon (example: @foo! { ... };@, @ foo!(...);@, and @foo![...];@)
| BracesMac -- ^ braces (example: @foo! { ... }@)
deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Represents a method's signature in a trait declaration, or in an implementation.
data MethodSig a = MethodSig Unsafety Constness Abi (FnDecl a) deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | The movability of a generator / closure literal (@syntax::ast::Movability@).
data Movability = Immovable | Movable deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Encodes whether something can be updated or changed (@syntax::ast::Mutability@).
data Mutability = Mutable | Immutable deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | For interpolation during macro expansion (@syntax::ast::NonTerminal@).
data Nonterminal a
= NtItem (Item a)
| NtBlock (Block a)
| NtStmt (Stmt a)
| NtPat (Pat a)
| NtExpr (Expr a)
| NtTy (Ty a)
| NtIdent Ident
| NtPath (Path a)
| NtTT TokenTree
| NtArm (Arm a)
| NtImplItem (ImplItem a)
| NtTraitItem (TraitItem a)
| NtGenerics (Generics a)
| NtWhereClause (WhereClause a)
| NtArg (Arg a)
| NtLit (Lit a)
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | Patterns (@syntax::ast::Pat@).
data Pat a
-- | wildcard pattern: @_@
= WildP a
-- | identifier pattern - either a new bound variable or a unit (tuple) struct pattern, or a
-- const pattern. Disambiguation cannot be done with parser alone, so it happens during name
-- resolution. (example: @mut x@)
| IdentP BindingMode Ident (Maybe (Pat a)) a
-- | struct pattern. The 'Bool' signals the presence of a @..@. (example: @Variant { x, y, .. }@)
| StructP (Path a) [FieldPat a] Bool a
-- | tuple struct pattern. If the @..@ pattern is present, the 'Maybe Int' denotes its position.
-- (example: @Variant(x, y, .., z)@)
| TupleStructP (Path a) [Pat a] (Maybe Int) a
-- | path pattern (example @A::B::C@)
| PathP (Maybe (QSelf a)) (Path a) a
-- | tuple pattern. If the @..@ pattern is present, the 'Maybe Int' denotes its position.
-- (example: @(a, b)@)
| TupleP [Pat a] (Maybe Int) a
-- | box pattern (example: @box _@)
| BoxP (Pat a) a
-- | reference pattern (example: @&mut (a, b)@)
| RefP (Pat a) Mutability a
-- | literal (example: @1@)
| LitP (Expr a) a
-- | range pattern (example: @1...2@)
| RangeP (Expr a) (Expr a) a
-- | slice pattern where, as per [this RFC](https://github.com/P1start/rfcs/blob/array-pattern-changes/text/0000-array-pattern-changes.md),
-- the pattern is split into the patterns before/after the @..@ and the pattern at the @..@. (example: @[a, b, ..i, y, z]@)
| SliceP [Pat a] (Maybe (Pat a)) [Pat a] a
-- | generated from a call to a macro (example: @LinkedList!(1,2,3)@)
| MacP (Mac a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Pat a) where
spanOf (WildP s) = spanOf s
spanOf (IdentP _ _ _ s) = spanOf s
spanOf (StructP _ _ _ s) = spanOf s
spanOf (TupleStructP _ _ _ s) = spanOf s
spanOf (PathP _ _ s) = spanOf s
spanOf (TupleP _ _ s) = spanOf s
spanOf (BoxP _ s) = spanOf s
spanOf (RefP _ _ s) = spanOf s
spanOf (LitP _ s) = spanOf s
spanOf (RangeP _ _ s) = spanOf s
spanOf (SliceP _ _ _ s) = spanOf s
spanOf (MacP _ s) = spanOf s
-- | Everything in Rust is namespaced using nested modules. A 'Path' represents a path into nested
-- modules, possibly instantiating type parameters along the way (@syntax::ast::Path@). Much like
-- file paths, these paths can be relative or absolute (global) with respect to the crate root.
--
-- Paths are used to identify expressions (see 'PathExpr'), types (see 'PathTy'), and modules
-- (indirectly through 'ViewPath' and such).
--
-- The 'Bool' argument identifies whether the path is relative or absolute.
--
-- Example: @std::cmp::PartialEq@
data Path a = Path Bool [PathSegment a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Path a) where spanOf (Path _ _ s) = spanOf s
-- | Parameters on a path segment (@syntax::ast::PathParameters@).
data PathParameters a
-- | Parameters in a chevron comma-delimited list (@syntax::ast::AngleBracketedParameterData@).
-- Note that lifetimes must come before types, which must come before bindings. Bindings are
-- equality constraints on associated types (example: @Foo\<A=Bar\>@)
--
-- Example: @\<\'a,A,B,C=i32\>@ in a path segment like @foo::\<'a,A,B,C=i32\>@
= AngleBracketed [Lifetime a] [Ty a] [(Ident, Ty a)] a
-- | Parameters in a parenthesized comma-delimited list, with an optional output type
-- (@syntax::ast::ParenthesizedParameterData@).
--
-- Example: @(A,B) -\> C@ in a path segment @Foo(A,B) -\> C@
| Parenthesized [Ty a] (Maybe (Ty a)) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (PathParameters a) where
spanOf (AngleBracketed _ _ _ s) = spanOf s
spanOf (Parenthesized _ _ s) = spanOf s
-- | Segment of a path (@syntax::ast::PathSegment@).
data PathSegment a
= PathSegment Ident (Maybe (PathParameters a)) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (PathSegment a) where spanOf (PathSegment _ _ s) = spanOf s
-- | Trait ref parametrized over lifetimes introduced by a @for@ (@syntax::ast::PolyTraitRef@).
--
-- Example: @for\<\'a,'b\> Foo\<&\'a Bar\>@
data PolyTraitRef a = PolyTraitRef [LifetimeDef a] (TraitRef a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (PolyTraitRef a) where spanOf (PolyTraitRef _ _ s) = spanOf s
-- | The explicit @Self@ type in a "qualified path". The actual path, including the trait and the
-- associated item, is stored separately. The first argument is the type given to @Self@ and the
-- second is the index of the associated qualified with this @Self@ type
data QSelf a = QSelf (Ty a) Int
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | Limit types of a 'Range'
data RangeLimits
= HalfOpen -- ^ Inclusive at the beginning, exclusive at the end
| Closed -- ^ Inclusive at the beginning and end
deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | A statement (@syntax::ast::Stmt@). Rust has relatively few types of statements by turning both
-- expressions (sometimes with a required semicolon at the end) and items into statements.
data Stmt a
-- | A local @let@ binding (@syntax::ast::Local@) (example: @let x: i32 = 1;@)
= Local (Pat a) (Maybe (Ty a)) (Maybe (Expr a)) [Attribute a] a
-- | Item definition (example: @fn foo(x: i32) { return x + 1 }@)
| ItemStmt (Item a) a
-- | Expression without a trailing semicolon (example: @x + 1@)
| NoSemi (Expr a) a
-- | Expression with a trailing semicolon (example: @x + 1;@)
| Semi (Expr a) a
-- | A macro call (example: @println!("hello world")@)
| MacStmt (Mac a) MacStmtStyle [Attribute a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Stmt a) where
spanOf (Local _ _ _ _ s) = spanOf s
spanOf (ItemStmt _ s) = spanOf s
spanOf (NoSemi _ s) = spanOf s
spanOf (Semi _ s) = spanOf s
spanOf (MacStmt _ _ _ s) = spanOf s
-- | Style of a string literal (@syntax::ast::StrStyle@).
data StrStyle
= Cooked -- ^ regular strings (example: @\"foo\"@)
| Raw Int -- ^ raw strings, with the number of @#@ delimiters (example: @r##\"foo\"##@)
deriving (Eq, Ord, Show, Typeable, Data, Generic, NFData)
-- | Field of a struct (@syntax::ast::StructField@) used in declarations
--
-- Example: @bar: usize@ as in @struct Foo { bar: usize }@
data StructField a = StructField (Maybe Ident) (Visibility a) (Ty a) [Attribute a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (StructField a) where spanOf (StructField _ _ _ _ s) = spanOf s
-- | An abstract sequence of tokens, organized into a sequence (e.g. stream) of 'TokenTree', each of
-- which is a single 'Token' or a 'Delimited' subsequence of tokens.
data TokenStream
= Tree TokenTree -- ^ a single token or a single set of delimited tokens
| Stream [TokenStream] -- ^ stream of streams of tokens
deriving (Eq, Ord, Show, Typeable, Data, Generic, NFData)
-- | A 'TokenStream' is at its core just a stream of 'TokenTree'. This function lets you get at that
-- directly. For example, you can use 'Data.List.unfoldr unconsTokenStream' to convert between a
-- 'TokenStream' and '[TokenTree]'.
unconsTokenStream :: TokenStream -> Maybe (TokenTree, TokenStream)
unconsTokenStream (Tree t) = Just (t, Stream [])
unconsTokenStream (Stream []) = Nothing
unconsTokenStream (Stream (ts:tss)) = case unconsTokenStream ts of
Nothing -> unconsTokenStream (Stream tss)
Just (t,ts') -> Just (t, Stream (ts':tss))
-- | 'Span' is not stored on 'TokenStream' - it is computed
instance Located TokenStream where
spanOf (Tree t) = spanOf t
spanOf (Stream tt) = spanOf tt
-- | When the parser encounters a macro call, it parses what follows as a 'Delimited' token tree.
-- Basically, token trees let you store raw tokens or 'Sequence' forms inside of balanced
-- parens, braces, or brackets. This is a very loose structure, such that all sorts of different
-- AST-fragments can be passed to syntax extensions using a uniform type.
data TokenTree
-- | A single token
= Token Span Token
-- | A delimited sequence of tokens (@syntax::tokenstream::Delimited@)
-- Example: @{ [-\>+\<] }@ in @brainfuck!{ [-\>+\<] };@
| Delimited
{ span :: Span
, delim :: Delim -- ^ type of delimiter
, tts :: TokenStream -- ^ delimited sequence of tokens
}
deriving (Eq, Ord, Show, Typeable, Data, Generic, NFData)
instance Located TokenTree where
spanOf (Token s _) = s
spanOf (Delimited s _ _) = s
-- | Modifier on a bound, currently this is only used for @?Sized@, where the modifier is @Maybe@.
-- Negative bounds should also be handled here.
data TraitBoundModifier = None | Maybe deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Item declaration within a trait declaration (@syntax::ast::TraitItem@ with
-- @syntax::ast::TraitItemKind@ inlined), possibly including a default implementation. A trait item
-- is either required (meaning it doesn't have an implementation, just a signature) or provided
-- (meaning it has a default implementation).
--
-- Examples:
--
-- @
-- trait MyTrait {
-- // Associated constant
-- const ID: i32 = 1;
--
-- // Method
-- fn area(&self) -> f64;
--
-- // Associated type
-- type N: fmt::Display;
--
-- // Call to a macro
-- foo!{}
-- }
-- @
data TraitItem a
-- | Associated constants
= ConstT [Attribute a] Ident (Ty a) (Maybe (Expr a)) a
-- | Method with optional body
| MethodT [Attribute a] Ident (Generics a) (MethodSig a) (Maybe (Block a)) a
-- | Possibly abstract associated types
| TypeT [Attribute a] Ident [TyParamBound a] (Maybe (Ty a)) a
-- | Call to a macro
| MacroT [Attribute a] (Mac a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (TraitItem a) where
spanOf (ConstT _ _ _ _ s) = spanOf s
spanOf (MethodT _ _ _ _ _ s) = spanOf s
spanOf (TypeT _ _ _ _ s) = spanOf s
spanOf (MacroT _ _ s) = spanOf s
-- | A 'TraitRef' is a path which identifies a trait (@syntax::ast::TraitRef@).
newtype TraitRef a = TraitRef (Path a) deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (TraitRef a) where spanOf (TraitRef p) = spanOf p
-- | Types (@syntax::ast::Ty@).
data Ty a
-- | variable length slice (example: @[T]@)
= Slice (Ty a) a
-- | fixed length array (example: @[T; n]@)
| Array (Ty a) (Expr a) a
-- | raw pointer (example: @*const T@ or @*mut T@)
| Ptr Mutability (Ty a) a
-- | reference (example: @&\'a T@ or @&\'a mut T@)
| Rptr (Maybe (Lifetime a)) Mutability (Ty a) a
-- | bare function (example: @fn(usize) -> bool@)
| BareFn Unsafety Abi [LifetimeDef a] (FnDecl a) a
-- | never type: @!@
| Never a
-- | tuple (example: @(i32, i32)@)
| TupTy [Ty a] a
-- | path type (examples: @std::math::pi@, @\<Vec\<T\> as SomeTrait\>::SomeType@).
| PathTy (Maybe (QSelf a)) (Path a) a
-- | trait object type (example: @Bound1 + Bound2 + Bound3@)
| TraitObject (NonEmpty (TyParamBound a)) a
-- | impl trait type (see the
-- [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md))
-- (example: @impl Bound1 + Bound2 + Bound3@).
| ImplTrait (NonEmpty (TyParamBound a)) a
-- | no-op; kept solely so that we can pretty print faithfully
| ParenTy (Ty a) a
-- | typeof, currently unsupported in @rustc@ (example: @typeof(1)@)
| Typeof (Expr a) a
-- | inferred type: @_@
| Infer a
-- | generated from a call to a macro (example: @HList![i32,(),u8]@)
| MacTy (Mac a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Ty a) where
spanOf (Slice _ s) = spanOf s
spanOf (Array _ _ s) = spanOf s
spanOf (Ptr _ _ s) = spanOf s
spanOf (Rptr _ _ _ s) = spanOf s
spanOf (BareFn _ _ _ _ s) = spanOf s
spanOf (Never s) = spanOf s
spanOf (TupTy _ s) = spanOf s
spanOf (PathTy _ _ s) = spanOf s
spanOf (TraitObject _ s) = spanOf s
spanOf (ImplTrait _ s) = spanOf s
spanOf (ParenTy _ s) = spanOf s
spanOf (Typeof _ s) = spanOf s
spanOf (Infer s) = spanOf s
spanOf (MacTy _ s) = spanOf s
-- | Type parameter definition used in 'Generics' (@syntax::ast::TyParam@). Note that each
-- parameter can have any number of (lifetime or trait) bounds, as well as possibly a default type.
data TyParam a = TyParam [Attribute a] Ident [TyParamBound a] (Maybe (Ty a)) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (TyParam a) where spanOf (TyParam _ _ _ _ s) = spanOf s
-- | Bounds that can be placed on types (@syntax::ast::TyParamBound@). These can be either traits or
-- lifetimes.
data TyParamBound a
= TraitTyParamBound (PolyTraitRef a) TraitBoundModifier a -- ^ trait bound
| RegionTyParamBound (Lifetime a) a -- ^ lifetime bound
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (TyParamBound a) where
spanOf (TraitTyParamBound _ _ s) = spanOf s
spanOf (RegionTyParamBound _ s) = spanOf s
-- | Partition a list of 'TyParamBound' into a tuple of the 'TraitTyParamBound' and
-- 'RegionTyParamBound' variants.
partitionTyParamBounds :: [TyParamBound a] -> ([TyParamBound a], [TyParamBound a])
partitionTyParamBounds = partition isTraitBound
where
isTraitBound TraitTyParamBound{} = True
isTraitBound RegionTyParamBound{} = False
-- | Unary operators, used in the 'Unary' constructor of 'Expr' (@syntax::ast::UnOp@).
--
-- Example: @!@ as in @!true@
data UnOp
= Deref -- ^ @*@ operator (dereferencing)
| Not -- ^ @!@ operator (logical inversion)
| Neg -- ^ @-@ operator (negation)
deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | Qualifies whether something is using unsafe Rust or not (@syntax::ast::Unsafety@). Note that we
-- also use this to describe whether a 'Block' is unsafe or not, while Rust has a seperate structure
-- (@syntax::ast::BlockCheckMode@) for that. This is because they also need to keep track of whether
-- an unsafe block is compiler generated.
data Unsafety = Unsafe | Normal deriving (Eq, Ord, Enum, Bounded, Show, Typeable, Data, Generic, NFData)
-- | A variant in Rust is a constructor (either in a 'StructItem', 'Union', or 'Enum') which groups
-- together fields (@syntax::ast::Variant@). In the case of a unit variant, there can also be an
-- explicit discriminant expression.
data Variant a = Variant Ident [Attribute a] (VariantData a) (Maybe (Expr a)) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (Variant a) where spanOf (Variant _ _ _ _ s) = spanOf s
-- | Main payload in a 'Variant' (@syntax::ast::VariantData@).
--
-- Examples:
--
-- @
-- enum Foo {
-- // Struct variant
-- Bar { x: f64 },
--
-- // Tuple variant
-- Baz(i32, i32),
--
-- // Unit variant
-- Qux,
-- }
-- @
data VariantData a
= StructD [StructField a] a -- ^ Struct variant
| TupleD [StructField a] a -- ^ Tuple variant
| UnitD a -- ^ Unit variant
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (VariantData a) where
spanOf (StructD _ s) = spanOf s
spanOf (TupleD _ s) = spanOf s
spanOf (UnitD s) = spanOf s
-- | Paths used in 'Use' items (@ast::syntax::UseTree@).
--
-- Examples:
--
-- @
-- // Simple use paths
-- use foo::bar::baz as quux;
-- use foo::bar::baz;
--
-- // Glob use paths
-- use foo::bar::*;
--
-- // Nested use paths
-- use foo::bar::{a, b, c::quux as d}
-- @
data UseTree a
-- | Simple path, optionally ending in an @as@
= UseTreeSimple (Path a) (Maybe Ident) a
-- | Path ending in a glob pattern
| UseTreeGlob (Path a) a
-- | Path ending in a list of more paths
| UseTreeNested (Path a) [UseTree a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (UseTree a) where
spanOf (UseTreeSimple _ _ s) = spanOf s
spanOf (UseTreeGlob _ s) = spanOf s
spanOf (UseTreeNested _ _ s) = spanOf s
-- | The visibility modifier dictates from where one can access something
-- (@ast::syntax::Visibility@). [RFC about adding restricted
-- visibility](https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md)
data Visibility a
= PublicV -- ^ @pub@ is accessible from everywhere
| CrateV -- ^ @pub(crate)@ is accessible from within the crate
| RestrictedV (Path a) -- ^ for some path @p@, @pub(p)@ is visible at that path
| InheritedV -- ^ if no visbility is specified, this is the default
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
-- | A @where@ clause in a definition, where one can apply a series of constraints to the types
-- introduced and used by a 'Generic' clause (@syntax::ast::WhereClause@). In many cases, @where@
-- is the /only/ way to express certain bounds (since those bounds may not be immediately on a type
-- defined in the generic, but on a type derived from types defined in the generic).
--
-- Note that while 'WhereClause' is a field of 'Generic', not all uses of generics are coupled with
-- a where clause. In those cases, we leave the list of predicates empty.
--
-- Example: @where Option\<T\>: Debug@ as in
--
-- @
-- impl\<T\> PrintInOption for T where Option\<T\>: Debug { }
-- @
data WhereClause a = WhereClause [WherePredicate a] a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (WhereClause a) where spanOf (WhereClause _ s) = spanOf s
instance Sem.Semigroup a => Sem.Semigroup (WhereClause a) where
WhereClause wp1 x1 <> WhereClause wp2 x2 = WhereClause (wp1 ++ wp2) (x1 <> x2)
instance (Sem.Semigroup a, Monoid a) => Monoid (WhereClause a) where
mappend = (<>)
mempty = WhereClause [] mempty
-- | An individual predicate in a 'WhereClause' (@syntax::ast::WherePredicate@).
data WherePredicate a
-- | type bound (@syntax::ast::WhereBoundPredicate@) (example: @for\<\'c\> Foo: Send+Clone+\'c@)
= BoundPredicate [LifetimeDef a] (Ty a) [TyParamBound a] a
-- | lifetime predicate (@syntax::ast::WhereRegionPredicate@) (example: @\'a: \'b+\'c@)
| RegionPredicate (Lifetime a) [Lifetime a] a
-- | equality predicate (@syntax::ast::WhereEqPredicate@) (example: @T=int@). Note that this is
-- not currently supported.
| EqPredicate (Ty a) (Ty a) a
deriving (Eq, Ord, Functor, Show, Typeable, Data, Generic, Generic1, NFData)
instance Located a => Located (WherePredicate a) where
spanOf (BoundPredicate _ _ _ s) = spanOf s
spanOf (RegionPredicate _ _ s) = spanOf s
spanOf (EqPredicate _ _ s) = spanOf s