Skip to content

Commit 871ec86

Browse files
committed
Only check for already loaded indirect dependencies in existing_match
For direct dependencies it is a lot harder to not accidentally resolve an ambiguity through an indirect dependency edge and as it turns out this check was actually more expensive than the work it skipped. For indirect dependencies existing_match is still necessary due to an assert in load, but at the same time it also can't accidentally resolve an ambiguity given that we already know exactly which crate to look for based on the crate hash.
1 parent 3743df9 commit 871ec86

File tree

1 file changed

+8
-43
lines changed

1 file changed

+8
-43
lines changed

compiler/rustc_metadata/src/creader.rs

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -514,55 +514,20 @@ impl CStore {
514514
}
515515
}
516516

517-
fn existing_match(
518-
&self,
519-
externs: &Externs,
520-
name: Symbol,
521-
hash: Option<Svh>,
522-
) -> Option<CrateNum> {
517+
fn existing_match(&self, name: Symbol, hash: Option<Svh>) -> Option<CrateNum> {
518+
let hash = hash?;
519+
523520
for (cnum, data) in self.iter_crate_data() {
524521
if data.name() != name {
525522
trace!("{} did not match {}", data.name(), name);
526523
continue;
527524
}
528525

529-
match hash {
530-
Some(hash) if hash == data.hash() => return Some(cnum),
531-
Some(hash) => {
532-
debug!("actual hash {} did not match expected {}", hash, data.hash());
533-
continue;
534-
}
535-
None => {}
536-
}
537-
538-
// When the hash is None we're dealing with a top-level dependency
539-
// in which case we may have a specification on the command line for
540-
// this library. Even though an upstream library may have loaded
541-
// something of the same name, we have to make sure it was loaded
542-
// from the exact same location as well.
543-
//
544-
// We're also sure to compare *paths*, not actual byte slices. The
545-
// `source` stores paths which are normalized which may be different
546-
// from the strings on the command line.
547-
let source = data.source();
548-
if let Some(entry) = externs.get(name.as_str()) {
549-
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
550-
if let Some(mut files) = entry.files() {
551-
if files.any(|l| {
552-
let l = l.canonicalized();
553-
source.dylib.as_ref() == Some(l)
554-
|| source.rlib.as_ref() == Some(l)
555-
|| source.rmeta.as_ref() == Some(l)
556-
}) {
557-
return Some(cnum);
558-
}
559-
}
560-
continue;
526+
if hash == data.hash() {
527+
return Some(cnum);
528+
} else {
529+
debug!("actual hash {} did not match expected {}", hash, data.hash());
561530
}
562-
563-
// While the crate name matched, no --extern crate_name=path matched. It is possible
564-
// that we have already loaded the target crate, but if that happens CStore::load will
565-
// indicate so and we gracefully handle this, just potentially wasting a bit of time.
566531
}
567532

568533
None
@@ -799,7 +764,7 @@ impl CStore {
799764
let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
800765
let private_dep = origin.private_dep();
801766

802-
let result = if let Some(cnum) = self.existing_match(&tcx.sess.opts.externs, name, hash) {
767+
let result = if let Some(cnum) = self.existing_match(name, hash) {
803768
(LoadResult::Previous(cnum), None)
804769
} else {
805770
info!("falling back to a load");

0 commit comments

Comments
 (0)