Skip to content

Commit

Permalink
Auto merge of #37213 - jseyfried:refactor_crate_var, r=nrc
Browse files Browse the repository at this point in the history
macros: improve `$crate`

This PR refactors the implementation of `$crate` so that
 - `$crate` is only allowed at the start of a path (like `super`),
 - we can make `$crate` work with inter-crate re-exports (groundwork for macro modularization), and
 - we can support importing macros from an extern crate that is not declared at the crate root (also groundwork for macro modularization).

This is a [breaking-change]. For example, the following would break:
```rust
fn foo() {}
macro_rules! m { () => {
    $crate foo $crate () $crate $crate;
    //^ Today, `$crate` is allowed just about anywhere in unexported macros.
} }
fn main() {
    m!();
}
```
r? @nrc
  • Loading branch information
bors authored Oct 19, 2016
2 parents a41505f + 8b0c292 commit cfc9b51
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 133 deletions.
25 changes: 21 additions & 4 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ext::base::{SyntaxExtension, Resolver as SyntaxResolver};
use syntax::ext::expand::mark_tts;
use syntax::ext::hygiene::Mark;
use syntax::feature_gate::{self, emit_feature_err};
use syntax::ext::tt::macro_rules;
Expand Down Expand Up @@ -95,22 +96,22 @@ impl<'b> Resolver<'b> {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path: Vec<Name> = match view_path.node {
let module_path: Vec<_> = match view_path.node {
ViewPathSimple(_, ref full_path) => {
full_path.segments
.split_last()
.unwrap()
.1
.iter()
.map(|seg| seg.identifier.name)
.map(|seg| seg.identifier)
.collect()
}

ViewPathGlob(ref module_ident_path) |
ViewPathList(ref module_ident_path, _) => {
module_ident_path.segments
.iter()
.map(|seg| seg.identifier.name)
.map(|seg| seg.identifier)
.collect()
}
};
Expand Down Expand Up @@ -159,7 +160,7 @@ impl<'b> Resolver<'b> {
(module_path.clone(), node.name.name, rename)
} else {
let name = match module_path.last() {
Some(name) => *name,
Some(ident) => ident.name,
None => {
resolve_error(
self,
Expand Down Expand Up @@ -207,11 +208,16 @@ impl<'b> Resolver<'b> {
};

let mut custom_derive_crate = false;
// The mark of the expansion that generates the loaded macros.
let mut opt_mark = None;
for loaded_macro in self.crate_loader.load_macros(item, is_crate_root) {
let mark = opt_mark.unwrap_or_else(Mark::fresh);
opt_mark = Some(mark);
match loaded_macro.kind {
LoadedMacroKind::Def(mut def) => {
if def.use_locally {
self.macro_names.insert(def.ident.name);
def.body = mark_tts(&def.body, mark);
let ext = macro_rules::compile(&self.session.parse_sess, &def);
import_macro(self, def.ident.name, ext, loaded_macro.import_site);
}
Expand Down Expand Up @@ -249,6 +255,17 @@ impl<'b> Resolver<'b> {
});
self.define(parent, name, TypeNS, (module, sp, vis));

if let Some(mark) = opt_mark {
let invocation = self.arenas.alloc_invocation_data(InvocationData {
module: Cell::new(module),
def_index: CRATE_DEF_INDEX,
const_integer: false,
legacy_scope: Cell::new(LegacyScope::Empty),
expansion: Cell::new(LegacyScope::Empty),
});
self.invocations.insert(mark, invocation);
}

self.populate_module_if_necessary(module);
} else if custom_derive_crate {
// Define an empty module
Expand Down
Loading

0 comments on commit cfc9b51

Please sign in to comment.