Allow non-inline modules in more places.

This commit is contained in:
Jeffrey Seyfried 2016-09-27 21:14:45 +00:00
parent d0623cf7bd
commit ce5ad1da12
4 changed files with 29 additions and 18 deletions

View File

@ -696,7 +696,9 @@ pub struct ExpansionData {
pub depth: usize,
pub backtrace: ExpnId,
pub module: Rc<ModuleData>,
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,
},
}
}

View File

@ -601,9 +601,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
}
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
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),

View File

@ -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(),
};

View File

@ -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<PathBuf> {