// The Rust abstract syntax tree.
-pub use self::BindingMode::*;
pub use self::BinOp_::*;
pub use self::BlockCheckMode::*;
pub use self::CaptureClause::*;
use attr::ThinAttributes;
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
use abi::Abi;
-use ast_util;
use ext::base;
use ext::tt::macro_parser;
-use owned_slice::OwnedSlice;
-use parse::token::{InternedString, str_to_ident};
+use parse::token::InternedString;
use parse::token;
use parse::lexer;
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum PathParameters {
/// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
- AngleBracketedParameters(AngleBracketedParameterData),
+ AngleBracketed(AngleBracketedParameterData),
/// The `(A,B)` and `C` in `Foo(A,B) -> C`
- ParenthesizedParameters(ParenthesizedParameterData),
+ Parenthesized(ParenthesizedParameterData),
}
impl PathParameters {
pub fn none() -> PathParameters {
- AngleBracketedParameters(AngleBracketedParameterData {
+ PathParameters::AngleBracketed(AngleBracketedParameterData {
lifetimes: Vec::new(),
- types: OwnedSlice::empty(),
- bindings: OwnedSlice::empty(),
+ types: P::empty(),
+ bindings: P::empty(),
})
}
pub fn is_empty(&self) -> bool {
match *self {
- AngleBracketedParameters(ref data) => data.is_empty(),
+ PathParameters::AngleBracketed(ref data) => data.is_empty(),
// Even if the user supplied no types, something like
// `X()` is equivalent to `X<(),()>`.
- ParenthesizedParameters(..) => false,
+ PathParameters::Parenthesized(..) => false,
}
}
pub fn has_lifetimes(&self) -> bool {
match *self {
- AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
- ParenthesizedParameters(_) => false,
+ PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
+ PathParameters::Parenthesized(_) => false,
}
}
pub fn has_types(&self) -> bool {
match *self {
- AngleBracketedParameters(ref data) => !data.types.is_empty(),
- ParenthesizedParameters(..) => true,
+ PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
+ PathParameters::Parenthesized(..) => true,
}
}
/// parameters in the parenthesized case.
pub fn types(&self) -> Vec<&P<Ty>> {
match *self {
- AngleBracketedParameters(ref data) => {
+ PathParameters::AngleBracketed(ref data) => {
data.types.iter().collect()
}
- ParenthesizedParameters(ref data) => {
+ PathParameters::Parenthesized(ref data) => {
data.inputs.iter()
.chain(data.output.iter())
.collect()
pub fn lifetimes(&self) -> Vec<&Lifetime> {
match *self {
- AngleBracketedParameters(ref data) => {
+ PathParameters::AngleBracketed(ref data) => {
data.lifetimes.iter().collect()
}
- ParenthesizedParameters(_) => {
+ PathParameters::Parenthesized(_) => {
Vec::new()
}
}
pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
match *self {
- AngleBracketedParameters(ref data) => {
+ PathParameters::AngleBracketed(ref data) => {
data.bindings.iter().collect()
}
- ParenthesizedParameters(_) => {
+ PathParameters::Parenthesized(_) => {
Vec::new()
}
}
/// The lifetime parameters for this path segment.
pub lifetimes: Vec<Lifetime>,
/// The type parameters for this path segment, if present.
- pub types: OwnedSlice<P<Ty>>,
+ pub types: P<[P<Ty>]>,
/// Bindings (equality constraints) on associated types, if present.
- /// E.g., `Foo<A=Bar>`.
- pub bindings: OwnedSlice<P<TypeBinding>>,
+ /// e.g., `Foo<A=Bar>`.
+ pub bindings: P<[P<TypeBinding>]>,
}
impl AngleBracketedParameterData {
Maybe,
}
-pub type TyParamBounds = OwnedSlice<TyParamBound>;
+pub type TyParamBounds = P<[TyParamBound]>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TyParam {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Generics {
pub lifetimes: Vec<LifetimeDef>,
- pub ty_params: OwnedSlice<TyParam>,
+ pub ty_params: P<[TyParam]>,
pub where_clause: WhereClause,
}
}
}
+impl Default for Generics {
+ fn default() -> Generics {
+ Generics {
+ lifetimes: Vec::new(),
+ ty_params: P::empty(),
+ where_clause: WhereClause {
+ id: DUMMY_NODE_ID,
+ predicates: Vec::new(),
+ }
+ }
+ }
+}
+
/// A `where` clause in a definition
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereClause {
/// A single predicate in a `where` clause
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum WherePredicate {
- /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
+ /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
BoundPredicate(WhereBoundPredicate),
/// A lifetime predicate, e.g. `'a: 'b+'c`
RegionPredicate(WhereRegionPredicate),
EqPredicate(WhereEqPredicate),
}
-/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
+/// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereBoundPredicate {
pub span: Span,
/// The type being bounded
pub bounded_ty: P<Ty>,
/// Trait and lifetime bounds (`Clone+Send+'static`)
- pub bounds: OwnedSlice<TyParamBound>,
+ pub bounds: TyParamBounds,
}
/// A lifetime predicate, e.g. `'a: 'b+'c`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum BindingMode {
- BindByRef(Mutability),
- BindByValue(Mutability),
+ ByRef(Mutability),
+ ByValue(Mutability),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
BiGt,
}
+impl BinOp_ {
+ pub fn to_string(&self) -> &'static str {
+ match *self {
+ BiAdd => "+",
+ BiSub => "-",
+ BiMul => "*",
+ BiDiv => "/",
+ BiRem => "%",
+ BiAnd => "&&",
+ BiOr => "||",
+ BiBitXor => "^",
+ BiBitAnd => "&",
+ BiBitOr => "|",
+ BiShl => "<<",
+ BiShr => ">>",
+ BiEq => "==",
+ BiLt => "<",
+ BiLe => "<=",
+ BiNe => "!=",
+ BiGe => ">=",
+ BiGt => ">"
+ }
+ }
+ pub fn lazy(&self) -> bool {
+ match *self {
+ BiAnd | BiOr => true,
+ _ => false
+ }
+ }
+
+ pub fn is_shift(&self) -> bool {
+ match *self {
+ BiShl | BiShr => true,
+ _ => false
+ }
+ }
+ pub fn is_comparison(&self) -> bool {
+ match *self {
+ BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
+ true,
+ BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
+ BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
+ false,
+ }
+ }
+ /// Returns `true` if the binary operator takes its arguments by value
+ pub fn is_by_value(&self) -> bool {
+ !BinOp_::is_comparison(self)
+ }
+}
+
pub type BinOp = Spanned<BinOp_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
UnNeg
}
+impl UnOp {
+ /// Returns `true` if the unary operator takes its argument by value
+ pub fn is_by_value(u: UnOp) -> bool {
+ match u {
+ UnNeg | UnNot => true,
+ _ => false,
+ }
+ }
+
+ pub fn to_string(op: UnOp) -> &'static str {
+ match op {
+ UnDeref => "*",
+ UnNot => "!",
+ UnNeg => "-",
+ }
+ }
+}
+
/// A statement
pub type Stmt = Spanned<Stmt_>;
impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "stmt({}: {})",
- ast_util::stmt_id(self)
+ self.node.id()
.map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
pprust::stmt_to_string(self))
}
}
impl Stmt_ {
+ pub fn id(&self) -> Option<NodeId> {
+ match *self {
+ StmtDecl(_, id) => Some(id),
+ StmtExpr(_, id) => Some(id),
+ StmtSemi(_, id) => Some(id),
+ StmtMac(..) => None,
+ }
+ }
+
pub fn attrs(&self) -> &[Attribute] {
match *self {
StmtDecl(ref d, _) => d.attrs(),
ExprLit(P<Lit>),
/// A cast (`foo as f64`)
ExprCast(P<Expr>, P<Ty>),
+ ExprType(P<Expr>, P<Ty>),
/// An `if` block, with an optional else block
///
/// `if expr { block } else { expr }`
}
}
-/// A sequence of token treesee
+/// A sequence of token trees
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
/// The sequence of token trees
LitBool(bool),
}
+impl Lit_ {
+ /// Returns true if this literal is a string and false otherwise.
+ pub fn is_str(&self) -> bool {
+ match *self {
+ LitStr(..) => true,
+ _ => false,
+ }
+ }
+}
+
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
}
/// Represents a method declaration in a trait declaration, possibly including
-/// a default implementation A trait method is either required (meaning it
+/// a default implementation. A trait method is either required (meaning it
/// doesn't have an implementation, just a signature) or provided (meaning it
/// has a default implementation).
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
impl fmt::Display for IntTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::int_ty_to_string(*self))
+ write!(f, "{}", self.ty_to_string())
}
}
impl IntTy {
+ pub fn ty_to_string(&self) -> &'static str {
+ match *self {
+ TyIs => "isize",
+ TyI8 => "i8",
+ TyI16 => "i16",
+ TyI32 => "i32",
+ TyI64 => "i64"
+ }
+ }
+
+ pub fn val_to_string(&self, val: i64) -> String {
+ // cast to a u64 so we can correctly print INT64_MIN. All integral types
+ // are parsed as u64, so we wouldn't want to print an extra negative
+ // sign.
+ format!("{}{}", val as u64, self.ty_to_string())
+ }
+
+ pub fn ty_max(&self) -> u64 {
+ match *self {
+ TyI8 => 0x80,
+ TyI16 => 0x8000,
+ TyIs | TyI32 => 0x80000000, // actually ni about TyIs
+ TyI64 => 0x8000000000000000
+ }
+ }
+
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyIs => return None,
}
impl UintTy {
+ pub fn ty_to_string(&self) -> &'static str {
+ match *self {
+ TyUs => "usize",
+ TyU8 => "u8",
+ TyU16 => "u16",
+ TyU32 => "u32",
+ TyU64 => "u64"
+ }
+ }
+
+ pub fn val_to_string(&self, val: u64) -> String {
+ format!("{}{}", val, self.ty_to_string())
+ }
+
+ pub fn ty_max(&self) -> u64 {
+ match *self {
+ TyU8 => 0xff,
+ TyU16 => 0xffff,
+ TyUs | TyU32 => 0xffffffff, // actually ni about TyUs
+ TyU64 => 0xffffffffffffffff
+ }
+ }
+
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyUs => return None,
impl fmt::Display for UintTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::uint_ty_to_string(*self))
+ write!(f, "{}", self.ty_to_string())
}
}
impl fmt::Display for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::float_ty_to_string(*self))
+ write!(f, "{}", self.ty_to_string())
}
}
impl FloatTy {
+ pub fn ty_to_string(&self) -> &'static str {
+ match *self {
+ TyF32 => "f32",
+ TyF64 => "f64",
+ }
+ }
+
pub fn bit_width(&self) -> usize {
match *self {
TyF32 => 32,
Intel,
}
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct InlineAsmOutput {
+ pub constraint: InternedString,
+ pub expr: P<Expr>,
+ pub is_rw: bool,
+ pub is_indirect: bool,
+}
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
pub asm: InternedString,
pub asm_str_style: StrStyle,
- pub outputs: Vec<(InternedString, P<Expr>, bool)>,
+ pub outputs: Vec<InlineAsmOutput>,
pub inputs: Vec<(InternedString, P<Expr>)>,
pub clobbers: Vec<InternedString>,
pub volatile: bool,
}),
pat: P(Pat {
id: DUMMY_NODE_ID,
- node: PatIdent(BindByValue(mutability), path, None),
+ node: PatIdent(BindingMode::ByValue(mutability), path, None),
span: span
}),
id: DUMMY_NODE_ID