diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2016-02-26 16:25:25 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-03-25 14:07:18 -0400 |
| commit | 2eebb7b60588902c51d6d8dd9e695c6babaa8aa2 (patch) | |
| tree | 560ad9f8aaef9fed7162961441e0ff7cdfe50197 /src | |
| parent | fafdfa8bdc2cf762d84ca2e18215d3e11caf3af5 (diff) | |
| download | rust-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')
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 |
