about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2016-02-26 16:25:25 -0500
committerNiko Matsakis <niko@alum.mit.edu>2016-03-25 14:07:18 -0400
commit2eebb7b60588902c51d6d8dd9e695c6babaa8aa2 (patch)
tree560ad9f8aaef9fed7162961441e0ff7cdfe50197 /src
parentfafdfa8bdc2cf762d84ca2e18215d3e11caf3af5 (diff)
downloadrust-2eebb7b60588902c51d6d8dd9e695c6babaa8aa2.tar.gz
rust-2eebb7b60588902c51d6d8dd9e695c6babaa8aa2.zip
Make the compiler emit an error if the crate graph contains two crates with the same crate-name and crate-salt but different SVHs.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_driver/driver.rs10
-rw-r--r--src/librustc_metadata/creader.rs48
-rw-r--r--src/librustc_metadata/cstore.rs3
-rw-r--r--src/librustc_metadata/decoder.rs4
-rw-r--r--src/librustc_metadata/diagnostics.rs2
-rw-r--r--src/librustc_metadata/macro_import.rs11
-rw-r--r--src/librustc_plugin/load.rs11
-rw-r--r--src/librustc_trans/back/symbol_names.rs11
-rw-r--r--src/test/auxiliary/inline-default-methods.rs2
-rw-r--r--src/test/auxiliary/issue-13698.rs2
-rw-r--r--src/test/auxiliary/issue-15318.rs2
-rw-r--r--src/test/auxiliary/issue-17476.rs1
-rw-r--r--src/test/auxiliary/issue-19190-3.rs2
-rw-r--r--src/test/auxiliary/issue-20646.rs2
-rw-r--r--src/test/auxiliary/issue-20727.rs2
-rw-r--r--src/test/auxiliary/issue-21092.rs2
-rw-r--r--src/test/auxiliary/issue-21801.rs2
-rw-r--r--src/test/auxiliary/issue-22025.rs2
-rw-r--r--src/test/auxiliary/issue-27362.rs2
-rw-r--r--src/test/auxiliary/issue-29584.rs2
-rw-r--r--src/test/run-make/extern-overrides-distribution/Makefile2
-rw-r--r--src/test/run-make/issue-26006/Makefile2
22 files changed, 103 insertions, 24 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 1af01a41223..4c64923456d 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -526,11 +526,15 @@ pub fn phase_2_configure_and_expand(sess: &Session,
 
     let macros = time(time_passes,
                       "macro loading",
-                      || macro_import::read_macro_defs(sess, &cstore, &krate));
+                      || macro_import::read_macro_defs(sess, &cstore, &krate, crate_name));
 
     let mut addl_plugins = Some(addl_plugins);
     let registrars = time(time_passes, "plugin loading", || {
-        plugin::load::load_plugins(sess, &cstore, &krate, addl_plugins.take().unwrap())
+        plugin::load::load_plugins(sess,
+                                   &cstore,
+                                   &krate,
+                                   crate_name,
+                                   addl_plugins.take().unwrap())
     });
 
     let mut registry = Registry::new(sess, &krate);
@@ -755,7 +759,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
     time(time_passes,
          "external crate/lib resolution",
-         || LocalCrateReader::new(sess, cstore, &hir_map).read_crates());
+         || LocalCrateReader::new(sess, cstore, &hir_map, name).read_crates());
 
     let lang_items = time(time_passes, "language item collection", || {
         sess.track_errors(|| {
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index d05728d11cd..11cb2b8a818 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -55,6 +55,7 @@ pub struct CrateReader<'a> {
     cstore: &'a CStore,
     next_crate_num: ast::CrateNum,
     foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
+    local_crate_name: String,
 }
 
 impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> {
@@ -146,12 +147,15 @@ impl PMDSource {
 }
 
 impl<'a> CrateReader<'a> {
-    pub fn new(sess: &'a Session, cstore: &'a CStore) -> CrateReader<'a> {
+    pub fn new(sess: &'a Session,
+               cstore: &'a CStore,
+               local_crate_name: &str) -> CrateReader<'a> {
         CrateReader {
             sess: sess,
             cstore: cstore,
             next_crate_num: cstore.next_crate_num(),
             foreign_item_map: FnvHashMap(),
+            local_crate_name: local_crate_name.to_owned(),
         }
     }
 
@@ -272,6 +276,38 @@ impl<'a> CrateReader<'a> {
         }
     }
 
+    fn verify_no_symbol_conflicts(&self,
+                                  crate_name: &str,
+                                  span: Span,
+                                  metadata: &MetadataBlob) {
+        let disambiguator = decoder::get_crate_disambiguator(metadata.as_slice());
+
+        // Check for (potential) conflicts with the local crate
+        if self.local_crate_name == crate_name &&
+           &self.sess.crate_disambiguator.borrow()[..] == disambiguator {
+            span_fatal!(self.sess, span, E0519,
+                        "the current crate is indistinguishable from one of its \
+                         dependencies: it has the same crate-name `{}` and was \
+                         compiled with the same `-C metadata` arguments. This \
+                         will result in symbol conflicts between the two.",
+                        crate_name)
+        }
+
+        let svh = decoder::get_crate_hash(metadata.as_slice());
+        // Check for conflicts with any crate loaded so far
+        self.cstore.iter_crate_data(|_, other| {
+            if other.name() == crate_name && // same crate-name
+               other.disambiguator() == disambiguator &&  // same crate-disambiguator
+               other.hash() != svh { // but different SVH
+                span_fatal!(self.sess, span, E0520,
+                        "found two different crates with name `{}` that are \
+                         not distinguished by differing `-C metadata`. This \
+                         will result in symbol conflicts between the two.",
+                        crate_name)
+            }
+        });
+    }
+
     fn register_crate(&mut self,
                       root: &Option<CratePaths>,
                       ident: &str,
@@ -282,6 +318,7 @@ impl<'a> CrateReader<'a> {
                       -> (ast::CrateNum, Rc<cstore::crate_metadata>,
                           cstore::CrateSource) {
         self.verify_rustc_version(name, span, &lib.metadata);
+        self.verify_no_symbol_conflicts(name, span, &lib.metadata);
 
         // Claim this crate number and cache it
         let cnum = self.next_crate_num;
@@ -713,12 +750,15 @@ impl<'a> CrateReader<'a> {
 }
 
 impl<'a, 'b> LocalCrateReader<'a, 'b> {
-    pub fn new(sess: &'a Session, cstore: &'a CStore,
-               map: &'a hir_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
+    pub fn new(sess: &'a Session,
+               cstore: &'a CStore,
+               map: &'a hir_map::Map<'b>,
+               local_crate_name: &str)
+               -> LocalCrateReader<'a, 'b> {
         LocalCrateReader {
             sess: sess,
             cstore: cstore,
-            creader: CrateReader::new(sess, cstore),
+            creader: CrateReader::new(sess, cstore, local_crate_name),
             ast_map: map,
         }
     }
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index a96da6bf4d6..1e265c546c5 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -250,6 +250,9 @@ impl crate_metadata {
     pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
     pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
     pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
+    pub fn disambiguator(&self) -> &str {
+        decoder::get_crate_disambiguator(self.data())
+    }
     pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap)
                                  -> Ref<'a, Vec<ImportedFileMap>> {
         let filemaps = self.codemap_import_info.borrow();
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index f24c489b7c2..79209a7d26d 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1297,8 +1297,8 @@ pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
 
 pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str {
     let crate_doc = rbml::Doc::new(data);
-    let salt_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
-    let slice: &'a str = salt_doc.as_str_slice();
+    let disambiguator_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
+    let slice: &'a str = disambiguator_doc.as_str_slice();
     slice
 }
 
diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs
index 50b9ea57550..ebc7a4b461e 100644
--- a/src/librustc_metadata/diagnostics.rs
+++ b/src/librustc_metadata/diagnostics.rs
@@ -87,4 +87,6 @@ register_diagnostics! {
     E0468, // an `extern crate` loading macros must be at the crate root
     E0469, // imported macro not found
     E0470, // reexported macro not found
+    E0519, // local crate and dependency have same (crate-name, disambiguator)
+    E0520, // two dependencies have same (crate-name, disambiguator) but different SVH
 }
diff --git a/src/librustc_metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs
index 102bcc10fac..911ca7e315c 100644
--- a/src/librustc_metadata/macro_import.rs
+++ b/src/librustc_metadata/macro_import.rs
@@ -32,11 +32,11 @@ struct MacroLoader<'a> {
 }
 
 impl<'a> MacroLoader<'a> {
-    fn new(sess: &'a Session, cstore: &'a CStore) -> MacroLoader<'a> {
+    fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> MacroLoader<'a> {
         MacroLoader {
             sess: sess,
             span_whitelist: HashSet::new(),
-            reader: CrateReader::new(sess, cstore),
+            reader: CrateReader::new(sess, cstore, crate_name),
             macros: vec![],
         }
     }
@@ -47,10 +47,13 @@ pub fn call_bad_macro_reexport(a: &Session, b: Span) {
 }
 
 /// Read exported macros.
-pub fn read_macro_defs(sess: &Session, cstore: &CStore, krate: &ast::Crate)
+pub fn read_macro_defs(sess: &Session,
+                       cstore: &CStore,
+                       krate: &ast::Crate,
+                       crate_name: &str)
                        -> Vec<ast::MacroDef>
 {
-    let mut loader = MacroLoader::new(sess, cstore);
+    let mut loader = MacroLoader::new(sess, cstore, crate_name);
 
     // We need to error on `#[macro_use] extern crate` when it isn't at the
     // crate root, because `$crate` won't work properly. Identify these by
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index a950198a4e4..ac40215bbb1 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -44,9 +44,12 @@ fn call_malformed_plugin_attribute(a: &Session, b: Span) {
 }
 
 /// Read plugin metadata and dynamically load registrar functions.
-pub fn load_plugins(sess: &Session, cstore: &CStore, krate: &ast::Crate,
+pub fn load_plugins(sess: &Session,
+                    cstore: &CStore,
+                    krate: &ast::Crate,
+                    crate_name: &str,
                     addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader::new(sess, cstore);
+    let mut loader = PluginLoader::new(sess, cstore, crate_name);
 
     for attr in &krate.attrs {
         if !attr.check_name("plugin") {
@@ -82,10 +85,10 @@ pub fn load_plugins(sess: &Session, cstore: &CStore, krate: &ast::Crate,
 }
 
 impl<'a> PluginLoader<'a> {
-    fn new(sess: &'a Session, cstore: &'a CStore) -> PluginLoader<'a> {
+    fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> PluginLoader<'a> {
         PluginLoader {
             sess: sess,
-            reader: CrateReader::new(sess, cstore),
+            reader: CrateReader::new(sess, cstore, crate_name),
             plugins: vec![],
         }
     }
diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs
index f9bed0019df..6edf8db9bf7 100644
--- a/src/librustc_trans/back/symbol_names.rs
+++ b/src/librustc_trans/back/symbol_names.rs
@@ -78,11 +78,12 @@
 //!
 //! - In order to be able to also use symbols from two versions of the same
 //!   crate (which naturally also have the same name), a stronger measure is
-//!   required: The compiler accepts an arbitrary "salt" value via the
-//!   `-C metadata` commandline argument. This salt is then fed into the symbol
-//!   hash of every exported item. Consequently, the symbols in two identical
-//!   crates but with different salts are not in conflict with each other. This
-//!   facility is mainly intended to be used by build tools like Cargo.
+//!   required: The compiler accepts an arbitrary "disambiguator" value via the
+//!   `-C metadata` commandline argument. This disambiguator is then fed into
+//!   the symbol hash of every exported item. Consequently, the symbols in two
+//!   identical crates but with different disambiguators are not in conflict
+//!   with each other. This facility is mainly intended to be used by build
+//!   tools like Cargo.
 //!
 //! A note on symbol name stability
 //! -------------------------------
diff --git a/src/test/auxiliary/inline-default-methods.rs b/src/test/auxiliary/inline-default-methods.rs
index 5f1bd7ab522..e21e6ad2043 100644
--- a/src/test/auxiliary/inline-default-methods.rs
+++ b/src/test/auxiliary/inline-default-methods.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub trait Foo {
     fn bar(&self);
     fn foo(&mut self) {}
diff --git a/src/test/auxiliary/issue-13698.rs b/src/test/auxiliary/issue-13698.rs
index 0bb2133c833..ecddfe99b3b 100644
--- a/src/test/auxiliary/issue-13698.rs
+++ b/src/test/auxiliary/issue-13698.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub trait Foo {
     #[doc(hidden)]
     fn foo(&self) {}
diff --git a/src/test/auxiliary/issue-15318.rs b/src/test/auxiliary/issue-15318.rs
index 9e42dbfbc6b..145b4df6299 100644
--- a/src/test/auxiliary/issue-15318.rs
+++ b/src/test/auxiliary/issue-15318.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 #![doc(html_root_url = "http://example.com/")]
 
 /// dox
diff --git a/src/test/auxiliary/issue-17476.rs b/src/test/auxiliary/issue-17476.rs
index d3a86035742..644d1634e9d 100644
--- a/src/test/auxiliary/issue-17476.rs
+++ b/src/test/auxiliary/issue-17476.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
 
 #![doc(html_root_url = "http://example.com")]
 
diff --git a/src/test/auxiliary/issue-19190-3.rs b/src/test/auxiliary/issue-19190-3.rs
index 7403bcf4afb..2c9271202a6 100644
--- a/src/test/auxiliary/issue-19190-3.rs
+++ b/src/test/auxiliary/issue-19190-3.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 use std::ops::Deref;
 
 pub struct Foo;
diff --git a/src/test/auxiliary/issue-20646.rs b/src/test/auxiliary/issue-20646.rs
index 150d8018f08..815b78a91d9 100644
--- a/src/test/auxiliary/issue-20646.rs
+++ b/src/test/auxiliary/issue-20646.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub trait Trait {
     type Output;
 }
diff --git a/src/test/auxiliary/issue-20727.rs b/src/test/auxiliary/issue-20727.rs
index aea8b429d9f..2ec761fad96 100644
--- a/src/test/auxiliary/issue-20727.rs
+++ b/src/test/auxiliary/issue-20727.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub trait Deref {
     type Target: ?Sized;
 
diff --git a/src/test/auxiliary/issue-21092.rs b/src/test/auxiliary/issue-21092.rs
index 6d6046cc7bf..e906311e3ae 100644
--- a/src/test/auxiliary/issue-21092.rs
+++ b/src/test/auxiliary/issue-21092.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub trait Foo {
     type Bar;
     fn foo(&self) {}
diff --git a/src/test/auxiliary/issue-21801.rs b/src/test/auxiliary/issue-21801.rs
index ada6c692502..f618edec598 100644
--- a/src/test/auxiliary/issue-21801.rs
+++ b/src/test/auxiliary/issue-21801.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub struct Foo;
 
 impl Foo {
diff --git a/src/test/auxiliary/issue-22025.rs b/src/test/auxiliary/issue-22025.rs
index 554b580ae2b..35a37e27d91 100644
--- a/src/test/auxiliary/issue-22025.rs
+++ b/src/test/auxiliary/issue-22025.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub mod foo {
 
     pub trait Foo {}
diff --git a/src/test/auxiliary/issue-27362.rs b/src/test/auxiliary/issue-27362.rs
index e551d623ae7..25de698cad1 100644
--- a/src/test/auxiliary/issue-27362.rs
+++ b/src/test/auxiliary/issue-27362.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 #![feature(const_fn)]
 
 pub const fn foo() {}
diff --git a/src/test/auxiliary/issue-29584.rs b/src/test/auxiliary/issue-29584.rs
index 4a9e6126fc6..63c79f875ef 100644
--- a/src/test/auxiliary/issue-29584.rs
+++ b/src/test/auxiliary/issue-29584.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -Cmetadata=aux
+
 pub struct Foo;
 
 #[doc(hidden)]
diff --git a/src/test/run-make/extern-overrides-distribution/Makefile b/src/test/run-make/extern-overrides-distribution/Makefile
index 110db9f068d..7d063a4c83c 100644
--- a/src/test/run-make/extern-overrides-distribution/Makefile
+++ b/src/test/run-make/extern-overrides-distribution/Makefile
@@ -1,5 +1,5 @@
 -include ../tools.mk
 
 all:
-	$(RUSTC) libc.rs
+	$(RUSTC) libc.rs -Cmetadata=foo
 	$(RUSTC) main.rs --extern libc=$(TMPDIR)/liblibc.rlib
diff --git a/src/test/run-make/issue-26006/Makefile b/src/test/run-make/issue-26006/Makefile
index de89a6f6ad6..66aa78d5386 100644
--- a/src/test/run-make/issue-26006/Makefile
+++ b/src/test/run-make/issue-26006/Makefile
@@ -12,7 +12,7 @@ time: libc
 
 libc:
 	mkdir -p $(OUT)/libc
-	$(RUSTC) in/libc/lib.rs --crate-name=libc -o $(OUT)/libc/liblibc.rlib
+	$(RUSTC) in/libc/lib.rs --crate-name=libc -Cmetadata=foo -o $(OUT)/libc/liblibc.rlib
 else
 all:
 endif