From ce5ad1da12da71712750a984dbdb1a1645745e6b Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 27 Sep 2016 21:14:45 +0000 Subject: [PATCH 1/2] Allow non-inline modules in more places. --- src/libsyntax/ext/base.rs | 6 ++++-- src/libsyntax/ext/expand.rs | 17 +++++++++++------ src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/parse/parser.rs | 22 +++++++++++++--------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3e85565beb6d1..2d8fbdf3721c8 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -696,7 +696,9 @@ pub struct ExpansionData { pub depth: usize, pub backtrace: ExpnId, pub module: Rc, - pub in_block: bool, + + // True if non-inline modules without a `#[path]` are forbidden at the root of this expansion. + pub no_noninline_mod: bool, } /// One of these is made during expansion and incrementally updated as we go; @@ -727,7 +729,7 @@ impl<'a> ExtCtxt<'a> { depth: 0, backtrace: NO_EXPANSION, module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), - in_block: false, + no_noninline_mod: false, }, } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 43c622189632a..bc56c54ea5241 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -601,9 +601,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } fn fold_block(&mut self, block: P) -> P { - let orig_in_block = mem::replace(&mut self.cx.current_expansion.in_block, true); + let no_noninline_mod = mem::replace(&mut self.cx.current_expansion.no_noninline_mod, true); let result = noop_fold_block(block, self); - self.cx.current_expansion.in_block = orig_in_block; + self.cx.current_expansion.no_noninline_mod = no_noninline_mod; result } @@ -642,6 +642,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { return noop_fold_item(item, self); } + let orig_no_noninline_mod = self.cx.current_expansion.no_noninline_mod; let mut module = (*self.cx.current_expansion.module).clone(); module.mod_path.push(item.ident); @@ -651,11 +652,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let inline_module = item.span.contains(inner) || inner == syntax_pos::DUMMY_SP; if inline_module { - module.directory.push(&*{ - ::attr::first_attr_value_str_by_name(&item.attrs, "path") - .unwrap_or(item.ident.name.as_str()) - }); + 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); + } else { + module.directory.push(&*item.ident.name.as_str()); + } } else { + self.cx.current_expansion.no_noninline_mod = false; module.directory = PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner)); module.directory.pop(); @@ -665,6 +669,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { 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; return result; } _ => noop_fold_item(item, self), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 0eed3e5898c00..4619caf26c718 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -211,7 +211,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, rhs); let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr)); p.directory = cx.current_expansion.module.directory.clone(); - p.restrictions = match cx.current_expansion.in_block { + p.restrictions = match cx.current_expansion.no_noninline_mod { true => Restrictions::NO_NONINLINE_MOD, false => Restrictions::empty(), }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 23085fadc5e60..72d89510e7909 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5289,23 +5289,27 @@ impl<'a> Parser<'a> { } } else { let directory = self.directory.clone(); - self.push_directory(id, &outer_attrs); + let restrictions = self.push_directory(id, &outer_attrs); self.expect(&token::OpenDelim(token::Brace))?; let mod_inner_lo = self.span.lo; let attrs = self.parse_inner_attributes()?; - let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?; + let m = self.with_res(restrictions, |this| { + this.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo) + })?; self.directory = directory; Ok((id, ItemKind::Mod(m), Some(attrs))) } } - fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { - let default_path = self.id_to_interned_str(id); - let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") { - Some(d) => d, - None => default_path, - }; - self.directory.push(&*file_path) + fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) -> Restrictions { + if let Some(path) = ::attr::first_attr_value_str_by_name(attrs, "path") { + self.directory.push(&*path); + self.restrictions - Restrictions::NO_NONINLINE_MOD + } else { + let default_path = self.id_to_interned_str(id); + self.directory.push(&*default_path); + self.restrictions + } } pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option { From 174f0936514d7e7224c34a78699733eea498875e Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 27 Sep 2016 21:31:30 +0000 Subject: [PATCH 2/2] Add regression test. --- src/test/run-pass/mod_dir_path.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/run-pass/mod_dir_path.rs b/src/test/run-pass/mod_dir_path.rs index e0327a1dcd4ed..28dee15cfa043 100644 --- a/src/test/run-pass/mod_dir_path.rs +++ b/src/test/run-pass/mod_dir_path.rs @@ -17,4 +17,15 @@ mod mod_dir_simple { pub fn main() { assert_eq!(mod_dir_simple::syrup::foo(), 10); + + #[path = "auxiliary"] + mod foo { + mod two_macros; + } + + #[path = "auxiliary"] + mod bar { + macro_rules! m { () => { mod two_macros; } } + m!(); + } }