pub use self::UnsafeSource::*;
pub use self::ViewPath_::*;
pub use self::PathParameters::*;
+pub use symbol::Symbol as Name;
pub use util::ThinVec;
use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
use codemap::{respan, Spanned};
use abi::Abi;
use ext::hygiene::SyntaxContext;
-use parse::token::{self, keywords, InternedString};
use print::pprust;
use ptr::P;
-use tokenstream::{TokenTree};
+use symbol::{Symbol, keywords};
+use tokenstream::{ThinTokenStream, TokenStream};
+use std::collections::HashSet;
use std::fmt;
use std::rc::Rc;
-use serialize::{Encodable, Decodable, Encoder, Decoder};
+use std::u32;
-/// A name is a part of an identifier, representing a string or gensym. It's
-/// the result of interning.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Name(pub u32);
+use serialize::{self, Encodable, Decodable, Encoder, Decoder};
/// An identifier contains a Name (index into the interner
/// table) and a SyntaxContext to track renaming and
/// macro expansion per Flatt et al., "Macros That Work Together"
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Ident {
- pub name: Name,
+ pub name: Symbol,
pub ctxt: SyntaxContext
}
-impl Name {
- pub fn as_str(self) -> token::InternedString {
- token::InternedString::new_from_name(self)
- }
-}
-
-impl fmt::Debug for Name {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}({})", self, self.0)
- }
-}
-
-impl fmt::Display for Name {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.as_str(), f)
- }
-}
-
-impl Encodable for Name {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- s.emit_str(&self.as_str())
+impl Ident {
+ pub const fn with_empty_ctxt(name: Name) -> Ident {
+ Ident { name: name, ctxt: SyntaxContext::empty() }
}
-}
-impl Decodable for Name {
- fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
- Ok(token::intern(&d.read_str()?[..]))
+ /// Maps a string to an identifier with an empty syntax context.
+ pub fn from_str(s: &str) -> Ident {
+ Ident::with_empty_ctxt(Symbol::intern(s))
}
-}
-impl Ident {
- pub const fn with_empty_ctxt(name: Name) -> Ident {
- Ident { name: name, ctxt: SyntaxContext::empty() }
+ pub fn unhygienize(&self) -> Ident {
+ Ident { name: self.name, ctxt: SyntaxContext::empty() }
}
}
/// A lifetime definition, e.g. `'a: 'b+'c+'d`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct LifetimeDef {
+ pub attrs: ThinVec<Attribute>,
pub lifetime: Lifetime,
pub bounds: Vec<Lifetime>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
pub span: Span,
- /// A `::foo` path, is relative to the crate root rather than current
- /// module (like paths in an import).
- pub global: bool,
/// The segments in the path: the things separated by `::`.
+ /// Global paths begin with `keywords::CrateRoot`.
pub segments: Vec<PathSegment>,
}
pub fn from_ident(s: Span, identifier: Ident) -> Path {
Path {
span: s,
- global: false,
- segments: vec!(
- PathSegment {
- identifier: identifier,
- parameters: PathParameters::none()
- }
- ),
+ segments: vec![PathSegment::from_ident(identifier, s)],
}
}
+
+ pub fn default_to_global(mut self) -> Path {
+ let name = self.segments[0].identifier.name;
+ if !self.is_global() && name != "$crate" &&
+ name != keywords::SelfValue.name() && name != keywords::Super.name() {
+ self.segments.insert(0, PathSegment::crate_root());
+ }
+ self
+ }
+
+ pub fn is_global(&self) -> bool {
+ !self.segments.is_empty() && self.segments[0].identifier.name == keywords::CrateRoot.name()
+ }
}
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
pub struct PathSegment {
/// The identifier portion of this path segment.
pub identifier: Ident,
+ /// Span of the segment identifier.
+ pub span: Span,
/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
/// this is more than just simple syntactic sugar; the use of
/// parens affects the region binding rules, so we preserve the
/// distinction.
- pub parameters: PathParameters,
+ /// The `Option<P<..>>` wrapper is purely a size optimization;
+ /// `None` is used to represent both `Path` and `Path<>`.
+ pub parameters: Option<P<PathParameters>>,
+}
+
+impl PathSegment {
+ pub fn from_ident(ident: Ident, span: Span) -> Self {
+ PathSegment { identifier: ident, span: span, parameters: None }
+ }
+ pub fn crate_root() -> Self {
+ PathSegment {
+ identifier: keywords::CrateRoot.ident(),
+ span: DUMMY_SP,
+ parameters: None,
+ }
+ }
}
/// Parameters of a path segment.
Parenthesized(ParenthesizedParameterData),
}
-impl PathParameters {
- pub fn none() -> PathParameters {
- PathParameters::AngleBracketed(AngleBracketedParameterData {
- lifetimes: Vec::new(),
- types: P::new(),
- bindings: P::new(),
- })
- }
-
- pub fn is_empty(&self) -> bool {
- match *self {
- PathParameters::AngleBracketed(ref data) => data.is_empty(),
-
- // Even if the user supplied no types, something like
- // `X()` is equivalent to `X<(),()>`.
- PathParameters::Parenthesized(..) => false,
- }
- }
-
- pub fn has_lifetimes(&self) -> bool {
- match *self {
- PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
- PathParameters::Parenthesized(_) => false,
- }
- }
-
- pub fn has_types(&self) -> bool {
- match *self {
- PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
- PathParameters::Parenthesized(..) => true,
- }
- }
-
- /// Returns the types that the user wrote. Note that these do not necessarily map to the type
- /// parameters in the parenthesized case.
- pub fn types(&self) -> Vec<&P<Ty>> {
- match *self {
- PathParameters::AngleBracketed(ref data) => {
- data.types.iter().collect()
- }
- PathParameters::Parenthesized(ref data) => {
- data.inputs.iter()
- .chain(data.output.iter())
- .collect()
- }
- }
- }
-
- pub fn lifetimes(&self) -> Vec<&Lifetime> {
- match *self {
- PathParameters::AngleBracketed(ref data) => {
- data.lifetimes.iter().collect()
- }
- PathParameters::Parenthesized(_) => {
- Vec::new()
- }
- }
- }
-
- pub fn bindings(&self) -> Vec<&TypeBinding> {
- match *self {
- PathParameters::AngleBracketed(ref data) => {
- data.bindings.iter().collect()
- }
- PathParameters::Parenthesized(_) => {
- Vec::new()
- }
- }
- }
-}
-
/// A path like `Foo<'a, T>`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
pub struct AngleBracketedParameterData {
/// The lifetime parameters for this path segment.
pub lifetimes: Vec<Lifetime>,
/// The type parameters for this path segment, if present.
- pub types: P<[P<Ty>]>,
+ pub types: Vec<P<Ty>>,
/// Bindings (equality constraints) on associated types, if present.
///
/// E.g., `Foo<A=Bar>`.
- pub bindings: P<[TypeBinding]>,
+ pub bindings: Vec<TypeBinding>,
}
-impl AngleBracketedParameterData {
- fn is_empty(&self) -> bool {
- self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
+impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
+ fn into(self) -> Option<P<PathParameters>> {
+ let empty = self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty();
+ if empty { None } else { Some(P(PathParameters::AngleBracketed(self))) }
}
}
pub output: Option<P<Ty>>,
}
-pub type CrateNum = u32;
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
+pub struct NodeId(u32);
+
+impl NodeId {
+ pub fn new(x: usize) -> NodeId {
+ assert!(x < (u32::MAX as usize));
+ NodeId(x as u32)
+ }
+
+ pub fn from_u32(x: u32) -> NodeId {
+ NodeId(x)
+ }
+
+ pub fn as_usize(&self) -> usize {
+ self.0 as usize
+ }
+
+ pub fn as_u32(&self) -> u32 {
+ self.0
+ }
+}
+
+impl fmt::Display for NodeId {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.0, f)
+ }
+}
-pub type NodeId = u32;
+impl serialize::UseSpecializedEncodable for NodeId {
+ fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ s.emit_u32(self.0)
+ }
+}
+
+impl serialize::UseSpecializedDecodable for NodeId {
+ fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
+ d.read_u32().map(NodeId)
+ }
+}
/// Node id used to represent the root of the crate.
-pub const CRATE_NODE_ID: NodeId = 0;
+pub const CRATE_NODE_ID: NodeId = NodeId(0);
/// When parsing and doing expansions, we initially give all AST nodes this AST
/// node value. Then later, in the renumber pass, we renumber them to have
/// small, positive ids.
-pub const DUMMY_NODE_ID: NodeId = !0;
+pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
/// The AST represents all type param bounds as types.
/// typeck::collect::compute_bounds matches these against
Maybe,
}
-pub type TyParamBounds = P<[TyParamBound]>;
+pub type TyParamBounds = Vec<TyParamBound>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TyParam {
+ pub attrs: ThinVec<Attribute>,
pub ident: Ident,
pub id: NodeId,
pub bounds: TyParamBounds,
pub default: Option<P<Ty>>,
- pub span: Span
+ pub span: Span,
}
/// Represents lifetimes and type parameters attached to a declaration
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Generics {
pub lifetimes: Vec<LifetimeDef>,
- pub ty_params: P<[TyParam]>,
+ pub ty_params: Vec<TyParam>,
pub where_clause: WhereClause,
+ pub span: Span,
}
impl Generics {
pub fn is_parameterized(&self) -> bool {
self.is_lt_parameterized() || self.is_type_parameterized()
}
+ pub fn span_for_name(&self, name: &str) -> Option<Span> {
+ for t in &self.ty_params {
+ if t.ident.name == name {
+ return Some(t.span);
+ }
+ }
+ None
+ }
}
impl Default for Generics {
+ /// Creates an instance of `Generics`.
fn default() -> Generics {
Generics {
lifetimes: Vec::new(),
- ty_params: P::new(),
+ ty_params: Vec::new(),
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
- }
+ },
+ span: DUMMY_SP,
}
}
}
pub struct WhereEqPredicate {
pub id: NodeId,
pub span: Span,
- pub path: Path,
- pub ty: P<Ty>,
+ pub lhs_ty: P<Ty>,
+ pub rhs_ty: P<Ty>,
}
/// The set of MetaItems that define the compilation environment of the crate,
/// used to drive conditional compilation
-pub type CrateConfig = Vec<P<MetaItem>>;
+pub type CrateConfig = HashSet<(Name, Option<Symbol>)>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Crate {
pub module: Mod,
pub attrs: Vec<Attribute>,
- pub config: CrateConfig,
pub span: Span,
- pub exported_macros: Vec<MacroDef>,
+}
+
+/// A spanned compile-time attribute list item.
+pub type NestedMetaItem = Spanned<NestedMetaItemKind>;
+
+/// Possible values inside of compile-time attribute lists.
+///
+/// E.g. the '..' in `#[name(..)]`.
+#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialEq)]
+pub enum NestedMetaItemKind {
+ /// A full MetaItem, for recursive meta items.
+ MetaItem(MetaItem),
+ /// A literal.
+ ///
+ /// E.g. "foo", 64, true
+ Literal(Lit),
}
/// A spanned compile-time attribute item.
///
/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-pub type MetaItem = Spanned<MetaItemKind>;
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct MetaItem {
+ pub name: Name,
+ pub node: MetaItemKind,
+ pub span: Span,
+}
/// A compile-time attribute item.
///
/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MetaItemKind {
/// Word meta item.
///
/// E.g. `test` as in `#[test]`
- Word(InternedString),
+ Word,
/// List meta item.
///
/// E.g. `derive(..)` as in `#[derive(..)]`
- List(InternedString, Vec<P<MetaItem>>),
+ List(Vec<NestedMetaItem>),
/// Name value meta item.
///
/// E.g. `feature = "foo"` as in `#[feature = "foo"]`
- NameValue(InternedString, Lit),
-}
-
-// can't be derived because the MetaItemKind::List requires an unordered comparison
-impl PartialEq for MetaItemKind {
- fn eq(&self, other: &MetaItemKind) -> bool {
- use self::MetaItemKind::*;
- match *self {
- Word(ref ns) => match *other {
- Word(ref no) => (*ns) == (*no),
- _ => false
- },
- NameValue(ref ns, ref vs) => match *other {
- NameValue(ref no, ref vo) => {
- (*ns) == (*no) && vs.node == vo.node
- }
- _ => false
- },
- List(ref ns, ref miss) => match *other {
- List(ref no, ref miso) => {
- ns == no &&
- miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
- }
- _ => false
- }
- }
- }
+ NameValue(Lit)
}
/// A Block (`{ .. }`).
PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
s.walk(it)
}
- PatKind::Vec(ref before, ref slice, ref after) => {
+ PatKind::Slice(ref before, ref slice, ref after) => {
before.iter().all(|p| p.walk(it)) &&
slice.iter().all(|p| p.walk(it)) &&
after.iter().all(|p| p.walk(it))
}
PatKind::Wild |
PatKind::Lit(_) |
- PatKind::Range(_, _) |
- PatKind::Ident(_, _, _) |
+ PatKind::Range(..) |
+ PatKind::Ident(..) |
PatKind::Path(..) |
PatKind::Mac(_) => {
true
/// The pattern the field is destructured to
pub pat: P<Pat>,
pub is_shorthand: bool,
+ pub attrs: ThinVec<Attribute>,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
ByValue(Mutability),
}
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum RangeEnd {
+ Included,
+ Excluded,
+}
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum PatKind {
/// Represents a wildcard pattern (`_`)
Ref(P<Pat>, Mutability),
/// A literal
Lit(P<Expr>),
- /// A range pattern, e.g. `1...2`
- Range(P<Expr>, P<Expr>),
+ /// A range pattern, e.g. `1...2` or `1..2`
+ Range(P<Expr>, P<Expr>, RangeEnd),
/// `[a, b, ..i, y, z]` is represented as:
- /// `PatKind::Vec(box [a, b], Some(i), box [y, z])`
- Vec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
+ /// `PatKind::Slice(box [a, b], Some(i), box [y, z])`
+ Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
/// A macro pattern; pre-expansion
Mac(Mac),
}
pub ident: SpannedIdent,
pub expr: P<Expr>,
pub span: Span,
+ pub is_shorthand: bool,
+ pub attrs: ThinVec<Attribute>,
}
pub type SpannedIdent = Spanned<Ident>;
/// First expr is the place; second expr is the value.
InPlace(P<Expr>, P<Expr>),
/// An array (`[a, b, c, d]`)
- Vec(Vec<P<Expr>>),
+ Array(Vec<P<Expr>>),
/// A function call
///
/// The first field resolves to the function itself,
Loop(P<Block>, Option<SpannedIdent>),
/// A `match` block.
Match(P<Expr>, Vec<Arm>),
- /// A closure (for example, `move |a, b, c| {a + b + c}`)
+ /// A closure (for example, `move |a, b, c| a + b + c`)
///
/// The final span is the span of the argument block `|...|`
- Closure(CaptureBy, P<FnDecl>, P<Block>, Span),
+ Closure(CaptureBy, P<FnDecl>, P<Expr>, Span),
/// A block (`{ ... }`)
Block(P<Block>),
/// A referencing operation (`&a` or `&mut a`)
AddrOf(Mutability, P<Expr>),
- /// A `break`, with an optional label to break
- Break(Option<SpannedIdent>),
+ /// A `break`, with an optional label to break, and an optional expression
+ Break(Option<SpannedIdent>, Option<P<Expr>>),
/// A `continue`, with an optional label
Continue(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned
Ret(Option<P<Expr>>),
/// Output of the `asm!()` macro
- InlineAsm(InlineAsm),
+ InlineAsm(P<InlineAsm>),
/// A macro invocation; pre-expansion
Mac(Mac),
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Mac_ {
pub path: Path,
- pub tts: Vec<TokenTree>,
+ pub tts: ThinTokenStream,
+}
+
+impl Mac_ {
+ pub fn stream(&self) -> TokenStream {
+ self.tts.clone().into()
+ }
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum LitKind {
/// A string literal (`"foo"`)
- Str(InternedString, StrStyle),
+ Str(Symbol, StrStyle),
/// A byte string (`b"foo"`)
ByteStr(Rc<Vec<u8>>),
/// A byte char (`b'f'`)
/// A character literal (`'a'`)
Char(char),
/// An integer literal (`1`)
- Int(u64, LitIntType),
+ Int(u128, LitIntType),
/// A float literal (`1f64` or `1E10f64`)
- Float(InternedString, FloatTy),
+ Float(Symbol, FloatTy),
/// A float literal without a suffix (`1.0 or 1.0E10`)
- FloatUnsuffixed(InternedString),
+ FloatUnsuffixed(Symbol),
/// A boolean literal
Bool(bool),
}
_ => false,
}
}
+
+ /// Returns true if this literal has no suffix. Note: this will return true
+ /// for literals with prefixes such as raw strings and byte strings.
+ pub fn is_unsuffixed(&self) -> bool {
+ match *self {
+ // unsuffixed variants
+ LitKind::Str(..) => true,
+ LitKind::ByteStr(..) => true,
+ LitKind::Byte(..) => true,
+ LitKind::Char(..) => true,
+ LitKind::Int(_, LitIntType::Unsuffixed) => true,
+ LitKind::FloatUnsuffixed(..) => true,
+ LitKind::Bool(..) => true,
+ // suffixed variants
+ LitKind::Int(_, LitIntType::Signed(..)) => false,
+ LitKind::Int(_, LitIntType::Unsigned(..)) => false,
+ LitKind::Float(..) => false,
+ }
+ }
+
+ /// Returns true if this literal has a suffix.
+ pub fn is_suffixed(&self) -> bool {
+ !self.is_unsuffixed()
+ }
}
// NB: If you change this, you'll probably want to change the corresponding
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct MethodSig {
pub unsafety: Unsafety,
- pub constness: Constness,
+ pub constness: Spanned<Constness>,
pub abi: Abi,
pub decl: P<FnDecl>,
pub generics: Generics,
I16,
I32,
I64,
+ I128,
}
impl fmt::Debug for IntTy {
IntTy::I8 => "i8",
IntTy::I16 => "i16",
IntTy::I32 => "i32",
- IntTy::I64 => "i64"
+ IntTy::I64 => "i64",
+ IntTy::I128 => "i128",
}
}
- 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
+ pub fn val_to_string(&self, val: i128) -> String {
+ // cast to a u128 so we can correctly print INT128_MIN. All integral types
+ // are parsed as u128, 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 {
- IntTy::I8 => 0x80,
- IntTy::I16 => 0x8000,
- IntTy::Is | IntTy::I32 => 0x80000000, // FIXME: actually ni about Is
- IntTy::I64 => 0x8000000000000000
- }
+ format!("{}{}", val as u128, self.ty_to_string())
}
pub fn bit_width(&self) -> Option<usize> {
IntTy::I16 => 16,
IntTy::I32 => 32,
IntTy::I64 => 64,
+ IntTy::I128 => 128,
})
}
}
U16,
U32,
U64,
+ U128,
}
impl UintTy {
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
- UintTy::U64 => "u64"
+ UintTy::U64 => "u64",
+ UintTy::U128 => "u128",
}
}
- pub fn val_to_string(&self, val: u64) -> String {
+ pub fn val_to_string(&self, val: u128) -> String {
format!("{}{}", val, self.ty_to_string())
}
- pub fn ty_max(&self) -> u64 {
- match *self {
- UintTy::U8 => 0xff,
- UintTy::U16 => 0xffff,
- UintTy::Us | UintTy::U32 => 0xffffffff, // FIXME: actually ni about Us
- UintTy::U64 => 0xffffffffffffffff
- }
- }
-
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
UintTy::Us => return None,
UintTy::U16 => 16,
UintTy::U32 => 32,
UintTy::U64 => 64,
+ UintTy::U128 => 128,
})
}
}
/// The different kinds of types recognized by the compiler
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TyKind {
- /// A variable-length array (`[T]`)
- Vec(P<Ty>),
+ /// A variable-length slice (`[T]`)
+ Slice(P<Ty>),
/// A fixed length array (`[T; n]`)
- FixedLengthVec(P<Ty>, P<Expr>),
+ Array(P<Ty>, P<Expr>),
/// A raw pointer (`*const T` or `*mut T`)
Ptr(MutTy),
/// A reference (`&'a T` or `&'a mut T`)
///
/// Type parameters are stored in the Path itself
Path(Option<QSelf>, Path),
- /// Something like `A+B`. Note that `B` must always be a path.
- ObjectSum(P<Ty>, TyParamBounds),
- /// A type like `for<'a> Foo<&'a Bar>`
- PolyTraitRef(TyParamBounds),
- /// An `impl TraitA+TraitB` type.
+ /// A trait object type `Bound1 + Bound2 + Bound3`
+ /// where `Bound` is a trait or a lifetime.
+ TraitObject(TyParamBounds),
+ /// An `impl Bound1 + Bound2 + Bound3` type
+ /// where `Bound` is a trait or a lifetime.
ImplTrait(TyParamBounds),
/// No-op; kept solely so that we can pretty-print faithfully
Paren(P<Ty>),
/// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsmOutput {
- pub constraint: InternedString,
+ pub constraint: Symbol,
pub expr: P<Expr>,
pub is_rw: bool,
pub is_indirect: bool,
/// E.g. `asm!("NOP");`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
- pub asm: InternedString,
+ pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: Vec<InlineAsmOutput>,
- pub inputs: Vec<(InternedString, P<Expr>)>,
- pub clobbers: Vec<InternedString>,
+ pub inputs: Vec<(Symbol, P<Expr>)>,
+ pub clobbers: Vec<Symbol>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
}
pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
+ let span = mk_sp(eself.span.lo, eself_ident.span.hi);
let infer_ty = P(Ty {
id: DUMMY_NODE_ID,
node: TyKind::ImplicitSelf,
- span: DUMMY_SP,
+ span: span,
});
- let arg = |mutbl, ty, span| Arg {
+ let arg = |mutbl, ty| Arg {
pat: P(Pat {
id: DUMMY_NODE_ID,
node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
id: DUMMY_NODE_ID,
};
match eself.node {
- SelfKind::Explicit(ty, mutbl) => {
- arg(mutbl, ty, mk_sp(eself.span.lo, eself_ident.span.hi))
- }
- SelfKind::Value(mutbl) => arg(mutbl, infer_ty, eself.span),
+ SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
+ SelfKind::Value(mutbl) => arg(mutbl, infer_ty),
SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty {
id: DUMMY_NODE_ID,
node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }),
- span: DUMMY_SP,
- }), eself.span),
+ span: span,
+ })),
}
}
}
pub type Variant = Spanned<Variant_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum PathListItemKind {
- Ident {
- name: Ident,
- /// renamed in list, e.g. `use foo::{bar as baz};`
- rename: Option<Ident>,
- id: NodeId
- },
- Mod {
- /// renamed in list, e.g. `use foo::{self as baz};`
- rename: Option<Ident>,
- id: NodeId
- }
-}
-
-impl PathListItemKind {
- pub fn id(&self) -> NodeId {
- match *self {
- PathListItemKind::Ident { id, .. } | PathListItemKind::Mod { id, .. } => id
- }
- }
-
- pub fn name(&self) -> Option<Ident> {
- match *self {
- PathListItemKind::Ident { name, .. } => Some(name),
- PathListItemKind::Mod { .. } => None,
- }
- }
-
- pub fn rename(&self) -> Option<Ident> {
- match *self {
- PathListItemKind::Ident { rename, .. } | PathListItemKind::Mod { rename, .. } => rename
- }
- }
+pub struct PathListItem_ {
+ pub name: Ident,
+ /// renamed in list, e.g. `use foo::{bar as baz};`
+ pub rename: Option<Ident>,
+ pub id: NodeId,
}
-pub type PathListItem = Spanned<PathListItemKind>;
+pub type PathListItem = Spanned<PathListItem_>;
pub type ViewPath = Spanned<ViewPath_>;
}
}
-/// Meta-data associated with an item
-pub type Attribute = Spanned<Attribute_>;
/// Distinguishes between Attributes that decorate items and Attributes that
/// are contained as statements within items. These two cases need to be
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub struct AttrId(pub usize);
+/// Meta-data associated with an item
/// Doc-comments are promoted to attributes that have is_sugared_doc = true
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Attribute_ {
+pub struct Attribute {
pub id: AttrId,
pub style: AttrStyle,
- pub value: P<MetaItem>,
+ pub value: MetaItem,
pub is_sugared_doc: bool,
+ pub span: Span,
}
/// TraitRef's appear in impls.
}
}
-/*
- FIXME (#3300): Should allow items to be anonymous. Right now
- we just use dummy names for anon items.
- */
/// An item
///
/// The name might be a dummy name in case of anonymous items
/// A function declaration (`fn` or `pub fn`).
///
/// E.g. `fn foo(bar: usize) -> usize { .. }`
- Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
+ Fn(P<FnDecl>, Unsafety, Spanned<Constness>, Abi, Generics, P<Block>),
/// A module declaration (`mod` or `pub mod`).
///
/// E.g. `mod foo;` or `mod foo { .. }`
///
/// E.g. `struct Foo<A> { x: A }`
Struct(VariantData, Generics),
+ /// A union definition (`union` or `pub union`).
+ ///
+ /// E.g. `union Foo<A, B> { x: A, y: B }`
+ Union(VariantData, Generics),
/// A Trait declaration (`trait` or `pub trait`).
///
/// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
Vec<ImplItem>),
- /// A macro invocation (which includes macro definition).
+ /// A macro invocation.
///
/// E.g. `macro_rules! foo { .. }` or `foo!(..)`
Mac(Mac),
+
+ /// A macro definition.
+ MacroDef(ThinTokenStream),
}
impl ItemKind {
ItemKind::Ty(..) => "type alias",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
+ ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::Mac(..) |
+ ItemKind::MacroDef(..) |
ItemKind::Impl(..) |
ItemKind::DefaultImpl(..) => "item"
}
}
}
-/// A macro definition, in this crate or imported from another.
-///
-/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct MacroDef {
- pub ident: Ident,
- pub attrs: Vec<Attribute>,
- pub id: NodeId,
- pub span: Span,
- pub imported_from: Option<Ident>,
- pub export: bool,
- pub use_locally: bool,
- pub allow_internal_unstable: bool,
- pub body: Vec<TokenTree>,
-}
-
#[cfg(test)]
mod tests {
use serialize;