This PR refactors the 'errors' part of libsyntax into its own crate (librustc_errors). This is the first part of a few refactorings to simplify error reporting and potentially support more output formats (like a standardized JSON output and possibly an --explain mode that can work with the user's code), though this PR stands on its own and doesn't assume further changes.
As part of separating out the errors crate, I have also refactored the code position portion of codemap into its own crate (libsyntax_pos). While it's helpful to have the common code positions in a separate crate for the new errors crate, this may also enable further simplifications in the future.
use syntax::ast::*;
use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::ptr::P;
- use syntax::codemap::{respan, Spanned, Span};
+ use syntax::codemap::{respan, Spanned};
use syntax::parse::token;
use syntax::std_inject;
use syntax::visit::{self, Visitor};
+ use syntax_pos::Span;
pub struct LoweringContext<'a> {
crate_root: Option<&'static str>,
hir::TypeTraitItem(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
}
+ TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
},
span: i.span,
}
pats.iter().map(|x| self.lower_pat(x)).collect(),
ddpos)
}
- PatKind::Path(ref pth) => {
+ PatKind::Path(None, ref pth) => {
hir::PatKind::Path(self.lower_path(pth))
}
- PatKind::QPath(ref qself, ref pth) => {
+ PatKind::Path(Some(ref qself), ref pth) => {
let qself = hir::QSelf {
ty: self.lower_ty(&qself.ty),
position: qself.position,
extern crate log;
extern crate rustc_back;
extern crate rustc_const_eval;
+ extern crate syntax_pos;
pub use rustc::lint as lint;
pub use rustc::middle as middle;
},
FutureIncompatibleInfo {
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
- reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
+ reference: "PR 30724 <https://github.com/rust-lang/rust/pull/30724>",
},
FutureIncompatibleInfo {
id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH),
use syntax::ast::Name;
use syntax::attr;
use syntax::parse::token;
- use syntax::codemap::{Span, DUMMY_SP};
use syntax::ast::{Block, Crate, DeclKind};
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::visit::{self, Visitor};
+ use syntax_pos::{Span, DUMMY_SP};
+
trait ToNameBinding<'a> {
fn to_name_binding(self) -> NameBinding<'a>;
}
(Def::Method(item_def_id), ValueNS)
}
TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
+ TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};
self.define(module_parent, item.ident.name, ns, (def, item.span, vis));
extern crate log;
#[macro_use]
extern crate syntax;
+ extern crate syntax_pos;
+ extern crate rustc_errors as errors;
extern crate arena;
#[macro_use]
extern crate rustc;
use syntax::ext::mtwt;
use syntax::ast::{self, FloatTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
- use syntax::codemap::{self, Span};
- use syntax::errors::DiagnosticBuilder;
use syntax::parse::token::{self, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind};
+ use syntax_pos::Span;
+ use errors::DiagnosticBuilder;
+
use std::collections::{HashMap, HashSet};
use std::cell::{Cell, RefCell};
use std::fmt;
}
fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
- span: syntax::codemap::Span,
+ span: syntax_pos::Span,
resolution_error: ResolutionError<'c>) {
resolve_struct_error(resolver, span, resolution_error).emit();
}
fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
- span: syntax::codemap::Span,
+ span: syntax_pos::Span,
resolution_error: ResolutionError<'c>)
-> DiagnosticBuilder<'a> {
if !resolver.emit_errors {
visit::walk_trait_item(this, trait_item)
});
}
+ TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};
}
});
self.resolve_crate_relative_path(trait_path.span, segments, TypeNS)
} else {
self.resolve_module_relative_path(trait_path.span, segments, TypeNS)
- }.map(|binding| binding.span).unwrap_or(codemap::DUMMY_SP)
+ }.map(|binding| binding.span).unwrap_or(syntax_pos::DUMMY_SP)
};
- if definition_site != codemap::DUMMY_SP {
+ if definition_site != syntax_pos::DUMMY_SP {
err.span_label(definition_site,
&format!("type aliases cannot be used for traits"));
}
}, "variant or struct");
}
- PatKind::Path(ref path) => {
- self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| {
+ PatKind::Path(ref qself, ref path) => {
+ self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| {
match def {
Def::Struct(..) | Def::Variant(..) |
Def::Const(..) | Def::AssociatedConst(..) | Def::Err => true,
}, "variant, struct or constant");
}
- PatKind::QPath(ref qself, ref path) => {
- self.resolve_pattern_path(pat.id, Some(qself), path, ValueNS, |def| {
- match def {
- Def::AssociatedConst(..) | Def::Err => true,
- _ => false,
- }
- }, "associated constant");
- }
-
PatKind::Struct(ref path, _, _) => {
self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| {
match def {
},
};
- if old_binding.span != codemap::DUMMY_SP {
+ if old_binding.span != syntax_pos::DUMMY_SP {
err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
}
err.emit();
use std::hash::*;
use syntax::ast::{self, NodeId, PatKind};
- use syntax::codemap::*;
use syntax::parse::token::{self, keywords};
use syntax::visit::{self, Visitor};
use syntax::print::pprust::{path_to_string, ty_to_string, bounds_to_string, generics_to_string};
use syntax::ptr::P;
+ use syntax::codemap::Spanned;
+ use syntax_pos::*;
use super::{escape, generated_code, SaveContext, PathCollector};
use super::data::*;
trait_item.span);
}
ast::TraitItemKind::Const(_, None) |
- ast::TraitItemKind::Type(..) => {}
+ ast::TraitItemKind::Type(..) |
+ ast::TraitItemKind::Macro(_) => {}
}
}
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
extern crate serialize as rustc_serialize;
+ extern crate syntax_pos;
mod csv_dumper;
mod json_dumper;
use std::path::{Path, PathBuf};
use syntax::ast::{self, NodeId, PatKind};
- use syntax::codemap::*;
use syntax::parse::token::{self, keywords};
use syntax::visit::{self, Visitor};
use syntax::print::pprust::{ty_to_string, arg_to_string};
+ use syntax::codemap::MacroAttribute;
+ use syntax_pos::*;
pub use self::csv_dumper::CsvDumper;
pub use self::json_dumper::JsonDumper;
ast::Mutability::Mutable, recorder::TypeRef));
}
PatKind::TupleStruct(ref path, _, _) |
- PatKind::Path(ref path) |
- PatKind::QPath(_, ref path) => {
+ PatKind::Path(_, ref path) => {
self.collected_paths.push((p.id, path.clone(),
ast::Mutability::Mutable, recorder::VarRef));
}
pub use self::PathParameters::*;
use attr::{ThinAttributes, HasAttrs};
- use codemap::{mk_sp, respan, Span, Spanned, DUMMY_SP, ExpnId};
+ use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
+ use codemap::{respan, Spanned};
use abi::Abi;
use errors;
use ext::base;
}
}
-/// A lifetime definition, eg `'a: 'b+'c+'d`
+/// A lifetime definition, e.g. `'a: 'b+'c+'d`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct LifetimeDef {
pub lifetime: Lifetime,
pub bounds: Vec<Lifetime>
}
-/// A "Path" is essentially Rust's notion of a name; for instance:
-/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
+/// A "Path" is essentially Rust's notion of a name.
+///
+/// It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
+///
+/// E.g. `std::cmp::PartialEq`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
pub span: Span,
}
}
-/// A segment of a path: an identifier, an optional lifetime, and a set of
-/// types.
+/// A segment of a path: an identifier, an optional lifetime, and a set of types.
+///
+/// E.g. `std`, `String` or `Box<T>`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct PathSegment {
/// The identifier portion of this path segment.
pub parameters: PathParameters,
}
+/// Parameters of a path segment.
+///
+/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum PathParameters {
/// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
/// The type parameters for this path segment, if present.
pub types: P<[P<Ty>]>,
/// Bindings (equality constraints) on associated types, if present.
- /// e.g., `Foo<A=Bar>`.
+ ///
+ /// E.g., `Foo<A=Bar>`.
pub bindings: P<[TypeBinding]>,
}
EqPredicate(WhereEqPredicate),
}
-/// A type bound, e.g. `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,
pub bounds: TyParamBounds,
}
-/// A lifetime predicate, e.g. `'a: 'b+'c`
+/// A lifetime predicate.
+///
+/// E.g. `'a: 'b+'c`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereRegionPredicate {
pub span: Span,
pub bounds: Vec<Lifetime>,
}
-/// An equality predicate (unsupported), e.g. `T=int`
+/// An equality predicate (unsupported).
+///
+/// E.g. `T=int`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereEqPredicate {
pub id: NodeId,
pub exported_macros: Vec<MacroDef>,
}
+/// A spanned compile-time attribute item.
+///
+/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
pub type MetaItem = Spanned<MetaItemKind>;
+/// A compile-time attribute item.
+///
+/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MetaItemKind {
+ /// Word meta item.
+ ///
+ /// E.g. `test` as in `#[test]`
Word(InternedString),
+ /// List meta item.
+ ///
+ /// E.g. `derive(..)` as in `#[derive(..)]`
List(InternedString, Vec<P<MetaItem>>),
+ /// Name value meta item.
+ ///
+ /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
NameValue(InternedString, Lit),
}
}
}
+/// A Block (`{ .. }`).
+///
+/// E.g. `{ .. }` as in `fn foo() { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Block {
/// Statements in a block
PatKind::Range(_, _) |
PatKind::Ident(_, _, _) |
PatKind::Path(..) |
- PatKind::QPath(_, _) |
PatKind::Mac(_) => {
true
}
/// 0 <= position <= subpats.len()
TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
- /// A path pattern.
- /// Such pattern can be resolved to a unit struct/variant or a constant.
- Path(Path),
-
- /// An associated const named using the qualified path `<T>::CONST` or
- /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
- /// referred to as simply `T::CONST`, in which case they will end up as
- /// PatKind::Path, and the resolver will have to sort that out.
- QPath(QSelf, Path),
+ /// A possibly qualified path pattern.
+ /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
+ /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
+ /// only legally refer to associated constants.
+ Path(Option<QSelf>, Path),
/// A tuple pattern `(a, b)`.
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
}
}
-/// represents one arm of a 'match'
+/// An arm of a 'match'.
+///
+/// E.g. `0...10 => { println!("match!") }` as in
+///
+/// ```rust,ignore
+/// match n {
+/// 0...10 => { println!("match!") },
+/// // ..
+/// }
+/// ```
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Arm {
pub attrs: Vec<Attribute>,
/// parameters, e.g. foo::bar::<baz>.
///
/// Optionally "qualified",
- /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
+ /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
Path(Option<QSelf>, Path),
/// A referencing operation (`&a` or `&mut a`)
/// separately. `position` represents the index of the associated
/// item qualified with this Self type.
///
-/// ```ignore
+/// ```rust,ignore
/// <Vec<T> as a::b::Trait>::AssociatedItem
/// ^~~~~ ~~~~~~~~~~~~~~^
/// ty position = 3
Unsuffixed,
}
+/// Literal kind.
+///
+/// E.g. `"foo"`, `42`, `12.34` or `bool`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum LitKind {
/// A string literal (`"foo"`)
Const(P<Ty>, Option<P<Expr>>),
Method(MethodSig, Option<P<Block>>),
Type(TyParamBounds, Option<P<Ty>>),
+ Macro(Mac),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub decl: P<FnDecl>
}
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
/// The different kinds of types recognized by the compiler
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TyKind {
Vec(P<Ty>),
/// A fixed length array (`[T; n]`)
Mac(Mac),
}
+/// Inline assembly dialect.
+///
+/// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum AsmDialect {
Att,
Intel,
}
+/// Inline assembly.
+///
+/// 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 is_indirect: bool,
}
+/// Inline assembly.
+///
+/// E.g. `asm!("NOP");`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
pub asm: InternedString,
pub expn_id: ExpnId,
}
-/// represents an argument in a function header
+/// An argument in a function header.
+///
+/// E.g. `bar: usize` as in `fn foo(bar: usize)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Arg {
pub ty: P<Ty>,
}
/// Alternative representation for `Arg`s describing `self` parameter of methods.
+///
+/// E.g. `&mut self` as in `fn foo(&mut self)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum SelfKind {
/// `self`, `mut self`
}
}
-/// Represents the header (not the body) of a function declaration
+/// Header (not the body) of a function declaration.
+///
+/// E.g. `fn foo(bar: baz)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct FnDecl {
pub inputs: Vec<Arg>,
}
}
+/// Module declaration.
+///
+/// E.g. `mod foo;` or `mod foo { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
pub items: Vec<P<Item>>,
}
+/// Foreign module declaration.
+///
+/// E.g. `extern { .. }` or `extern C { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct ForeignMod {
pub abi: Abi,
pub name: Ident,
pub attrs: Vec<Attribute>,
pub data: VariantData,
- /// Explicit discriminant, eg `Foo = 1`
+ /// Explicit discriminant, e.g. `Foo = 1`
pub disr_expr: Option<P<Expr>>,
}
pub enum PathListItemKind {
Ident {
name: Ident,
- /// renamed in list, eg `use foo::{bar as baz};`
+ /// renamed in list, e.g. `use foo::{bar as baz};`
rename: Option<Ident>,
id: NodeId
},
Mod {
- /// renamed in list, eg `use foo::{self as baz};`
+ /// renamed in list, e.g. `use foo::{self as baz};`
rename: Option<Ident>,
id: NodeId
}
Inherited,
}
+/// Field of a struct.
+///
+/// E.g. `bar: usize` as in `struct Foo { bar: usize }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct StructField {
pub span: Span,
/// Id of the whole struct lives in `Item`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum VariantData {
+ /// Struct variant.
+ ///
+ /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
Struct(Vec<StructField>, NodeId),
+ /// Tuple variant.
+ ///
+ /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
Tuple(Vec<StructField>, NodeId),
+ /// Unit variant.
+ ///
+ /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
Unit(NodeId),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum ItemKind {
- /// An`extern crate` item, with optional original crate name,
+ /// An`extern crate` item, with optional original crate name.
///
- /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
+ /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
ExternCrate(Option<Name>),
- /// A `use` or `pub use` item
+ /// A use declaration (`use` or `pub use`) item.
+ ///
+ /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
Use(P<ViewPath>),
-
- /// A `static` item
+ /// A static item (`static` or `pub static`).
+ ///
+ /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
Static(P<Ty>, Mutability, P<Expr>),
- /// A `const` item
+ /// A constant item (`const` or `pub const`).
+ ///
+ /// E.g. `const FOO: i32 = 42;`
Const(P<Ty>, P<Expr>),
- /// A function declaration
+ /// A function declaration (`fn` or `pub fn`).
+ ///
+ /// E.g. `fn foo(bar: usize) -> usize { .. }`
Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
- /// A module
+ /// A module declaration (`mod` or `pub mod`).
+ ///
+ /// E.g. `mod foo;` or `mod foo { .. }`
Mod(Mod),
- /// An external module
+ /// An external module (`extern` or `pub extern`).
+ ///
+ /// E.g. `extern {}` or `extern "C" {}`
ForeignMod(ForeignMod),
- /// A type alias, e.g. `type Foo = Bar<u8>`
+ /// A type alias (`type` or `pub type`).
+ ///
+ /// E.g. `type Foo = Bar<u8>;`
Ty(P<Ty>, Generics),
- /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
+ /// An enum definition (`enum` or `pub enum`).
+ ///
+ /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
Enum(EnumDef, Generics),
- /// A struct definition, e.g. `struct Foo<A> {x: A}`
+ /// A struct definition (`struct` or `pub struct`).
+ ///
+ /// E.g. `struct Foo<A> { x: A }`
Struct(VariantData, Generics),
- /// Represents a Trait Declaration
+ /// A Trait declaration (`trait` or `pub trait`).
+ ///
+ /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
-
- // Default trait implementations
+ // Default trait implementation.
///
- // `impl Trait for .. {}`
+ /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
DefaultImpl(Unsafety, TraitRef),
- /// An implementation, eg `impl<A> Trait for Foo { .. }`
+ /// An implementation.
+ ///
+ /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
Impl(Unsafety,
ImplPolarity,
Generics,
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
Vec<ImplItem>),
- /// A macro invocation (which includes macro definition)
+ /// A macro invocation (which includes macro definition).
+ ///
+ /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
Mac(Mac),
}
use ast;
use ast::{Name, PatKind};
use attr::HasAttrs;
- use codemap;
- use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
+ use codemap::{self, CodeMap, ExpnInfo};
+ use syntax_pos::{Span, ExpnId, NO_EXPANSION};
use errors::DiagnosticBuilder;
use ext;
use ext::expand;
None
}
+ /// Create zero or more trait items.
+ fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
+ None
+ }
+
/// Create a pattern.
fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
None
pat: P<ast::Pat>,
items: SmallVector<P<ast::Item>>,
impl_items: SmallVector<ast::ImplItem>,
+ trait_items: SmallVector<ast::TraitItem>,
stmts: SmallVector<ast::Stmt>,
ty: P<ast::Ty>,
}
self.impl_items
}
+ fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
+ self.trait_items
+ }
+
fn make_stmts(self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
match self.stmts.as_ref().map_or(0, |s| s.len()) {
0 => make_stmts_default!(self),
}
}
+ fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem>> {
+ if self.expr_only {
+ None
+ } else {
+ Some(SmallVector::zero())
+ }
+ }
+
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
Some(SmallVector::one(
codemap::respan(self.span,
use abi::Abi;
use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
use attr;
- use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
+ use syntax_pos::{Span, DUMMY_SP, Pos};
+ use codemap::{respan, Spanned};
use ext::base::ExtCtxt;
use parse::token::{self, keywords, InternedString};
use ptr::P;
}
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
let pat = if subpats.is_empty() {
- PatKind::Path(path)
+ PatKind::Path(None, path)
} else {
PatKind::TupleStruct(path, subpats, None)
};
use ext::build::AstBuilder;
use attr;
use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
- use codemap;
- use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
+ use codemap::{Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+ use syntax_pos::{self, Span, ExpnId};
use config::StripUnconfigured;
use ext::base::*;
use feature_gate::{self, Features};
"statement", .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
SmallVector<P<ast::Item>>:
"item", .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
+ SmallVector<ast::TraitItem>:
+ "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
+ |_span| SmallVector::zero();
SmallVector<ast::ImplItem>:
- "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
+ "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
|_span| SmallVector::zero();
}
_ => noop_fold_item(it, fld),
}.into_iter().map(|i| Annotatable::Item(i)).collect(),
- Annotatable::TraitItem(it) => match it.node {
- ast::TraitItemKind::Method(_, Some(_)) => {
- let ti = it.unwrap();
- SmallVector::one(ast::TraitItem {
- id: ti.id,
- ident: ti.ident,
- attrs: ti.attrs,
- node: match ti.node {
- ast::TraitItemKind::Method(sig, Some(body)) => {
- let (sig, body) = expand_and_rename_method(sig, body, fld);
- ast::TraitItemKind::Method(sig, Some(body))
- }
- _ => unreachable!()
- },
- span: ti.span,
- })
- }
- _ => fold::noop_fold_trait_item(it.unwrap(), fld)
- }.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
+ Annotatable::TraitItem(it) => {
+ expand_trait_item(it.unwrap(), fld).into_iter().
+ map(|it| Annotatable::TraitItem(P(it))).collect()
+ }
Annotatable::ImplItem(ii) => {
expand_impl_item(ii.unwrap(), fld).into_iter().
}
}
+fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
+ -> SmallVector<ast::TraitItem> {
+ match ti.node {
+ ast::TraitItemKind::Method(_, Some(_)) => {
+ SmallVector::one(ast::TraitItem {
+ id: ti.id,
+ ident: ti.ident,
+ attrs: ti.attrs,
+ node: match ti.node {
+ ast::TraitItemKind::Method(sig, Some(body)) => {
+ let (sig, body) = expand_and_rename_method(sig, body, fld);
+ ast::TraitItemKind::Method(sig, Some(body))
+ }
+ _ => unreachable!()
+ },
+ span: ti.span,
+ })
+ }
+ ast::TraitItemKind::Macro(mac) => {
+ expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
+ }
+ _ => fold::noop_fold_trait_item(ti, fld)
+ }
+}
+
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block.
result = expand_item(item, self);
self.pop_mod_path();
} else {
- let filename = if inner != codemap::DUMMY_SP {
+ let filename = if inner != syntax_pos::DUMMY_SP {
Some(self.cx.parse_sess.codemap().span_to_filename(inner))
} else { None };
let orig_filename = replace(&mut self.cx.filename, filename);
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
use ast;
use ast::Name;
- use codemap;
+ use syntax_pos;
use ext::base::{ExtCtxt, DummyMacroLoader};
use ext::mtwt;
use fold::Folder;
}
impl<'v> Visitor<'v> for IdentFinder {
- fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
+ fn visit_ident(&mut self, _: syntax_pos::Span, id: ast::Ident){
self.ident_accumulator.push(id);
}
}
// except according to those terms.
use ast::{self, TokenTree};
- use codemap::{Span, DUMMY_SP};
+ use syntax_pos::{Span, DUMMY_SP};
use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
use ext::base::{NormalTT, TTMacroExpander};
use ext::tt::macro_parser::{Success, Error, Failure};
Some(ret)
}
+ fn make_trait_items(self: Box<ParserAnyMacro<'a>>)
+ -> Option<SmallVector<ast::TraitItem>> {
+ let mut ret = SmallVector::zero();
+ loop {
+ let mut parser = self.parser.borrow_mut();
+ match parser.token {
+ token::Eof => break,
+ _ => ret.push(panictry!(parser.parse_trait_item()))
+ }
+ }
+ self.ensure_complete_parse(false, "item");
+ Some(ret)
+ }
+
+
fn make_stmts(self: Box<ParserAnyMacro<'a>>)
-> Option<SmallVector<ast::Stmt>> {
let mut ret = SmallVector::zero();
use ast::*;
use ast;
use attr::{ThinAttributes, ThinAttributesExt};
- use codemap::{respan, Span, Spanned};
+ use syntax_pos::Span;
+ use codemap::{Spanned, respan};
use parse::token::{self, keywords};
use ptr::P;
use util::small_vector::SmallVector;
TraitItemKind::Type(folder.fold_bounds(bounds),
default.map(|x| folder.fold_ty(x)))
}
+ ast::TraitItemKind::Macro(mac) => {
+ TraitItemKind::Macro(folder.fold_mac(mac))
+ }
},
span: folder.new_span(i.span)
})
PatKind::TupleStruct(folder.fold_path(pth),
pats.move_map(|x| folder.fold_pat(x)), ddpos)
}
- PatKind::Path(pth) => {
- PatKind::Path(folder.fold_path(pth))
- }
- PatKind::QPath(qself, pth) => {
- let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself};
- PatKind::QPath(qself, folder.fold_path(pth))
+ PatKind::Path(opt_qself, pth) => {
+ let opt_qself = opt_qself.map(|qself| {
+ QSelf { ty: folder.fold_ty(qself.ty), position: qself.position }
+ });
+ PatKind::Path(opt_qself, folder.fold_path(pth))
}
PatKind::Struct(pth, fields, etc) => {
let pth = folder.fold_path(pth);
use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
use ast::{BinOpKind, UnOp};
use ast;
- use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
+ use codemap::{self, CodeMap, Spanned, spanned};
+ use syntax_pos::{self, Span, BytePos, mk_sp};
use errors::{self, DiagnosticBuilder};
use ext::tt::macro_parser;
use parse;
{
let tok0 = rdr.real_token();
let span = tok0.sp;
- let filename = if span != codemap::DUMMY_SP {
+ let filename = if span != syntax_pos::DUMMY_SP {
Some(sess.codemap().span_to_filename(span))
} else { None };
let placeholder = TokenAndSpan {
}
/// Parse the items in a trait declaration
- pub fn parse_trait_items(&mut self) -> PResult<'a, Vec<TraitItem>> {
- self.parse_unspanned_seq(
- &token::OpenDelim(token::Brace),
- &token::CloseDelim(token::Brace),
- SeqSep::none(),
- |p| -> PResult<'a, TraitItem> {
- maybe_whole!(no_clone_from_p p, NtTraitItem);
- let mut attrs = p.parse_outer_attributes()?;
- let lo = p.span.lo;
-
- let (name, node) = if p.eat_keyword(keywords::Type) {
- let TyParam {ident, bounds, default, ..} = p.parse_ty_param()?;
- p.expect(&token::Semi)?;
- (ident, TraitItemKind::Type(bounds, default))
- } else if p.is_const_item() {
- p.expect_keyword(keywords::Const)?;
- let ident = p.parse_ident()?;
- p.expect(&token::Colon)?;
- let ty = p.parse_ty_sum()?;
- let default = if p.check(&token::Eq) {
- p.bump();
- let expr = p.parse_expr()?;
- p.commit_expr_expecting(&expr, token::Semi)?;
- Some(expr)
- } else {
- p.expect(&token::Semi)?;
- None
- };
- (ident, TraitItemKind::Const(ty, default))
+ pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
+ maybe_whole!(no_clone_from_p self, NtTraitItem);
+ let mut attrs = self.parse_outer_attributes()?;
+ let lo = self.span.lo;
+
+ let (name, node) = if self.eat_keyword(keywords::Type) {
+ let TyParam {ident, bounds, default, ..} = self.parse_ty_param()?;
+ self.expect(&token::Semi)?;
+ (ident, TraitItemKind::Type(bounds, default))
+ } else if self.is_const_item() {
+ self.expect_keyword(keywords::Const)?;
+ let ident = self.parse_ident()?;
+ self.expect(&token::Colon)?;
+ let ty = self.parse_ty_sum()?;
+ let default = if self.check(&token::Eq) {
+ self.bump();
+ let expr = self.parse_expr()?;
+ self.commit_expr_expecting(&expr, token::Semi)?;
+ Some(expr)
+ } else {
+ self.expect(&token::Semi)?;
+ None
+ };
+ (ident, TraitItemKind::Const(ty, default))
+ } else if !self.token.is_any_keyword()
+ && self.look_ahead(1, |t| *t == token::Not)
+ && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
+ || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
+ // trait item macro.
+ // code copied from parse_macro_use_or_failure... abstraction!
+ let lo = self.span.lo;
+ let pth = self.parse_ident_into_path()?;
+ self.expect(&token::Not)?;
+
+ // eat a matched-delimiter token tree:
+ let delim = self.expect_open_delim()?;
+ let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
+ SeqSep::none(),
+ |pp| pp.parse_token_tree())?;
+ let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
+ let m: ast::Mac = codemap::Spanned { node: m_,
+ span: mk_sp(lo,
+ self.last_span.hi) };
+ if delim != token::Brace {
+ self.expect(&token::Semi)?
+ }
+ (keywords::Invalid.ident(), ast::TraitItemKind::Macro(m))
} else {
- let (constness, unsafety, abi) = match p.parse_fn_front_matter() {
+ let (constness, unsafety, abi) = match self.parse_fn_front_matter() {
Ok(cua) => cua,
Err(e) => {
loop {
- match p.token {
+ match self.token {
token::Eof => break,
-
token::CloseDelim(token::Brace) |
token::Semi => {
- p.bump();
+ self.bump();
break;
}
-
token::OpenDelim(token::Brace) => {
- p.parse_token_tree()?;
+ self.parse_token_tree()?;
break;
}
-
- _ => p.bump()
+ _ => self.bump()
}
}
}
};
- let ident = p.parse_ident()?;
- let mut generics = p.parse_generics()?;
+ let ident = self.parse_ident()?;
+ let mut generics = self.parse_generics()?;
- let d = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
+ let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
// This is somewhat dubious; We don't want to allow
// argument names to be left off if there is a
// definition...
p.parse_arg_general(false)
})?;
- generics.where_clause = p.parse_where_clause()?;
+ generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig {
unsafety: unsafety,
constness: constness,
abi: abi,
};
- let body = match p.token {
- token::Semi => {
- p.bump();
- debug!("parse_trait_methods(): parsing required method");
- None
- }
- token::OpenDelim(token::Brace) => {
- debug!("parse_trait_methods(): parsing provided method");
- let (inner_attrs, body) =
- p.parse_inner_attrs_and_block()?;
- attrs.extend(inner_attrs.iter().cloned());
- Some(body)
- }
+ let body = match self.token {
+ token::Semi => {
+ self.bump();
+ debug!("parse_trait_methods(): parsing required method");
+ None
+ }
+ token::OpenDelim(token::Brace) => {
+ debug!("parse_trait_methods(): parsing provided method");
+ let (inner_attrs, body) =
+ self.parse_inner_attrs_and_block()?;
+ attrs.extend(inner_attrs.iter().cloned());
+ Some(body)
+ }
- _ => {
- let token_str = p.this_token_to_string();
- return Err(p.fatal(&format!("expected `;` or `{{`, found `{}`",
- token_str)[..]))
- }
+ _ => {
+ let token_str = self.this_token_to_string();
+ return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`",
+ token_str)[..]))
+ }
};
(ident, ast::TraitItemKind::Method(sig, body))
};
+ Ok(TraitItem {
+ id: ast::DUMMY_NODE_ID,
+ ident: name,
+ attrs: attrs,
+ node: node,
+ span: mk_sp(lo, self.last_span.hi),
+ })
+ }
- Ok(TraitItem {
- id: ast::DUMMY_NODE_ID,
- ident: name,
- attrs: attrs,
- node: node,
- span: mk_sp(lo, p.last_span.hi),
+
+ /// Parse the items in a trait declaration
+ pub fn parse_trait_items(&mut self) -> PResult<'a, Vec<TraitItem>> {
+ self.parse_unspanned_seq(
+ &token::OpenDelim(token::Brace),
+ &token::CloseDelim(token::Brace),
+ SeqSep::none(),
+ |p| -> PResult<'a, TraitItem> {
+ p.parse_trait_item()
})
- })
}
/// Parse a possibly mutable type
}
/// Parse the fields of a struct-like pattern
- fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>> , bool)> {
+ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>>, bool)> {
let mut fields = Vec::new();
let mut etc = false;
let mut first = true;
};
fields.push(codemap::Spanned { span: mk_sp(lo, hi),
- node: ast::FieldPat { ident: fieldname,
- pat: subpat,
- is_shorthand: is_shorthand }});
+ node: ast::FieldPat { ident: fieldname,
+ pat: subpat,
+ is_shorthand: is_shorthand }});
}
return Ok((fields, etc));
}
SeqSep::none(), |p| p.parse_token_tree())?;
let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
pat = PatKind::Mac(codemap::Spanned {node: mac,
- span: mk_sp(lo, self.last_span.hi)});
+ span: mk_sp(lo, self.last_span.hi)});
} else {
// Parse ident @ pat
// This can give false positives and parse nullary enums,
pat = PatKind::TupleStruct(path, fields, ddpos)
}
_ => {
- pat = match qself {
- // Parse qualified path
- Some(qself) => PatKind::QPath(qself, path),
- // Parse nullary enum
- None => PatKind::Path(path)
- };
+ pat = PatKind::Path(qself, path);
}
}
}
|p| p.parse_token_tree())?;
let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m_,
- span: mk_sp(lo,
- self.last_span.hi) };
+ span: mk_sp(lo,
+ self.last_span.hi) };
if delim != token::Brace {
self.expect(&token::Semi)?
}
/// Parse trait Foo { ... }
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
-
let ident = self.parse_ident()?;
let mut tps = self.parse_generics()?;
return Err(self.fatal(&format!("expected item, found `{}`", token_str)));
}
- let hi = if self.span == codemap::DUMMY_SP {
+ let hi = if self.span == syntax_pos::DUMMY_SP {
inner_lo
} else {
self.last_span.hi
// single-variant-enum... :
let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m,
- span: mk_sp(mac_lo,
- self.last_span.hi) };
+ span: mk_sp(mac_lo,
+ self.last_span.hi) };
if delim != token::Brace {
if !self.eat(&token::Semi) {
use util::parser::AssocOp;
use attr;
use attr::{AttrMetaMethods, AttributeMethods};
- use codemap::{self, CodeMap, BytePos};
+ use codemap::{self, CodeMap};
+ use syntax_pos::{self, BytePos};
use errors;
use parse::token::{self, keywords, BinOpToken, Token, InternedString};
use parse::lexer::comments;
self.end() // close the head-box
}
- pub fn bclose_(&mut self, span: codemap::Span,
+ pub fn bclose_(&mut self, span: syntax_pos::Span,
indented: usize) -> io::Result<()> {
self.bclose_maybe_open(span, indented, true)
}
- pub fn bclose_maybe_open(&mut self, span: codemap::Span,
+ pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
indented: usize, close_box: bool) -> io::Result<()> {
try!(self.maybe_print_comment(span.hi));
try!(self.break_offset_if_not_bol(1, -(indented as isize)));
}
Ok(())
}
- pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
+ pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
self.bclose_(span, INDENT_UNIT)
}
mut op: F,
mut get_span: G) -> io::Result<()> where
F: FnMut(&mut State, &T) -> io::Result<()>,
- G: FnMut(&T) -> codemap::Span,
+ G: FnMut(&T) -> syntax_pos::Span,
{
try!(self.rbox(0, b));
let len = elts.len();
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
generics: &ast::Generics, ident: ast::Ident,
- span: codemap::Span,
+ span: syntax_pos::Span,
visibility: &ast::Visibility) -> io::Result<()> {
try!(self.head(&visibility_qualified(visibility, "enum")));
try!(self.print_ident(ident));
pub fn print_variants(&mut self,
variants: &[ast::Variant],
- span: codemap::Span) -> io::Result<()> {
+ span: syntax_pos::Span) -> io::Result<()> {
try!(self.bopen());
for v in variants {
try!(self.space_if_not_bol());
struct_def: &ast::VariantData,
generics: &ast::Generics,
ident: ast::Ident,
- span: codemap::Span,
+ span: syntax_pos::Span,
print_finalizer: bool) -> io::Result<()> {
try!(self.print_ident(ident));
try!(self.print_generics(generics));
try!(self.print_associated_type(ti.ident, Some(bounds),
default.as_ref().map(|ty| &**ty)));
}
+ ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
+ // code copied from ItemKind::Mac:
+ self.print_path(&node.path, false, 0)?;
+ word(&mut self.s, "! ")?;
+ self.cbox(INDENT_UNIT)?;
+ self.popen()?;
+ self.print_tts(&node.tts[..])?;
+ self.pclose()?;
+ word(&mut self.s, ";")?;
+ self.end()?
+ }
}
self.ann.post(self, NodeSubItem(ti.id))
}
}
try!(self.pclose());
}
- PatKind::Path(ref path) => {
+ PatKind::Path(None, ref path) => {
try!(self.print_path(path, true, 0));
}
- PatKind::QPath(ref qself, ref path) => {
+ PatKind::Path(Some(ref qself), ref path) => {
try!(self.print_qpath(path, qself, false));
}
PatKind::Struct(ref path, ref fields, etc) => {
self.end()
}
- pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
+ pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
next_pos: Option<BytePos>)
-> io::Result<()> {
let cm = match self.cm {
use ast;
use codemap;
use parse::token;
+ use syntax_pos;
#[test]
fn test_fun_to_string() {
let decl = ast::FnDecl {
inputs: Vec::new(),
- output: ast::FunctionRetTy::Default(codemap::DUMMY_SP),
+ output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP),
variadic: false
};
let generics = ast::Generics::default();
fn test_variant_to_string() {
let ident = token::str_to_ident("principal_skinner");
- let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
+ let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
name: ident,
attrs: Vec::new(),
// making this up as I go.... ?
use abi::Abi;
use ast::*;
use attr::ThinAttributesExt;
- use codemap::{Span, Spanned};
+ use syntax_pos::Span;
+ use codemap::Spanned;
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum FnKind<'a> {
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat, children);
}
- PatKind::Path(ref path) => {
- visitor.visit_path(path, pattern.id);
- }
- PatKind::QPath(ref qself, ref path) => {
- visitor.visit_ty(&qself.ty);
+ PatKind::Path(ref opt_qself, ref path) => {
+ if let Some(ref qself) = *opt_qself {
+ visitor.visit_ty(&qself.ty);
+ }
visitor.visit_path(path, pattern.id)
}
PatKind::Struct(ref path, ref fields, _) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_ty, default);
}
+ TraitItemKind::Macro(ref mac) => {
+ visitor.visit_mac(mac);
+ }
}
}