use crate::placeholders::{placeholder, PlaceholderExpander};
use crate::proc_macro::collect_derives;
+use rustc_ast_pretty::pprust;
+use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::Features;
use rustc_parse::parser::Parser;
use rustc_parse::validate_attr;
use rustc_parse::DirectoryOwnership;
+use rustc_session::parse::{feature_err, ParseSess};
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{FileName, Span, DUMMY_SP};
use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
-use syntax::attr::{self, is_builtin_attr, HasAttrs};
use syntax::mut_visit::*;
-use syntax::print::pprust;
use syntax::ptr::P;
-use syntax::sess::{feature_err, ParseSess};
use syntax::token;
use syntax::tokenstream::{TokenStream, TokenTree};
use syntax::util::map_in_place::MapInPlace;
-use syntax::visit::{self, Visitor};
+use syntax::visit::{self, AssocCtxt, Visitor};
use smallvec::{smallvec, SmallVec};
use std::io::ErrorKind;
$($Kind:ident($AstTy:ty) {
$kind_name:expr;
$(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)?
- $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)?
+ $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)?
fn $make_ast:ident;
})*
) => {
AstFragment::OptExpr(None) => {}
$($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] {
- visitor.$visit_ast_elt(ast_elt);
+ visitor.$visit_ast_elt(ast_elt, $($args)*);
})?)*
}
}
Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; }
Ty(P<ast::Ty>) { "type"; one fn visit_ty; fn visit_ty; fn make_ty; }
Stmts(SmallVec<[ast::Stmt; 1]>) {
- "statement"; many fn flat_map_stmt; fn visit_stmt; fn make_stmts;
+ "statement"; many fn flat_map_stmt; fn visit_stmt(); fn make_stmts;
}
Items(SmallVec<[P<ast::Item>; 1]>) {
- "item"; many fn flat_map_item; fn visit_item; fn make_items;
+ "item"; many fn flat_map_item; fn visit_item(); fn make_items;
}
TraitItems(SmallVec<[P<ast::AssocItem>; 1]>) {
- "trait item"; many fn flat_map_trait_item; fn visit_trait_item; fn make_trait_items;
+ "trait item";
+ many fn flat_map_trait_item;
+ fn visit_assoc_item(AssocCtxt::Trait);
+ fn make_trait_items;
}
ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
- "impl item"; many fn flat_map_impl_item; fn visit_impl_item; fn make_impl_items;
+ "impl item";
+ many fn flat_map_impl_item;
+ fn visit_assoc_item(AssocCtxt::Impl);
+ fn make_impl_items;
}
ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
"foreign item";
many fn flat_map_foreign_item;
- fn visit_foreign_item;
+ fn visit_foreign_item();
fn make_foreign_items;
}
Arms(SmallVec<[ast::Arm; 1]>) {
- "match arm"; many fn flat_map_arm; fn visit_arm; fn make_arms;
+ "match arm"; many fn flat_map_arm; fn visit_arm(); fn make_arms;
}
Fields(SmallVec<[ast::Field; 1]>) {
- "field expression"; many fn flat_map_field; fn visit_field; fn make_fields;
+ "field expression"; many fn flat_map_field; fn visit_field(); fn make_fields;
}
FieldPats(SmallVec<[ast::FieldPat; 1]>) {
"field pattern";
many fn flat_map_field_pattern;
- fn visit_field_pattern;
+ fn visit_field_pattern();
fn make_field_patterns;
}
GenericParams(SmallVec<[ast::GenericParam; 1]>) {
"generic parameter";
many fn flat_map_generic_param;
- fn visit_generic_param;
+ fn visit_generic_param();
fn make_generic_params;
}
Params(SmallVec<[ast::Param; 1]>) {
- "function parameter"; many fn flat_map_param; fn visit_param; fn make_params;
+ "function parameter"; many fn flat_map_param; fn visit_param(); fn make_params;
}
StructFields(SmallVec<[ast::StructField; 1]>) {
"field";
many fn flat_map_struct_field;
- fn visit_struct_field;
+ fn visit_struct_field();
fn make_struct_fields;
}
Variants(SmallVec<[ast::Variant; 1]>) {
- "variant"; many fn flat_map_variant; fn visit_variant; fn make_variants;
+ "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
}
}
krate.attrs = vec![];
krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
}
- _ => unreachable!(),
+ Some(ast::Item { span, kind, .. }) => {
+ krate.attrs = vec![];
+ krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
+ self.cx.span_err(
+ span,
+ &format!(
+ "expected crate top-level item to be a module after macro expansion, found a {}",
+ kind.descriptive_variant()
+ ),
+ );
+ }
};
self.cx.trace_macros_diag();
krate
&format!("recursion limit reached while expanding `{}`", expn_data.kind.descr()),
);
err.help(&format!(
- "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
- suggested_limit
+ "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)",
+ suggested_limit, self.cx.ecfg.crate_name,
));
err.emit();
self.cx.trace_macros_diag();
AstFragmentKind::ForeignItems => {
let mut items = SmallVec::new();
while this.token != token::Eof {
- items.push(this.parse_foreign_item(DUMMY_SP)?);
+ items.push(this.parse_foreign_item()?);
}
AstFragment::ForeignItems(items)
}