Skip to content

Commit f1ea5cc

Browse files
author
Jonathan Turner
authored
Rollup merge of rust-lang#36789 - jseyfried:non_inline_mod_in_block, r=nikomatsakis
Allow more non-inline modules in blocks Currently, non-inline modules without a `#[path]` attribute are not allowed in blocks. This PR allows non-inline modules that have an ancestor module with a `#[path]` attribute, provided there is not a nearer ancestor block. For example, ```rust fn main() { #[path = "..."] mod foo { mod bar; //< allowed by this PR fn f() { mod bar; //< still an error } } } ``` Fixes rust-lang#36772. r? @nikomatsakis
2 parents 13c8e76 + 174f093 commit f1ea5cc

File tree

5 files changed

+40
-18
lines changed

5 files changed

+40
-18
lines changed

src/libsyntax/ext/base.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,9 @@ pub struct ExpansionData {
557557
pub depth: usize,
558558
pub backtrace: ExpnId,
559559
pub module: Rc<ModuleData>,
560-
pub in_block: bool,
560+
561+
// True if non-inline modules without a `#[path]` are forbidden at the root of this expansion.
562+
pub no_noninline_mod: bool,
561563
}
562564

563565
/// One of these is made during expansion and incrementally updated as we go;
@@ -590,7 +592,7 @@ impl<'a> ExtCtxt<'a> {
590592
depth: 0,
591593
backtrace: NO_EXPANSION,
592594
module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
593-
in_block: false,
595+
no_noninline_mod: false,
594596
},
595597
}
596598
}

src/libsyntax/ext/expand.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
667667
}
668668

669669
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
670-
let orig_in_block = mem::replace(&mut self.cx.current_expansion.in_block, true);
670+
let no_noninline_mod = mem::replace(&mut self.cx.current_expansion.no_noninline_mod, true);
671671
let result = noop_fold_block(block, self);
672-
self.cx.current_expansion.in_block = orig_in_block;
672+
self.cx.current_expansion.no_noninline_mod = no_noninline_mod;
673673
result
674674
}
675675

@@ -708,6 +708,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
708708
return noop_fold_item(item, self);
709709
}
710710

711+
let orig_no_noninline_mod = self.cx.current_expansion.no_noninline_mod;
711712
let mut module = (*self.cx.current_expansion.module).clone();
712713
module.mod_path.push(item.ident);
713714

@@ -717,11 +718,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
717718
let inline_module = item.span.contains(inner) || inner == syntax_pos::DUMMY_SP;
718719

719720
if inline_module {
720-
module.directory.push(&*{
721-
::attr::first_attr_value_str_by_name(&item.attrs, "path")
722-
.unwrap_or(item.ident.name.as_str())
723-
});
721+
if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
722+
self.cx.current_expansion.no_noninline_mod = false;
723+
module.directory.push(&*path);
724+
} else {
725+
module.directory.push(&*item.ident.name.as_str());
726+
}
724727
} else {
728+
self.cx.current_expansion.no_noninline_mod = false;
725729
module.directory =
726730
PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner));
727731
module.directory.pop();
@@ -731,6 +735,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
731735
mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
732736
let result = noop_fold_item(item, self);
733737
self.cx.current_expansion.module = orig_module;
738+
self.cx.current_expansion.no_noninline_mod = orig_no_noninline_mod;
734739
return result;
735740
}
736741
// Ensure that test functions are accessible from the test harness.

src/libsyntax/ext/tt/macro_rules.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
122122
rhs);
123123
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
124124
p.directory = cx.current_expansion.module.directory.clone();
125-
p.restrictions = match cx.current_expansion.in_block {
125+
p.restrictions = match cx.current_expansion.no_noninline_mod {
126126
true => Restrictions::NO_NONINLINE_MOD,
127127
false => Restrictions::empty(),
128128
};

src/libsyntax/parse/parser.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -5274,23 +5274,27 @@ impl<'a> Parser<'a> {
52745274
}
52755275
} else {
52765276
let directory = self.directory.clone();
5277-
self.push_directory(id, &outer_attrs);
5277+
let restrictions = self.push_directory(id, &outer_attrs);
52785278
self.expect(&token::OpenDelim(token::Brace))?;
52795279
let mod_inner_lo = self.span.lo;
52805280
let attrs = self.parse_inner_attributes()?;
5281-
let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
5281+
let m = self.with_res(restrictions, |this| {
5282+
this.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)
5283+
})?;
52825284
self.directory = directory;
52835285
Ok((id, ItemKind::Mod(m), Some(attrs)))
52845286
}
52855287
}
52865288

5287-
fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
5288-
let default_path = self.id_to_interned_str(id);
5289-
let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
5290-
Some(d) => d,
5291-
None => default_path,
5292-
};
5293-
self.directory.push(&*file_path)
5289+
fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) -> Restrictions {
5290+
if let Some(path) = ::attr::first_attr_value_str_by_name(attrs, "path") {
5291+
self.directory.push(&*path);
5292+
self.restrictions - Restrictions::NO_NONINLINE_MOD
5293+
} else {
5294+
let default_path = self.id_to_interned_str(id);
5295+
self.directory.push(&*default_path);
5296+
self.restrictions
5297+
}
52945298
}
52955299

52965300
pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {

src/test/run-pass/mod_dir_path.rs

+11
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,15 @@ mod mod_dir_simple {
1717

1818
pub fn main() {
1919
assert_eq!(mod_dir_simple::syrup::foo(), 10);
20+
21+
#[path = "auxiliary"]
22+
mod foo {
23+
mod two_macros;
24+
}
25+
26+
#[path = "auxiliary"]
27+
mod bar {
28+
macro_rules! m { () => { mod two_macros; } }
29+
m!();
30+
}
2031
}

0 commit comments

Comments
 (0)