Skip to content

Commit 472fcb5

Browse files
committed
Fix the search paths for macro-expanded non-inline modules
1 parent cccc088 commit 472fcb5

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/libsyntax/ext/base.rs

+8
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,10 @@ pub struct ExtCtxt<'a> {
552552

553553
pub syntax_env: SyntaxEnv,
554554
pub recursion_count: usize,
555+
556+
pub filename: Option<String>,
557+
pub mod_path_stack: Vec<InternedString>,
558+
pub in_block: bool,
555559
}
556560

557561
impl<'a> ExtCtxt<'a> {
@@ -570,6 +574,10 @@ impl<'a> ExtCtxt<'a> {
570574
exported_macros: Vec::new(),
571575
syntax_env: env,
572576
recursion_count: 0,
577+
578+
filename: None,
579+
mod_path_stack: Vec::new(),
580+
in_block: false,
573581
}
574582
}
575583

src/libsyntax/ext/expand.rs

+45-2
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
11831183
}
11841184

11851185
impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
1186+
fn fold_crate(&mut self, c: Crate) -> Crate {
1187+
self.cx.filename = Some(self.cx.parse_sess.codemap().span_to_filename(c.span));
1188+
noop_fold_crate(c, self)
1189+
}
1190+
11861191
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
11871192
expand_expr(expr, self)
11881193
}
@@ -1192,7 +1197,27 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
11921197
}
11931198

11941199
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
1195-
expand_item(item, self)
1200+
use std::mem::replace;
1201+
let result;
1202+
if let ast::ItemKind::Mod(ast::Mod { inner, .. }) = item.node {
1203+
if item.span.contains(inner) {
1204+
self.push_mod_path(item.ident, &item.attrs);
1205+
result = expand_item(item, self);
1206+
self.pop_mod_path();
1207+
} else {
1208+
let filename = if inner != codemap::DUMMY_SP {
1209+
Some(self.cx.parse_sess.codemap().span_to_filename(inner))
1210+
} else { None };
1211+
let orig_filename = replace(&mut self.cx.filename, filename);
1212+
let orig_mod_path_stack = replace(&mut self.cx.mod_path_stack, Vec::new());
1213+
result = expand_item(item, self);
1214+
self.cx.filename = orig_filename;
1215+
self.cx.mod_path_stack = orig_mod_path_stack;
1216+
}
1217+
} else {
1218+
result = expand_item(item, self);
1219+
}
1220+
result
11961221
}
11971222

11981223
fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
@@ -1204,7 +1229,10 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
12041229
}
12051230

12061231
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
1207-
expand_block(block, self)
1232+
let was_in_block = ::std::mem::replace(&mut self.cx.in_block, true);
1233+
let result = expand_block(block, self);
1234+
self.cx.in_block = was_in_block;
1235+
result
12081236
}
12091237

12101238
fn fold_arm(&mut self, arm: ast::Arm) -> ast::Arm {
@@ -1230,6 +1258,21 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
12301258
}
12311259
}
12321260

1261+
impl<'a, 'b> MacroExpander<'a, 'b> {
1262+
fn push_mod_path(&mut self, id: Ident, attrs: &[ast::Attribute]) {
1263+
let default_path = id.name.as_str();
1264+
let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
1265+
Some(d) => d,
1266+
None => default_path,
1267+
};
1268+
self.cx.mod_path_stack.push(file_path)
1269+
}
1270+
1271+
fn pop_mod_path(&mut self) {
1272+
self.cx.mod_path_stack.pop().unwrap();
1273+
}
1274+
}
1275+
12331276
fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
12341277
/* this discards information in the case of macro-defining macros */
12351278
Span {

src/libsyntax/ext/tt/macro_rules.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use ext::tt::macro_parser::{Success, Error, Failure};
1616
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
1717
use ext::tt::macro_parser::parse;
1818
use parse::lexer::new_tt_reader;
19-
use parse::parser::Parser;
19+
use parse::parser::{Parser, Restrictions};
2020
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
2121
use parse::token::Token::*;
2222
use print;
@@ -195,6 +195,12 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
195195
imported_from,
196196
rhs);
197197
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
198+
p.filename = cx.filename.clone();
199+
p.mod_path_stack = cx.mod_path_stack.clone();
200+
p.restrictions = match cx.in_block {
201+
true => Restrictions::NO_NONINLINE_MOD,
202+
false => Restrictions::empty(),
203+
};
198204
p.check_unknown_macro_variable();
199205
// Let the context choose how to interpret the result.
200206
// Weird, but useful for X-macros.

0 commit comments

Comments
 (0)