From 0a21018d14f7c0613459dc41e071f1efde102c4e Mon Sep 17 00:00:00 2001 From: msizanoen Date: Tue, 22 Oct 2019 15:47:07 +0700 Subject: [PATCH 1/2] 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. --- src/librustc/middle/cstore.rs | 1 + src/librustc/query/mod.rs | 4 ++++ src/librustc/ty/context.rs | 4 ++++ src/librustc_metadata/creader.rs | 20 +++++++++++++------- src/librustc_metadata/cstore.rs | 3 +++ src/librustc_metadata/cstore_impl.rs | 4 ++++ src/librustc_metadata/encoder.rs | 1 + src/librustc_metadata/locator.rs | 2 ++ src/librustc_metadata/schema.rs | 1 + 9 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index d5558db2397e7..1f4086227327e 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -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; fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics; fn postorder_cnums_untracked(&self) -> Vec; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d13b21bb7722b..86ed2419e048b 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -754,6 +754,10 @@ rustc_queries! { eval_always desc { "looking up the hash a crate" } } + query crate_host_hash(_: CrateNum) -> Option { + 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" } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index bdf9b2d7f3f27..25e953ee257ec 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -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()) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 540b06b3a8be9..07c49d91797d4 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -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> { 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, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 8dfc921c95b3d..b7596d2018f7e 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -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, // --- Data used only for improving diagnostics --- diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index d942a19194a14..2e6ed1d187a68 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -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 { + 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. diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index f6498f4eaa891..f2b0cfa530508 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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), }; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index a5298402dd411..4a263250f9b0d 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -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, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index ad39aa34fd5c8..8bece2511166e 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -217,6 +217,7 @@ crate struct CrateRoot<'tcx> { crate struct CrateDep { pub name: ast::Name, pub hash: Svh, + pub host_hash: Option, pub kind: DepKind, pub extra_filename: String, } From 8a0d2332f9267f4fc5c8e836c94494e2faf644a4 Mon Sep 17 00:00:00 2001 From: msizanoen1 Date: Tue, 29 Oct 2019 12:17:18 +0700 Subject: [PATCH 2/2] Adjust rustc-workspace-hack --- Cargo.lock | 1 + src/tools/rustc-workspace-hack/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9119af1266727..71ea6f242b13f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3393,6 +3393,7 @@ dependencies = [ "serde", "serde_json", "smallvec", + "syn 0.15.35", "url 2.1.0", "winapi 0.3.6", ] diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index a78cbdc2c4c6a..285af038a1ef4 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -64,7 +64,7 @@ serde = { version = "1.0.82", features = ['derive'] } serde_json = { version = "1.0.31", features = ["raw_value"] } smallvec = { version = "0.6", features = ['union', 'may_dangle'] } url = { version = "2.0", features = ['serde'] } - +syn = { version = "0.15", features = ['full'] } [target.'cfg(not(windows))'.dependencies] openssl = { version = "0.10.12", optional = true }