diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 6a1e3663a54ef..eb47b30b9c03c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -284,38 +284,46 @@ impl<'a> Context<'a> { // reading dylib metadata is quite slow. fn extract_one(&mut self, m: HashSet, flavor: &str, slot: &mut Option) -> Option { - if m.len() == 0 { return None } - if m.len() > 1 { - self.sess.span_err(self.span, - format!("multiple {} candidates for `{}` \ - found", flavor, self.crate_id.name)); - for (i, path) in m.iter().enumerate() { - self.sess.span_note(self.span, - format!(r"candidate \#{}: {}", i + 1, - path.display())); - } - return None - } + let mut ret = None::; + let mut error = 0; - let lib = m.move_iter().next().unwrap(); - if slot.is_none() { + for lib in m.move_iter() { info!("{} reading metadata from: {}", flavor, lib.display()); - match get_metadata_section(self.os, &lib) { + let metadata = match get_metadata_section(self.os, &lib) { Ok(blob) => { if self.crate_matches(blob.as_slice()) { - *slot = Some(blob); + blob } else { info!("metadata mismatch"); - return None; + continue } } Err(_) => { info!("no metadata found"); - return None + continue } + }; + if ret.is_some() { + self.sess.span_err(self.span, + format!("multiple {} candidates for `{}` \ + found", flavor, self.crate_id.name)); + self.sess.span_note(self.span, + format!(r"candidate \#1: {}", + ret.get_ref().display())); + error = 1; + ret = None; + } + if error > 0 { + error += 1; + self.sess.span_note(self.span, + format!(r"candidate \#{}: {}", error, + lib.display())); + continue } + *slot = Some(metadata); + ret = Some(lib); } - return Some(lib); + return if error > 0 {None} else {ret} } fn crate_matches(&mut self, crate_data: &[u8]) -> bool { diff --git a/src/test/run-make/suspicious-library/Makefile b/src/test/run-make/suspicious-library/Makefile new file mode 100644 index 0000000000000..621f3064b5ced --- /dev/null +++ b/src/test/run-make/suspicious-library/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs + touch $(call DYLIB,foo-something-special) + touch $(call DYLIB,foo-something-special2) + $(RUSTC) bar.rs diff --git a/src/test/run-make/suspicious-library/bar.rs b/src/test/run-make/suspicious-library/bar.rs new file mode 100644 index 0000000000000..ed0e8a7e23e80 --- /dev/null +++ b/src/test/run-make/suspicious-library/bar.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate foo; + +fn main() { foo::foo() } diff --git a/src/test/run-make/suspicious-library/foo.rs b/src/test/run-make/suspicious-library/foo.rs new file mode 100644 index 0000000000000..890fd3a7dd661 --- /dev/null +++ b/src/test/run-make/suspicious-library/foo.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_type = "dylib"]; + +pub fn foo() {}