{-| 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::\(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\: Copy@ as in -- -- @ -- fn nonsense\<\'a, \'b: \'c, T: \'a\>(x: i32) -\> i32 -- where Option\: 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\;@ | TyAlias [Attribute a] (Visibility a) Ident (Ty a) (Generics a) a -- | enum definition (@enum@ or @pub enum@) (@syntax::ast::EnumDef@). -- Example: @enum Foo\ { C(A), D(B) }@ | Enum [Attribute a] (Visibility a) Ident [Variant a] (Generics a) a -- | struct definition (@struct@ or @pub struct@). -- Example: @struct Foo\ { x: A }@ | StructItem [Attribute a] (Visibility a) Ident (VariantData a) (Generics a) a -- | union definition (@union@ or @pub union@). -- Example: @union Foo\ { 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\ { .. }@ | 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\ Foo\ { .. }@ or @impl\ Trait for Foo\ { .. }@ | 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\@) -- -- 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@, @\ 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\: Debug@ as in -- -- @ -- impl\ PrintInOption for T where Option\: 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