use feature_gate::{self, Features};
use fold;
use fold::*;
-use parse::{ParseSess, PResult, lexer};
+use parse::{ParseSess, DirectoryOwnership, PResult, lexer};
use parse::parser::Parser;
-use parse::token::{self, intern, keywords};
+use parse::token;
use print::pprust;
use ptr::P;
use std_inject;
+use symbol::keywords;
use tokenstream::{TokenTree, TokenStream};
use util::small_vector::SmallVector;
use visit::Visitor;
}
}
- pub fn visit_with<V: Visitor>(&self, visitor: &mut V) {
+ pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
match *self {
Expansion::OptExpr(Some(ref expr)) => visitor.visit_expr(expr),
Expansion::OptExpr(None) => {}
$($( Expansion::$kind(ref ast) => visitor.$visit(ast), )*)*
- $($( Expansion::$kind(ref ast) => for ast in ast.as_slice() {
+ $($( Expansion::$kind(ref ast) => for ast in &ast[..] {
visitor.$visit_elt(ast);
}, )*)*
}
pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
self.cx.crate_root = std_inject::injected_crate_name(&krate);
let mut module = ModuleData {
- mod_path: vec![token::str_to_ident(&self.cx.ecfg.crate_name)],
+ mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
directory: PathBuf::from(self.cx.codemap().span_to_filename(krate.span)),
};
module.directory.pop();
self.cx.current_expansion.depth = 0;
let (expansion, mut invocations) = self.collect_invocations(expansion);
+ self.resolve_imports();
invocations.reverse();
let mut expansions = Vec::new();
loop {
let invoc = if let Some(invoc) = invocations.pop() {
invoc
- } else if undetermined_invocations.is_empty() {
- break
} else {
+ self.resolve_imports();
+ if undetermined_invocations.is_empty() { break }
invocations = mem::replace(&mut undetermined_invocations, Vec::new());
force = !mem::replace(&mut progress, false);
continue
self.cx.resolver.resolve_macro(scope, &mac.node.path, force)
}
InvocationKind::Attr { ref attr, .. } => {
- let ident = ast::Ident::with_empty_ctxt(intern(&*attr.name()));
+ let ident = Ident::with_empty_ctxt(attr.name());
let path = ast::Path::from_ident(attr.span, ident);
self.cx.resolver.resolve_macro(scope, &path, force)
}
expansion.fold_with(&mut placeholder_expander)
}
+ fn resolve_imports(&mut self) {
+ if self.monotonic {
+ let err_count = self.cx.parse_sess.span_diagnostic.err_count();
+ self.cx.resolver.resolve_imports();
+ self.cx.resolve_err_count += self.cx.parse_sess.span_diagnostic.err_count() - err_count;
+ }
+ }
+
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
let result = {
let mut collector = InvocationCollector {
};
attr::mark_used(&attr);
- let name = intern(&attr.name());
+ let name = attr.name();
self.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
match *ext {
MultiModifier(ref mac) => {
- let item = mac.expand(self.cx, attr.span, &attr.node.value, item);
+ let item = mac.expand(self.cx, attr.span, &attr.value, item);
kind.expect_from_annotatables(item)
}
MultiDecorator(ref mac) => {
let mut items = Vec::new();
- mac.expand(self.cx, attr.span, &attr.node.value, &item,
+ mac.expand(self.cx, attr.span, &attr.value, &item,
&mut |item| items.push(item));
items.push(item);
kind.expect_from_annotatables(items)
&self.cx.ecfg.features.unwrap());
}
- if path.segments.len() > 1 || path.global || !path.segments[0].parameters.is_empty() {
- self.cx.span_err(path.span, "expected macro name without module separators");
- return kind.dummy(span);
- }
-
- let extname = path.segments[0].identifier.name;
+ let extname = path.segments.last().unwrap().identifier.name;
let ident = ident.unwrap_or(keywords::Invalid.ident());
let marked_tts = mark_tts(&tts, mark);
let opt_expanded = match *ext {
-> PResult<'a, Expansion> {
Ok(match kind {
ExpansionKind::Items => {
- let mut items = SmallVector::zero();
+ let mut items = SmallVector::new();
while let Some(item) = self.parse_item()? {
items.push(item);
}
Expansion::Items(items)
}
ExpansionKind::TraitItems => {
- let mut items = SmallVector::zero();
+ let mut items = SmallVector::new();
while self.token != token::Eof {
items.push(self.parse_trait_item()?);
}
Expansion::TraitItems(items)
}
ExpansionKind::ImplItems => {
- let mut items = SmallVector::zero();
+ let mut items = SmallVector::new();
while self.token != token::Eof {
items.push(self.parse_impl_item()?);
}
Expansion::ImplItems(items)
}
ExpansionKind::Stmts => {
- let mut stmts = SmallVector::zero();
- while self.token != token::Eof {
+ let mut stmts = SmallVector::new();
+ while self.token != token::Eof &&
+ // won't make progress on a `}`
+ self.token != token::CloseDelim(token::Brace) {
if let Some(stmt) = self.parse_full_stmt(macro_legacy_warnings)? {
stmts.push(stmt);
}
($this:ident, $node:ident, $noop_fold:ident) => {
match $noop_fold($node, &mut $this.cfg).pop() {
Some(node) => node,
- None => return SmallVector::zero(),
+ None => return SmallVector::new(),
}
}
}
.new_filemap(String::from("<macro expansion>"), None, text);
let lexer = lexer::StringReader::new(&parse_sess.span_diagnostic, filemap);
- let mut parser = Parser::new(parse_sess, Box::new(lexer));
+ let mut parser = Parser::new(parse_sess, Box::new(lexer), None, false);
panictry!(parser.parse_all_token_trees())
}
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
let stmt = match self.cfg.configure_stmt(stmt) {
Some(stmt) => stmt,
- None => return SmallVector::zero(),
+ None => return SmallVector::new(),
};
let (mac, style, attrs) = if let StmtKind::Mac(mac) = stmt.node {
}
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
- let no_noninline_mod = mem::replace(&mut self.cx.current_expansion.no_noninline_mod, true);
+ let old_directory_ownership = self.cx.current_expansion.directory_ownership;
+ self.cx.current_expansion.directory_ownership = DirectoryOwnership::UnownedViaBlock;
let result = noop_fold_block(block, self);
- self.cx.current_expansion.no_noninline_mod = no_noninline_mod;
+ self.cx.current_expansion.directory_ownership = old_directory_ownership;
result
}
return noop_fold_item(item, self);
}
- let orig_no_noninline_mod = self.cx.current_expansion.no_noninline_mod;
+ let orig_directory_ownership = self.cx.current_expansion.directory_ownership;
let mut module = (*self.cx.current_expansion.module).clone();
module.mod_path.push(item.ident);
if inline_module {
if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
- self.cx.current_expansion.no_noninline_mod = false;
- module.directory.push(&*path);
+ self.cx.current_expansion.directory_ownership = DirectoryOwnership::Owned;
+ module.directory.push(&*path.as_str());
} else {
module.directory.push(&*item.ident.name.as_str());
}
} else {
- self.cx.current_expansion.no_noninline_mod = false;
- module.directory =
+ let mut path =
PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner));
- module.directory.pop();
+ let directory_ownership = match path.file_name().unwrap().to_str() {
+ Some("mod.rs") => DirectoryOwnership::Owned,
+ _ => DirectoryOwnership::UnownedViaMod(false),
+ };
+ path.pop();
+ module.directory = path;
+ self.cx.current_expansion.directory_ownership = directory_ownership;
}
let orig_module =
mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
let result = noop_fold_item(item, self);
self.cx.current_expansion.module = orig_module;
- self.cx.current_expansion.no_noninline_mod = orig_no_noninline_mod;
+ self.cx.current_expansion.directory_ownership = orig_directory_ownership;
return result;
}
// Ensure that test functions are accessible from the test harness.
fn enable_allow_internal_unstable = allow_internal_unstable,
fn enable_custom_derive = custom_derive,
fn enable_pushpop_unsafe = pushpop_unsafe,
- fn enable_proc_macro = proc_macro,
}
}