Skip to content

Commit c01e2f0

Browse files
committed
auto merge of #13017 : alexcrichton/rust/issue-13010, r=huonw
Previously, any library of the pattern `lib<name>-<hash>-<version>.so` was >considered a candidate (rightly so) for loading a crate. Sets are generated for each unique `<hash>`, and then from these sets a candidate is selected. If a set contained more than one element, then it immediately generated an error saying that multiple copies of the same dylib were found. This is incorrect because each candidate needs to be validated to actually contain a rust library (valid metadata). This commit alters the logic to filter each set of candidates for a hash to only libraries which are actually rust libraries. This means that if multiple false positives are found with the right name pattern, they're all ignored. Closes #13010
2 parents 8cfef59 + 068740b commit c01e2f0

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

src/librustc/metadata/loader.rs

+27-19
Original file line numberDiff line numberDiff line change
@@ -284,38 +284,46 @@ impl<'a> Context<'a> {
284284
// reading dylib metadata is quite slow.
285285
fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
286286
slot: &mut Option<MetadataBlob>) -> Option<Path> {
287-
if m.len() == 0 { return None }
288-
if m.len() > 1 {
289-
self.sess.span_err(self.span,
290-
format!("multiple {} candidates for `{}` \
291-
found", flavor, self.crate_id.name));
292-
for (i, path) in m.iter().enumerate() {
293-
self.sess.span_note(self.span,
294-
format!(r"candidate \#{}: {}", i + 1,
295-
path.display()));
296-
}
297-
return None
298-
}
287+
let mut ret = None::<Path>;
288+
let mut error = 0;
299289

300-
let lib = m.move_iter().next().unwrap();
301-
if slot.is_none() {
290+
for lib in m.move_iter() {
302291
info!("{} reading metadata from: {}", flavor, lib.display());
303-
match get_metadata_section(self.os, &lib) {
292+
let metadata = match get_metadata_section(self.os, &lib) {
304293
Ok(blob) => {
305294
if self.crate_matches(blob.as_slice()) {
306-
*slot = Some(blob);
295+
blob
307296
} else {
308297
info!("metadata mismatch");
309-
return None;
298+
continue
310299
}
311300
}
312301
Err(_) => {
313302
info!("no metadata found");
314-
return None
303+
continue
315304
}
305+
};
306+
if ret.is_some() {
307+
self.sess.span_err(self.span,
308+
format!("multiple {} candidates for `{}` \
309+
found", flavor, self.crate_id.name));
310+
self.sess.span_note(self.span,
311+
format!(r"candidate \#1: {}",
312+
ret.get_ref().display()));
313+
error = 1;
314+
ret = None;
315+
}
316+
if error > 0 {
317+
error += 1;
318+
self.sess.span_note(self.span,
319+
format!(r"candidate \#{}: {}", error,
320+
lib.display()));
321+
continue
316322
}
323+
*slot = Some(metadata);
324+
ret = Some(lib);
317325
}
318-
return Some(lib);
326+
return if error > 0 {None} else {ret}
319327
}
320328

321329
fn crate_matches(&mut self, crate_data: &[u8]) -> bool {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(RUSTC) foo.rs
5+
touch $(call DYLIB,foo-something-special)
6+
touch $(call DYLIB,foo-something-special2)
7+
$(RUSTC) bar.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate foo;
12+
13+
fn main() { foo::foo() }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[crate_type = "dylib"];
12+
13+
pub fn foo() {}

0 commit comments

Comments
 (0)