From bd838a3b7ea3f6b410058e9413f5745586d3a459 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 24 Jul 2014 22:39:52 -0700 Subject: [PATCH] rustc: Compare paths with --extern, not bytes The right hand side of the comparison in these checks are values of type Option<&Path> which are normalized versions of the left-hand side, so they're not guaranteed to be byte-for-byte equivalent even though they're the same path. For this reasons, the command line arguments are promoted to paths for comparison of equality. This fixes a bug on windows where if a library was specified with --extern it would then be picked up twice because it was not considered to have been previously registered. --- src/librustc/metadata/creader.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 2314b3f74e3c4..0445b4d4e9e1f 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -293,13 +293,16 @@ fn existing_match(e: &Env, name: &str, // library. Even though an upstream library may have loaded something of // the same name, we have to make sure it was loaded from the exact same // location as well. + // + // We're also sure to compare *paths*, not actual byte slices. The + // `source` stores paths which are normalized which may be different + // from the strings on the command line. let source = e.sess.cstore.get_used_crate_source(cnum).unwrap(); - let dylib = source.dylib.as_ref().map(|p| p.as_vec()); - let rlib = source.rlib.as_ref().map(|p| p.as_vec()); match e.sess.opts.externs.find_equiv(&name) { Some(locs) => { let found = locs.iter().any(|l| { - Some(l.as_bytes()) == dylib || Some(l.as_bytes()) == rlib + let l = Some(Path::new(l.as_slice())); + l == source.dylib || l == source.rlib }); if found { ret = Some(cnum);