Skip to content

Commit

Permalink
Auto merge of #37463 - jseyfried:refactor_macro_reexports, r=nrc
Browse files Browse the repository at this point in the history
macros: improve reexports

This PR
- avoids building multiple module graphs for a crate that is referenced by multiple `extern crate` items,
- registers `#[no_link] extern crate`s to avoid loading the same crate metadata twice,
- stability checks `#[no_link] extern crate`s,
  - [breaking-chage]: `#[no_link] #[macro_use] extern crate syntax;` is allowed on stable today
- fixes `$crate` in `#[macro_reexport]`ed macros,
  - [breaking-change] for `#[feature(macro_reexport)]` (technically)
- allows selective macro importing (i.e. `#[macro_use(foo, bar)]`) from custom derive crates, and
- refactors the crate metadata to support re-exported macros in arbitrary modules (not yet needed).

r? @nrc
  • Loading branch information
bors authored Nov 10, 2016
2 parents c11e2bd + a0a9f8c commit ab03f85
Show file tree
Hide file tree
Showing 24 changed files with 477 additions and 419 deletions.
6 changes: 5 additions & 1 deletion src/librustc/hir/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ pub enum Def {
ast::NodeId), // expr node that creates the closure
Label(ast::NodeId),

// Macro namespace
Macro(DefId),

// Both namespaces
Err,
}
Expand Down Expand Up @@ -133,7 +136,7 @@ impl Def {
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) => {
Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) | Def::Macro(id) => {
id
}

Expand Down Expand Up @@ -173,6 +176,7 @@ impl Def {
Def::Upvar(..) => "closure capture",
Def::Label(..) => "label",
Def::SelfTy(..) => "self type",
Def::Macro(..) => "macro",
Def::Err => "unresolved item",
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ impl Idx for CrateNum {
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum(0);

/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get `CrateNum`s.
pub const BUILTIN_MACROS_CRATE: CrateNum = CrateNum(!0);

impl CrateNum {
pub fn new(x: usize) -> CrateNum {
assert!(x < (u32::MAX as usize));
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
self.insert(lifetime.id, NodeLifetime(lifetime));
}

fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
self.insert_entry(macro_def.id, NotPresent);
}
}
35 changes: 17 additions & 18 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,18 @@ pub struct LinkMeta {
pub struct CrateSource {
pub dylib: Option<(PathBuf, PathKind)>,
pub rlib: Option<(PathBuf, PathKind)>,
pub cnum: CrateNum,
}

#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum DepKind {
/// A dependency that is only used for its macros.
MacrosOnly,
/// A dependency that is always injected into the dependency list and so
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
Implicit,
/// A dependency that is required by an rlib version of this crate.
/// Ordinary `extern crate`s result in `Explicit` dependencies.
Explicit,
}

#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
Expand Down Expand Up @@ -170,10 +181,10 @@ pub trait CrateStore<'tcx> {
// crate metadata
fn dylib_dependency_formats(&self, cnum: CrateNum)
-> Vec<(CrateNum, LinkagePreference)>;
fn dep_kind(&self, cnum: CrateNum) -> DepKind;
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>;
fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>;
fn is_staged_api(&self, cnum: CrateNum) -> bool;
fn is_explicitly_linked(&self, cnum: CrateNum) -> bool;
fn is_allocator(&self, cnum: CrateNum) -> bool;
fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
Expand All @@ -200,6 +211,7 @@ pub trait CrateStore<'tcx> {
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<def::Export>;
fn load_macro(&self, did: DefId, sess: &Session) -> ast::MacroDef;

// misc. metadata
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
Expand Down Expand Up @@ -342,7 +354,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>
{ bug!("missing_lang_items") }
fn is_staged_api(&self, cnum: CrateNum) -> bool { bug!("is_staged_api") }
fn is_explicitly_linked(&self, cnum: CrateNum) -> bool { bug!("is_explicitly_linked") }
fn dep_kind(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
Expand Down Expand Up @@ -371,6 +383,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
fn load_macro(&self, did: DefId, sess: &Session) -> ast::MacroDef { bug!("load_macro") }

// misc. metadata
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
Expand Down Expand Up @@ -410,22 +423,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
}

pub enum LoadedMacros {
MacroRules(Vec<ast::MacroDef>),
ProcMacros(Vec<(ast::Name, SyntaxExtension)>),
}

impl LoadedMacros {
pub fn is_proc_macros(&self) -> bool {
match *self {
LoadedMacros::ProcMacros(_) => true,
_ => false,
}
}
}

pub trait CrateLoader {
fn process_item(&mut self, item: &ast::Item, defs: &Definitions, load_macros: bool)
-> Option<LoadedMacros>;
-> Vec<(ast::Name, SyntaxExtension)>;
fn postprocess(&mut self, krate: &ast::Crate);
}
7 changes: 5 additions & 2 deletions src/librustc/middle/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use hir::def_id::CrateNum;

use session;
use session::config;
use middle::cstore::DepKind;
use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
use util::nodemap::FxHashMap;
use rustc_back::PanicStrategy;
Expand Down Expand Up @@ -123,6 +124,7 @@ fn calculate_type(sess: &session::Session,
return v;
}
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
let src = sess.cstore.used_crate_source(cnum);
if src.rlib.is_some() { continue }
sess.err(&format!("dependency `{}` not found in rlib format",
Expand Down Expand Up @@ -155,6 +157,7 @@ fn calculate_type(sess: &session::Session,
// dependencies, ensuring there are no conflicts. The only valid case for a
// dependency to be relied upon twice is for both cases to rely on a dylib.
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
let name = sess.cstore.crate_name(cnum);
let src = sess.cstore.used_crate_source(cnum);
if src.dylib.is_some() {
Expand Down Expand Up @@ -188,7 +191,7 @@ fn calculate_type(sess: &session::Session,
let src = sess.cstore.used_crate_source(cnum);
if src.dylib.is_none() &&
!formats.contains_key(&cnum) &&
sess.cstore.is_explicitly_linked(cnum) {
sess.cstore.dep_kind(cnum) == DepKind::Explicit {
assert!(src.rlib.is_some());
info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
add_library(sess, cnum, RequireStatic, &mut formats);
Expand Down Expand Up @@ -272,7 +275,7 @@ fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
// everything in explicitly so long as it's actually required.
let last_crate = sess.cstore.crates().len();
let mut ret = (1..last_crate+1).map(|cnum| {
if sess.cstore.is_explicitly_linked(CrateNum::new(cnum)) {
if sess.cstore.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
Linkage::Static
} else {
Linkage::NotLinked
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
Def::Const(..) |
Def::AssociatedConst(..) |
Def::Local(..) |
Def::Upvar(..) => {
Def::Upvar(..) |
Def::Macro(..) => {
DefHash::SawDefId.hash(self.st);
self.hash_def_id(def.def_id());
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#![feature(staged_api)]
#![feature(linked_from)]
#![feature(concat_idents)]
#![cfg_attr(not(stage0), feature(rustc_private))]

extern crate libc;
#[macro_use]
Expand Down
Loading

0 comments on commit ab03f85

Please sign in to comment.