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:
commit
da5b6467c3
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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`
|
|
||||||
}
|
}
|
||||||
|
@ -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() {}
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user