about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-10-21 01:48:31 -0700
committerGitHub <noreply@github.com>2016-10-21 01:48:31 -0700
commitda5b6467c33f7f86b4964b08b37726f7611a8f0c (patch)
treebda505a46fc98c456aa2012b41af936d99fb1a79 /src
parente4708273b5401cd572d19f8836e121ce39dc2767 (diff)
parentb283aaf0ff74db93162b402e627f3b4ed7fb7d4e (diff)
downloadrust-da5b6467c33f7f86b4964b08b37726f7611a8f0c.tar.gz
rust-da5b6467c33f7f86b4964b08b37726f7611a8f0c.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/librustc_metadata/macro_import.rs11
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs3
-rw-r--r--src/test/compile-fail-fulldeps/no-link-unknown-crate.rs (renamed from src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs)2
-rw-r--r--src/test/compile-fail/no-link.rs2
5 files changed, 13 insertions, 7 deletions
diff --git a/src/librustc_metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs
index 3b1b2a4cd27..41e14ea9f40 100644
--- a/src/librustc_metadata/macro_import.rs
+++ b/src/librustc_metadata/macro_import.rs
@@ -52,6 +52,7 @@ impl<'a> CrateLoader<'a> {
         // Parse the attributes relating to macros.
         let mut import = ImportSelection::Some(FnvHashMap());
         let mut reexport = FnvHashMap();
+        let mut no_link = false;
 
         for attr in &extern_crate.attrs {
             let mut used = true;
@@ -87,6 +88,7 @@ impl<'a> CrateLoader<'a> {
                         }
                     }
                 }
+                "no_link" => no_link = true,
                 _ => used = false,
             }
             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,
                        vi: &ast::Item,
                        allows_macros: bool,
                        import: ImportSelection,
-                       reexport: MacroSelection)
+                       reexport: MacroSelection,
+                       no_link: bool)
                        -> Vec<LoadedMacro> {
         if let ImportSelection::Some(ref sel) = import {
             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();
             }
         }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index f19afd67faa..9ed7be5af4e 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -267,7 +267,7 @@ impl<'b> Resolver<'b> {
                     }
 
                     self.populate_module_if_necessary(module);
-                } else if custom_derive_crate {
+                } else {
                     // Define an empty module
                     let def = Def::Mod(self.definitions.local_def_id(item.id));
                     let module = ModuleS::new(Some(parent), ModuleKind::Def(def, name));
diff --git a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
index 1fbde00a3df..f563a1f88d0 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
@@ -14,6 +14,5 @@
 extern crate macro_crate_test;
 
 fn main() {
-    macro_crate_test::foo();
-    //~^ ERROR failed to resolve. Use of undeclared type or module `macro_crate_test`
+    macro_crate_test::foo(); //~ ERROR unresolved name
 }
diff --git a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs b/src/test/compile-fail-fulldeps/no-link-unknown-crate.rs
index 65657eea1ef..8e4692bdee1 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
+++ b/src/test/compile-fail-fulldeps/no-link-unknown-crate.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[macro_use] #[no_link]
+#[no_link]
 extern crate doesnt_exist; //~ ERROR can't find crate
 
 fn main() {}
diff --git a/src/test/compile-fail/no-link.rs b/src/test/compile-fail/no-link.rs
index 957b6cda553..8f6da99806b 100644
--- a/src/test/compile-fail/no-link.rs
+++ b/src/test/compile-fail/no-link.rs
@@ -13,6 +13,6 @@ extern crate libc;
 
 fn main() {
     unsafe {
-        libc::abs(0);  //~ ERROR Use of undeclared type or module `libc`
+        libc::abs(0);  //~ ERROR unresolved name
     }
 }