diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 394cb8389357f..99030febb7380 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -450,6 +450,7 @@ impl<'a> CrateLoader<'a> { &self, locator: &mut CrateLocator<'b>, path_kind: PathKind, + host_hash: Option, ) -> Result)>, CrateError> where 'a: 'b, @@ -459,7 +460,7 @@ impl<'a> CrateLoader<'a> { let mut proc_macro_locator = locator.clone(); // Try to load a proc macro - proc_macro_locator.is_proc_macro = Some(true); + proc_macro_locator.is_proc_macro = true; // Load the proc macro crate for the target let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros { @@ -471,7 +472,7 @@ impl<'a> CrateLoader<'a> { Some(LoadResult::Loaded(library)) => Some(LoadResult::Loaded(library)), None => return Ok(None), }; - locator.hash = locator.host_hash; + locator.hash = host_hash; // Use the locator when looking for the host proc macro crate, as that is required // so we want it to affect the error message (locator, result) @@ -482,7 +483,7 @@ impl<'a> CrateLoader<'a> { // Load the proc macro crate for the host locator.reset(); - locator.is_proc_macro = Some(true); + locator.is_proc_macro = true; locator.target = &self.sess.host; locator.triple = TargetTriple::from_triple(config::host_triple()); locator.filesearch = self.sess.host_filesearch(path_kind); @@ -510,12 +511,9 @@ impl<'a> CrateLoader<'a> { name: Symbol, span: Span, dep_kind: CrateDepKind, - dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> CrateNum { - if dep.is_none() { - self.used_extern_options.insert(name); - } - self.maybe_resolve_crate(name, dep_kind, dep).unwrap_or_else(|err| { + self.used_extern_options.insert(name); + self.maybe_resolve_crate(name, dep_kind, None).unwrap_or_else(|err| { let missing_core = self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err(); err.report(&self.sess, span, missing_core) @@ -551,21 +549,18 @@ impl<'a> CrateLoader<'a> { &*self.metadata_loader, name, hash, - host_hash, extra_filename, false, // is_host path_kind, - root, - Some(false), // is_proc_macro ); match self.load(&mut locator)? { Some(res) => (res, None), None => { dep_kind = CrateDepKind::MacrosOnly; - match self.load_proc_macro(&mut locator, path_kind)? { + match self.load_proc_macro(&mut locator, path_kind, host_hash)? { Some(res) => res, - None => return Err(locator.into_error()), + None => return Err(locator.into_error(root.cloned())), } } } @@ -605,7 +600,7 @@ impl<'a> CrateLoader<'a> { // FIXME: why is this condition necessary? It was adding in #33625 but I // don't know why and the original author doesn't remember ... let can_reuse_cratenum = - locator.triple == self.sess.opts.target_triple || locator.is_proc_macro == Some(true); + locator.triple == self.sess.opts.target_triple || locator.is_proc_macro; Ok(Some(if can_reuse_cratenum { let mut result = LoadResult::Loaded(library); self.cstore.iter_crate_data(|cnum, data| { @@ -755,7 +750,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime @@ -795,7 +790,7 @@ impl<'a> CrateLoader<'a> { ); } - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -1015,7 +1010,7 @@ impl<'a> CrateLoader<'a> { CrateDepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind, None); + let cnum = self.resolve_crate(name, item.span, dep_kind); let path_len = definitions.def_path(def_id).data.len(); self.update_extern_crate( @@ -1034,7 +1029,7 @@ impl<'a> CrateLoader<'a> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, None); + let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit); self.update_extern_crate( cnum, diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 8d1bf6f55df09..d3512b6cf579e 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -240,27 +240,22 @@ use tracing::{debug, info, warn}; #[derive(Clone)] crate struct CrateLocator<'a> { // Immutable per-session configuration. - sess: &'a Session, + only_needs_metadata: bool, + sysroot: &'a Path, metadata_loader: &'a dyn MetadataLoader, // Immutable per-search configuration. crate_name: Symbol, exact_paths: Vec, pub hash: Option, - pub host_hash: Option, extra_filename: Option<&'a str>, pub target: &'a Target, pub triple: TargetTriple, pub filesearch: FileSearch<'a>, - root: Option<&'a CratePaths>, - pub is_proc_macro: Option, + pub is_proc_macro: bool, // Mutable in-progress state or output. - rejected_via_hash: Vec, - rejected_via_triple: Vec, - rejected_via_kind: Vec, - rejected_via_version: Vec, - rejected_via_filename: Vec, + crate_rejections: CrateRejections, } #[derive(Clone)] @@ -298,15 +293,22 @@ impl<'a> CrateLocator<'a> { metadata_loader: &'a dyn MetadataLoader, crate_name: Symbol, hash: Option, - host_hash: Option, extra_filename: Option<&'a str>, is_host: bool, path_kind: PathKind, - root: Option<&'a CratePaths>, - is_proc_macro: Option, ) -> CrateLocator<'a> { + // The all loop is because `--crate-type=rlib --crate-type=rlib` is + // legal and produces both inside this type. + let is_rlib = sess.crate_types().iter().all(|c| *c == CrateType::Rlib); + let needs_object_code = sess.opts.output_types.should_codegen(); + // If we're producing an rlib, then we don't need object code. + // Or, if we're not producing object code, then we don't need it either + // (e.g., if we're a cdylib but emitting just metadata). + let only_needs_metadata = is_rlib || !needs_object_code; + CrateLocator { - sess, + only_needs_metadata, + sysroot: &sess.sysroot, metadata_loader, crate_name, exact_paths: if hash.is_none() { @@ -324,7 +326,6 @@ impl<'a> CrateLocator<'a> { Vec::new() }, hash, - host_hash, extra_filename, target: if is_host { &sess.host } else { &sess.target }, triple: if is_host { @@ -337,22 +338,17 @@ impl<'a> CrateLocator<'a> { } else { sess.target_filesearch(path_kind) }, - root, - is_proc_macro, - rejected_via_hash: Vec::new(), - rejected_via_triple: Vec::new(), - rejected_via_kind: Vec::new(), - rejected_via_version: Vec::new(), - rejected_via_filename: Vec::new(), + is_proc_macro: false, + crate_rejections: CrateRejections::default(), } } crate fn reset(&mut self) { - self.rejected_via_hash.clear(); - self.rejected_via_triple.clear(); - self.rejected_via_kind.clear(); - self.rejected_via_version.clear(); - self.rejected_via_filename.clear(); + self.crate_rejections.via_hash.clear(); + self.crate_rejections.via_triple.clear(); + self.crate_rejections.via_kind.clear(); + self.crate_rejections.via_version.clear(); + self.crate_rejections.via_filename.clear(); } crate fn maybe_load_library_crate(&mut self) -> Result, CrateError> { @@ -435,7 +431,7 @@ impl<'a> CrateLocator<'a> { }; FileMatches }); - self.rejected_via_kind.extend(staticlibs); + self.crate_rejections.via_kind.extend(staticlibs); // We have now collected all known libraries into a set of candidates // keyed of the filename hash listed. For each filename, we also have a @@ -480,18 +476,11 @@ impl<'a> CrateLocator<'a> { } fn needs_crate_flavor(&self, flavor: CrateFlavor) -> bool { - if flavor == CrateFlavor::Dylib && self.is_proc_macro == Some(true) { + if flavor == CrateFlavor::Dylib && self.is_proc_macro { return true; } - // The all loop is because `--crate-type=rlib --crate-type=rlib` is - // legal and produces both inside this type. - let is_rlib = self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib); - let needs_object_code = self.sess.opts.output_types.should_codegen(); - // If we're producing an rlib, then we don't need object code. - // Or, if we're not producing object code, then we don't need it either - // (e.g., if we're a cdylib but emitting just metadata). - if is_rlib || !needs_object_code { + if self.only_needs_metadata { flavor == CrateFlavor::Rmeta } else { // we need all flavors (perhaps not true, but what we do for now) @@ -591,7 +580,7 @@ impl<'a> CrateLocator<'a> { // candidates are all canonicalized, so we canonicalize the sysroot // as well. if let Some((prev, _)) = &ret { - let sysroot = &self.sess.sysroot; + let sysroot = self.sysroot; let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf()); if prev.starts_with(&sysroot) { continue; @@ -613,21 +602,20 @@ impl<'a> CrateLocator<'a> { let found_version = metadata.get_rustc_version(); if found_version != rustc_version { info!("Rejecting via version: expected {} got {}", rustc_version, found_version); - self.rejected_via_version + self.crate_rejections + .via_version .push(CrateMismatch { path: libpath.to_path_buf(), got: found_version }); return None; } let root = metadata.get_root(); - if let Some(expected_is_proc_macro) = self.is_proc_macro { - let is_proc_macro = root.is_proc_macro_crate(); - if is_proc_macro != expected_is_proc_macro { - info!( - "Rejecting via proc macro: expected {} got {}", - expected_is_proc_macro, is_proc_macro - ); - return None; - } + if root.is_proc_macro_crate() != self.is_proc_macro { + info!( + "Rejecting via proc macro: expected {} got {}", + self.is_proc_macro, + root.is_proc_macro_crate(), + ); + return None; } if self.exact_paths.is_empty() && self.crate_name != root.name() { @@ -637,7 +625,7 @@ impl<'a> CrateLocator<'a> { if root.triple() != &self.triple { info!("Rejecting via crate triple: expected {} got {}", self.triple, root.triple()); - self.rejected_via_triple.push(CrateMismatch { + self.crate_rejections.via_triple.push(CrateMismatch { path: libpath.to_path_buf(), got: root.triple().to_string(), }); @@ -648,7 +636,8 @@ impl<'a> CrateLocator<'a> { if let Some(expected_hash) = self.hash { if hash != expected_hash { info!("Rejecting via hash: expected {} got {}", expected_hash, hash); - self.rejected_via_hash + self.crate_rejections + .via_hash .push(CrateMismatch { path: libpath.to_path_buf(), got: hash.to_string() }); return None; } @@ -702,7 +691,8 @@ impl<'a> CrateLocator<'a> { dylibs.insert(loc_canon, PathKind::ExternFlag); } } else { - self.rejected_via_filename + self.crate_rejections + .via_filename .push(CrateMismatch { path: loc.original().clone(), got: String::new() }); } } @@ -711,18 +701,14 @@ impl<'a> CrateLocator<'a> { Ok(self.extract_lib(rlibs, rmetas, dylibs)?.map(|(_, lib)| lib)) } - crate fn into_error(self) -> CrateError { + crate fn into_error(self, root: Option) -> CrateError { CrateError::LocatorCombined(CombinedLocatorError { crate_name: self.crate_name, - root: self.root.cloned(), + root, triple: self.triple, dll_prefix: self.target.dll_prefix.clone(), dll_suffix: self.target.dll_suffix.clone(), - rejected_via_hash: self.rejected_via_hash, - rejected_via_triple: self.rejected_via_triple, - rejected_via_kind: self.rejected_via_kind, - rejected_via_version: self.rejected_via_version, - rejected_via_filename: self.rejected_via_filename, + crate_rejections: self.crate_rejections, }) } } @@ -806,12 +792,9 @@ fn find_plugin_registrar_impl<'a>( metadata_loader, name, None, // hash - None, // host_hash None, // extra_filename true, // is_host PathKind::Crate, - None, // root - None, // is_proc_macro ); match locator.maybe_load_library_crate()? { @@ -819,7 +802,7 @@ fn find_plugin_registrar_impl<'a>( Some(dylib) => Ok(dylib.0), None => Err(CrateError::NonDylibPlugin(name)), }, - None => Err(locator.into_error()), + None => Err(locator.into_error(None)), } } @@ -852,6 +835,15 @@ struct CrateMismatch { got: String, } +#[derive(Clone, Default)] +struct CrateRejections { + via_hash: Vec, + via_triple: Vec, + via_kind: Vec, + via_version: Vec, + via_filename: Vec, +} + /// Candidate rejection reasons collected during crate search. /// If no candidate is accepted, then these reasons are presented to the user, /// otherwise they are ignored. @@ -861,11 +853,7 @@ crate struct CombinedLocatorError { triple: TargetTriple, dll_prefix: String, dll_suffix: String, - rejected_via_hash: Vec, - rejected_via_triple: Vec, - rejected_via_kind: Vec, - rejected_via_version: Vec, - rejected_via_filename: Vec, + crate_rejections: CrateRejections, } crate enum CrateError { @@ -974,7 +962,7 @@ impl CrateError { Some(r) => format!(" which `{}` depends on", r.name), }; let mut msg = "the following crate versions were found:".to_string(); - let mut err = if !locator.rejected_via_hash.is_empty() { + let mut err = if !locator.crate_rejections.via_hash.is_empty() { let mut err = struct_span_err!( sess, span, @@ -984,7 +972,7 @@ impl CrateError { add, ); err.note("perhaps that crate needs to be recompiled?"); - let mismatches = locator.rejected_via_hash.iter(); + let mismatches = locator.crate_rejections.via_hash.iter(); for CrateMismatch { path, .. } in mismatches { msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display())); } @@ -995,7 +983,7 @@ impl CrateError { } err.note(&msg); err - } else if !locator.rejected_via_triple.is_empty() { + } else if !locator.crate_rejections.via_triple.is_empty() { let mut err = struct_span_err!( sess, span, @@ -1005,7 +993,7 @@ impl CrateError { locator.triple, add, ); - let mismatches = locator.rejected_via_triple.iter(); + let mismatches = locator.crate_rejections.via_triple.iter(); for CrateMismatch { path, got } in mismatches { msg.push_str(&format!( "\ncrate `{}`, target triple {}: {}", @@ -1016,7 +1004,7 @@ impl CrateError { } err.note(&msg); err - } else if !locator.rejected_via_kind.is_empty() { + } else if !locator.crate_rejections.via_kind.is_empty() { let mut err = struct_span_err!( sess, span, @@ -1026,13 +1014,13 @@ impl CrateError { add, ); err.help("please recompile that crate using --crate-type lib"); - let mismatches = locator.rejected_via_kind.iter(); + let mismatches = locator.crate_rejections.via_kind.iter(); for CrateMismatch { path, .. } in mismatches { msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display())); } err.note(&msg); err - } else if !locator.rejected_via_version.is_empty() { + } else if !locator.crate_rejections.via_version.is_empty() { let mut err = struct_span_err!( sess, span, @@ -1045,7 +1033,7 @@ impl CrateError { "please recompile that crate using this compiler ({})", rustc_version(), )); - let mismatches = locator.rejected_via_version.iter(); + let mismatches = locator.crate_rejections.via_version.iter(); for CrateMismatch { path, got } in mismatches { msg.push_str(&format!( "\ncrate `{}` compiled by {}: {}", @@ -1112,8 +1100,8 @@ impl CrateError { err }; - if !locator.rejected_via_filename.is_empty() { - let mismatches = locator.rejected_via_filename.iter(); + if !locator.crate_rejections.via_filename.is_empty() { + let mismatches = locator.crate_rejections.via_filename.iter(); for CrateMismatch { path, .. } in mismatches { err.note(&format!( "extern location for {} is of an unknown type: {}",