Auto merge of #37247 - jseyfried:future_proof_no_link, r=nrc

macros: Future proof `#[no_link]`

This PR future proofs `#[no_link]` for macro modularization (cc #35896).

First, we resolve all `#[no_link] extern crate`s. `#[no_link]` crates without `#[macro_use]` or `#[macro_reexport]` are not resolved today, this is a [breaking-change]. For example,
```rust
```
Any breakage can be fixed by simply removing the `#[no_link] extern crate`.

Second, `#[no_link] extern crate`s will define an empty module in type namespace to eventually allow importing the crate's macros with `use`. This is a [breaking-change], for example:
```rust
mod syntax {} //< This becomes a duplicate error.
```

r? @nrc
This commit is contained in:
bors 2016-10-21 01:48:31 -07:00 committed by GitHub
commit da5b6467c3
5 changed files with 13 additions and 7 deletions

View File

@ -52,6 +52,7 @@ impl<'a> CrateLoader<'a> {
// Parse the attributes relating to macros. // Parse the attributes relating to macros.
let mut import = ImportSelection::Some(FnvHashMap()); let mut import = ImportSelection::Some(FnvHashMap());
let mut reexport = FnvHashMap(); let mut reexport = FnvHashMap();
let mut no_link = false;
for attr in &extern_crate.attrs { for attr in &extern_crate.attrs {
let mut used = true; let mut used = true;
@ -87,6 +88,7 @@ impl<'a> CrateLoader<'a> {
} }
} }
} }
"no_link" => no_link = true,
_ => used = false, _ => used = false,
} }
if used { if used {
@ -94,17 +96,22 @@ impl<'a> CrateLoader<'a> {
} }
} }
self.load_macros(extern_crate, allows_macros, import, reexport) self.load_macros(extern_crate, allows_macros, import, reexport, no_link)
} }
fn load_macros<'b>(&mut self, fn load_macros<'b>(&mut self,
vi: &ast::Item, vi: &ast::Item,
allows_macros: bool, allows_macros: bool,
import: ImportSelection, import: ImportSelection,
reexport: MacroSelection) reexport: MacroSelection,
no_link: bool)
-> Vec<LoadedMacro> { -> Vec<LoadedMacro> {
if let ImportSelection::Some(ref sel) = import { if let ImportSelection::Some(ref sel) = import {
if sel.is_empty() && reexport.is_empty() { if sel.is_empty() && reexport.is_empty() {
// Make sure we can read macros from `#[no_link]` crates.
if no_link {
self.creader.read_macros(vi);
}
return Vec::new(); return Vec::new();
} }
} }

View File

@ -267,7 +267,7 @@ impl<'b> Resolver<'b> {
} }
self.populate_module_if_necessary(module); self.populate_module_if_necessary(module);
} else if custom_derive_crate { } else {
// Define an empty module // Define an empty module
let def = Def::Mod(self.definitions.local_def_id(item.id)); let def = Def::Mod(self.definitions.local_def_id(item.id));
let module = ModuleS::new(Some(parent), ModuleKind::Def(def, name)); let module = ModuleS::new(Some(parent), ModuleKind::Def(def, name));

View File

@ -14,6 +14,5 @@
extern crate macro_crate_test; extern crate macro_crate_test;
fn main() { fn main() {
macro_crate_test::foo(); macro_crate_test::foo(); //~ ERROR unresolved name
//~^ ERROR failed to resolve. Use of undeclared type or module `macro_crate_test`
} }

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#[macro_use] #[no_link] #[no_link]
extern crate doesnt_exist; //~ ERROR can't find crate extern crate doesnt_exist; //~ ERROR can't find crate
fn main() {} fn main() {}

View File

@ -13,6 +13,6 @@ extern crate libc;
fn main() { fn main() {
unsafe { unsafe {
libc::abs(0); //~ ERROR Use of undeclared type or module `libc` libc::abs(0); //~ ERROR unresolved name
} }
} }