Implement dual proc macro hashing

This changes the mechanism of `-Z dual-proc-macro` to record the host
proc macro hash in the transistive dependency information and use it
during dependency resolution instead of resolving only by name.
This commit is contained in:
msizanoen 2019-10-22 15:47:07 +07:00 committed by msizanoen1
parent 2f16be42dd
commit 0a21018d14
9 changed files with 33 additions and 7 deletions

View File

@ -216,6 +216,7 @@ pub trait CrateStore {
fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
fn crate_host_hash_untracked(&self, cnum: CrateNum) -> Option<Svh>;
fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics;
fn postorder_cnums_untracked(&self) -> Vec<CrateNum>;

View File

@ -754,6 +754,10 @@ rustc_queries! {
eval_always
desc { "looking up the hash a crate" }
}
query crate_host_hash(_: CrateNum) -> Option<Svh> {
eval_always
desc { "looking up the hash of a host version of a crate" }
}
query original_crate_name(_: CrateNum) -> Symbol {
eval_always
desc { "looking up the original name a crate" }

View File

@ -3015,6 +3015,10 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
assert_eq!(cnum, LOCAL_CRATE);
tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
};
providers.crate_host_hash = |tcx, cnum| {
assert_ne!(cnum, LOCAL_CRATE);
tcx.cstore.crate_host_hash_untracked(cnum)
};
providers.postorder_cnums = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
tcx.arena.alloc_slice(&tcx.cstore.postorder_cnums_untracked())

View File

@ -191,6 +191,7 @@ impl<'a> CrateLoader<'a> {
let Library { source, metadata } = lib;
let crate_root = metadata.get_root();
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash);
self.verify_no_symbol_conflicts(span, &crate_root);
let private_dep = self.sess.opts.externs.get(&name.as_str())
@ -245,6 +246,7 @@ impl<'a> CrateLoader<'a> {
def_path_table,
trait_impls,
root: crate_root,
host_hash,
blob: metadata,
cnum_map,
cnum,
@ -283,9 +285,7 @@ impl<'a> CrateLoader<'a> {
LoadResult::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)),
LoadResult::Loaded(library) => Some(LoadResult::Loaded(library))
};
// Don't look for a matching hash when looking for the host crate.
// It won't be the same as the target crate hash
locate_ctxt.hash = None;
locate_ctxt.hash = locate_ctxt.host_hash;
// Use the locate_ctxt when looking for the host proc macro crate, as that is required
// so we want it to affect the error message
(locate_ctxt, result)
@ -334,10 +334,15 @@ impl<'a> CrateLoader<'a> {
dep: Option<(&'b CratePaths, &'b CrateDep)>,
) -> Result<CrateNum, LoadError<'b>> {
info!("resolving crate `{}`", name);
let (root, hash, extra_filename, path_kind) = match dep {
Some((root, dep)) =>
(Some(root), Some(&dep.hash), Some(&dep.extra_filename[..]), PathKind::Dependency),
None => (None, None, None, PathKind::Crate),
let (root, hash, host_hash, extra_filename, path_kind) = match dep {
Some((root, dep)) => (
Some(root),
Some(&dep.hash),
dep.host_hash.as_ref(),
Some(&dep.extra_filename[..]),
PathKind::Dependency
),
None => (None, None, None, None, PathKind::Crate),
};
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
(LoadResult::Previous(cnum), None)
@ -348,6 +353,7 @@ impl<'a> CrateLoader<'a> {
span,
crate_name: name,
hash,
host_hash,
extra_filename,
filesearch: self.sess.target_filesearch(path_kind),
target: &self.sess.target.target,

View File

@ -10,6 +10,7 @@ use rustc::mir::interpret::AllocDecodingState;
use rustc_index::vec::IndexVec;
use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell};
use rustc_data_structures::svh::Svh;
use syntax::ast;
use syntax::edition::Edition;
use syntax_expand::base::SyntaxExtension;
@ -87,6 +88,8 @@ crate struct CrateMetadata {
/// Whether or not this crate should be consider a private dependency
/// for purposes of the 'exported_private_dependencies' lint
crate private_dep: bool,
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
crate host_hash: Option<Svh>,
// --- Data used only for improving diagnostics ---

View File

@ -505,6 +505,10 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(cnum).root.hash
}
fn crate_host_hash_untracked(&self, cnum: CrateNum) -> Option<Svh> {
self.get_crate_data(cnum).host_hash
}
/// Returns the `DefKey` for a given `DefId`. This indicates the
/// parent `DefId` as well as some idea of what kind of data the
/// `DefId` refers to.

View File

@ -1418,6 +1418,7 @@ impl EncodeContext<'tcx> {
let dep = CrateDep {
name: self.tcx.original_crate_name(cnum),
hash: self.tcx.crate_hash(cnum),
host_hash: self.tcx.crate_host_hash(cnum),
kind: self.tcx.dep_kind(cnum),
extra_filename: self.tcx.extra_filename(cnum),
};

View File

@ -258,6 +258,7 @@ crate struct Context<'a> {
pub span: Span,
pub crate_name: Symbol,
pub hash: Option<&'a Svh>,
pub host_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,
@ -929,6 +930,7 @@ pub fn find_plugin_registrar(
span,
crate_name: name,
hash: None,
host_hash: None,
extra_filename: None,
filesearch: sess.host_filesearch(PathKind::Crate),
target: &sess.host,

View File

@ -217,6 +217,7 @@ crate struct CrateRoot<'tcx> {
crate struct CrateDep {
pub name: ast::Name,
pub hash: Svh,
pub host_hash: Option<Svh>,
pub kind: DepKind,
pub extra_filename: String,
}