Take the original extra-filename passed to a crate into account when

resolving it as a dependency.

Fixes #46816
This commit is contained in:
Chris Manchester 2018-03-13 11:58:53 -07:00
parent 9942012f41
commit bd8154784e
9 changed files with 57 additions and 14 deletions

View File

@ -589,6 +589,7 @@ define_dep_nodes!( <'tcx>
[input] CrateDisambiguator(CrateNum),
[input] CrateHash(CrateNum),
[input] OriginalCrateName(CrateNum),
[input] ExtraFileName(CrateNum),
[] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
[] AllTraitImplementations(CrateNum),

View File

@ -466,6 +466,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
}
}
impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the extra filename for a crate")
}
}
impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
format!("looking up implementations of a trait in a crate")

View File

@ -328,6 +328,7 @@ define_maps! { <'tcx>
[] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
[] fn crate_hash: CrateHash(CrateNum) -> Svh,
[] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
[] fn extra_filename: ExtraFileName(CrateNum) -> String,
[] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
-> Lrc<Vec<DefId>>,

View File

@ -881,6 +881,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
DepKind::CrateHash => { force!(crate_hash, krate!()); }
DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
DepKind::AllTraitImplementations => {
force!(all_trait_implementations, krate!());

View File

@ -262,6 +262,7 @@ impl<'a> CrateLoader<'a> {
ident: Symbol,
name: Symbol,
hash: Option<&Svh>,
extra_filename: Option<&str>,
span: Span,
path_kind: PathKind,
mut dep_kind: DepKind)
@ -277,6 +278,7 @@ impl<'a> CrateLoader<'a> {
ident,
crate_name: name,
hash: hash.map(|a| &*a),
extra_filename: extra_filename,
filesearch: self.sess.target_filesearch(path_kind),
target: &self.sess.target.target,
triple: &self.sess.opts.target_triple,
@ -409,7 +411,8 @@ impl<'a> CrateLoader<'a> {
::std::iter::once(krate).chain(crate_root.crate_deps
.decode(metadata)
.map(|dep| {
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash,
dep.extra_filename);
if dep.kind == DepKind::UnexportedMacrosOnly {
return krate;
}
@ -418,7 +421,8 @@ impl<'a> CrateLoader<'a> {
_ => dep.kind,
};
let (local_cnum, ..) = self.resolve_crate(
root, dep.name, dep.name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
PathKind::Dependency, dep_kind,
);
local_cnum
})).collect()
@ -437,6 +441,7 @@ impl<'a> CrateLoader<'a> {
ident: orig_name,
crate_name: rename,
hash: None,
extra_filename: None,
filesearch: self.sess.host_filesearch(PathKind::Crate),
target: &self.sess.host,
triple: &host_triple,
@ -664,7 +669,7 @@ impl<'a> CrateLoader<'a> {
let dep_kind = DepKind::Implicit;
let (cnum, data) =
self.resolve_crate(&None, name, name, None, DUMMY_SP, PathKind::Crate, dep_kind);
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind);
// Sanity check the loaded crate to ensure it is indeed a panic runtime
// and the panic strategy is indeed what we thought it was.
@ -771,7 +776,7 @@ impl<'a> CrateLoader<'a> {
let symbol = Symbol::intern(name);
let dep_kind = DepKind::Explicit;
let (_, data) =
self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
PathKind::Crate, dep_kind);
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
@ -794,7 +799,7 @@ impl<'a> CrateLoader<'a> {
let symbol = Symbol::intern("profiler_builtins");
let dep_kind = DepKind::Implicit;
let (_, data) =
self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
PathKind::Crate, dep_kind);
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
@ -909,6 +914,7 @@ impl<'a> CrateLoader<'a> {
name,
name,
None,
None,
DUMMY_SP,
PathKind::Crate,
DepKind::Implicit);
@ -1059,7 +1065,8 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
};
let (cnum, ..) = self.resolve_crate(
&None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind,
&None, item.ident.name, orig_name, None, None,
item.span, PathKind::Crate, dep_kind,
);
let def_id = definitions.opt_local_def_id(item.id).unwrap();
@ -1074,6 +1081,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
}
fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum {
self.resolve_crate(&None, name, name, None, span, PathKind::Crate, DepKind::Explicit).0
self.resolve_crate(&None, name, name, None, None, span, PathKind::Crate,
DepKind::Explicit).0
}
}

View File

@ -213,6 +213,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
crate_hash => { cdata.hash() }
original_crate_name => { cdata.name() }
extra_filename => { cdata.root.extra_filename.clone() }
implementations_of_trait => {
let mut result = vec![];
let filter = Some(other);

View File

@ -462,6 +462,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let has_global_allocator = tcx.sess.has_global_allocator.get();
let root = self.lazy(&CrateRoot {
name: tcx.crate_name(LOCAL_CRATE),
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
triple: tcx.sess.opts.target_triple.clone(),
hash: link_meta.crate_hash,
disambiguator: tcx.sess.local_crate_disambiguator(),
@ -1357,6 +1358,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
name: self.tcx.original_crate_name(cnum),
hash: self.tcx.crate_hash(cnum),
kind: self.tcx.dep_kind(cnum),
extra_filename: self.tcx.extra_filename(cnum),
};
(cnum, dep)
})

View File

@ -83,7 +83,10 @@
//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
//! filename have the right prefix/suffix?
//! 2. Does the filename have the right prefix for the crate name being queried?
//! This is filtering for files like `libfoo*.rlib` and such.
//! This is filtering for files like `libfoo*.rlib` and such. If the crate
//! we're looking for was originally compiled with -C extra-filename, the
//! extra filename will be included in this prefix to reduce reading
//! metadata from crates that would otherwise share our prefix.
//! 3. Is the file an actual rust library? This is done by loading the metadata
//! from the library and making sure it's actually there.
//! 4. Does the name in the metadata agree with the name of the library?
@ -236,6 +239,7 @@ use syntax_pos::Span;
use rustc_back::target::{Target, TargetTriple};
use std::cmp;
use std::collections::HashSet;
use std::fmt;
use std::fs;
use std::io::{self, Read};
@ -256,6 +260,7 @@ pub struct Context<'a> {
pub ident: Symbol,
pub crate_name: Symbol,
pub hash: Option<&'a Svh>,
pub extra_filename: Option<&'a str>,
// points to either self.sess.target.target or self.sess.host, must match triple
pub target: &'a Target,
pub triple: &'a TargetTriple,
@ -303,7 +308,12 @@ impl CratePaths {
impl<'a> Context<'a> {
pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
self.find_library_crate()
let mut seen_paths = HashSet::new();
match self.extra_filename {
Some(s) => self.find_library_crate(s, &mut seen_paths)
.or_else(|| self.find_library_crate("", &mut seen_paths)),
None => self.find_library_crate("", &mut seen_paths)
}
}
pub fn report_errs(&mut self) -> ! {
@ -419,7 +429,10 @@ impl<'a> Context<'a> {
unreachable!();
}
fn find_library_crate(&mut self) -> Option<Library> {
fn find_library_crate(&mut self,
extra_prefix: &str,
seen_paths: &mut HashSet<PathBuf>)
-> Option<Library> {
// If an SVH is specified, then this is a transitive dependency that
// must be loaded via -L plus some filtering.
if self.hash.is_none() {
@ -434,9 +447,9 @@ impl<'a> Context<'a> {
let staticpair = self.staticlibname();
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
let dylib_prefix = format!("{}{}", dypair.0, self.crate_name);
let rlib_prefix = format!("lib{}", self.crate_name);
let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name);
let dylib_prefix = format!("{}{}{}", dypair.0, self.crate_name, extra_prefix);
let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix);
let staticlib_prefix = format!("{}{}{}", staticpair.0, self.crate_name, extra_prefix);
let mut candidates = FxHashMap();
let mut staticlibs = vec![];
@ -476,6 +489,7 @@ impl<'a> Context<'a> {
}
return FileDoesntMatch;
};
info!("lib candidate: {}", path.display());
let hash_str = hash.to_string();
@ -484,6 +498,10 @@ impl<'a> Context<'a> {
let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot;
fs::canonicalize(path)
.map(|p| {
if seen_paths.contains(&p) {
return FileDoesntMatch
};
seen_paths.insert(p.clone());
match found_kind {
CrateFlavor::Rlib => { rlibs.insert(p, kind); }
CrateFlavor::Rmeta => { rmetas.insert(p, kind); }

View File

@ -188,6 +188,7 @@ pub enum LazyState {
pub struct CrateRoot {
pub name: Symbol,
pub triple: TargetTriple,
pub extra_filename: String,
pub hash: hir::svh::Svh,
pub disambiguator: CrateDisambiguator,
pub panic_strategy: PanicStrategy,
@ -216,12 +217,14 @@ pub struct CrateDep {
pub name: ast::Name,
pub hash: hir::svh::Svh,
pub kind: DepKind,
pub extra_filename: String,
}
impl_stable_hash_for!(struct CrateDep {
name,
hash,
kind
kind,
extra_filename
});
#[derive(RustcEncodable, RustcDecodable)]