//! metadata::locator or metadata::creader for all the juicy details!
use crate::creader::Library;
-use crate::rmeta::{METADATA_HEADER, rustc_version, MetadataBlob};
+use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::MetadataRef;
use rustc::middle::cstore::{CrateSource, MetadataLoader};
-use rustc::session::{config, Session, CrateDisambiguator};
-use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
+use rustc::session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
use rustc::session::search_paths::PathKind;
-use rustc::util::nodemap::FxHashMap;
+use rustc::session::{config, CrateDisambiguator, Session};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::svh::Svh;
+use rustc_data_structures::sync::MetadataRef;
use errors::DiagnosticBuilder;
-use syntax::{span_err, span_fatal};
-use syntax::symbol::{Symbol, sym};
-use syntax::struct_span_err;
-use syntax_pos::Span;
+use rustc_span::symbol::{sym, Symbol};
+use rustc_span::Span;
use rustc_target::spec::{Target, TargetTriple};
+use syntax::struct_span_err;
+use syntax::{span_err, span_fatal};
use std::cmp;
use std::fmt;
metadata_loader,
crate_name,
exact_paths: if hash.is_none() {
- sess.opts.externs.get(&crate_name.as_str()).into_iter()
+ sess.opts
+ .externs
+ .get(&crate_name.as_str())
+ .into_iter()
.filter_map(|entry| entry.files())
.flatten()
- .map(|location| PathBuf::from(location)).collect()
+ .map(|location| PathBuf::from(location))
+ .collect()
} else {
// SVH being specified means this is a transitive dependency,
// so `--extern` options do not apply.
}
let mut seen_paths = FxHashSet::default();
match self.extra_filename {
- Some(s) => self.find_library_crate(s, &mut seen_paths)
+ 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)
+ None => self.find_library_crate("", &mut seen_paths),
}
}
};
let mut msg = "the following crate versions were found:".to_string();
let mut err = if !self.rejected_via_hash.is_empty() {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0460,
- "found possibly newer version of crate `{}`{}",
- self.crate_name,
- add);
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0460,
+ "found possibly newer version of crate `{}`{}",
+ self.crate_name,
+ add
+ );
err.note("perhaps that crate needs to be recompiled?");
let mismatches = self.rejected_via_hash.iter();
for &CrateMismatch { ref path, .. } in mismatches {
err.note(&msg);
err
} else if !self.rejected_via_triple.is_empty() {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0461,
- "couldn't find crate `{}` \
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0461,
+ "couldn't find crate `{}` \
with expected target triple {}{}",
- self.crate_name,
- self.triple,
- add);
+ self.crate_name,
+ self.triple,
+ add
+ );
let mismatches = self.rejected_via_triple.iter();
for &CrateMismatch { ref path, ref got } in mismatches {
- msg.push_str(&format!("\ncrate `{}`, target triple {}: {}",
- self.crate_name,
- got,
- path.display()));
+ msg.push_str(&format!(
+ "\ncrate `{}`, target triple {}: {}",
+ self.crate_name,
+ got,
+ path.display()
+ ));
}
err.note(&msg);
err
} else if !self.rejected_via_kind.is_empty() {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0462,
- "found staticlib `{}` instead of rlib or dylib{}",
- self.crate_name,
- add);
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0462,
+ "found staticlib `{}` instead of rlib or dylib{}",
+ self.crate_name,
+ add
+ );
err.help("please recompile that crate using --crate-type lib");
let mismatches = self.rejected_via_kind.iter();
for &CrateMismatch { ref path, .. } in mismatches {
err.note(&msg);
err
} else if !self.rejected_via_version.is_empty() {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0514,
- "found crate `{}` compiled by an incompatible version \
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0514,
+ "found crate `{}` compiled by an incompatible version \
of rustc{}",
- self.crate_name,
- add);
- err.help(&format!("please recompile that crate using this compiler ({})",
- rustc_version()));
+ self.crate_name,
+ add
+ );
+ err.help(&format!(
+ "please recompile that crate using this compiler ({})",
+ rustc_version()
+ ));
let mismatches = self.rejected_via_version.iter();
for &CrateMismatch { ref path, ref got } in mismatches {
- msg.push_str(&format!("\ncrate `{}` compiled by {}: {}",
- self.crate_name,
- got,
- path.display()));
+ msg.push_str(&format!(
+ "\ncrate `{}` compiled by {}: {}",
+ self.crate_name,
+ got,
+ path.display()
+ ));
}
err.note(&msg);
err
} else {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0463,
- "can't find crate for `{}`{}",
- self.crate_name,
- add);
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0463,
+ "can't find crate for `{}`{}",
+ self.crate_name,
+ add
+ );
if (self.crate_name == sym::std || self.crate_name == sym::core)
- && self.triple != TargetTriple::from_triple(config::host_triple()) {
+ && self.triple != TargetTriple::from_triple(config::host_triple())
+ {
err.note(&format!("the `{}` target may not be installed", self.triple));
}
err.span_label(self.span, "can't find crate");
let dylibname = self.dylibname();
let mismatches = self.rejected_via_filename.iter();
for &CrateMismatch { ref path, .. } in mismatches {
- err.note(&format!("extern location for {} is of an unknown type: {}",
- self.crate_name,
- path.display()))
- .help(&format!("file name should be lib*.rlib or {}*.{}",
- dylibname.0,
- dylibname.1));
+ err.note(&format!(
+ "extern location for {} is of an unknown type: {}",
+ self.crate_name,
+ path.display()
+ ))
+ .help(&format!(
+ "file name should be lib*.rlib or {}*.{}",
+ dylibname.0, dylibname.1
+ ));
}
}
unreachable!();
}
- fn find_library_crate(&mut self,
- extra_prefix: &str,
- seen_paths: &mut FxHashSet<PathBuf>)
- -> Option<Library> {
+ fn find_library_crate(
+ &mut self,
+ extra_prefix: &str,
+ seen_paths: &mut FxHashSet<PathBuf>,
+ ) -> Option<Library> {
let dypair = self.dylibname();
let staticpair = self.staticlibname();
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<
- _,
- (FxHashMap<_, _>, FxHashMap<_, _>, FxHashMap<_, _>),
- > = Default::default();
+ let mut candidates: FxHashMap<_, (FxHashMap<_, _>, FxHashMap<_, _>, FxHashMap<_, _>)> =
+ Default::default();
let mut staticlibs = vec![];
// First, find all possible candidate rlibs and dylibs purely based on
None => return FileDoesntMatch,
Some(file) => file,
};
- let (hash, found_kind) =
- if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") {
- (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
- } else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") {
- (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
- } else if file.starts_with(&dylib_prefix) &&
- file.ends_with(&dypair.1) {
- (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
- } else {
- if file.starts_with(&staticlib_prefix) && file.ends_with(&staticpair.1) {
- staticlibs.push(CrateMismatch {
- path: path.to_path_buf(),
- got: "static".to_string(),
- });
- }
- return FileDoesntMatch;
- };
+ let (hash, found_kind) = if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") {
+ (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
+ } else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") {
+ (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
+ } else if file.starts_with(&dylib_prefix) && file.ends_with(&dypair.1) {
+ (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
+ } else {
+ if file.starts_with(&staticlib_prefix) && file.ends_with(&staticpair.1) {
+ staticlibs.push(CrateMismatch {
+ path: path.to_path_buf(),
+ got: "static".to_string(),
+ });
+ }
+ return FileDoesntMatch;
+ };
info!("lib candidate: {}", path.display());
fs::canonicalize(path)
.map(|p| {
if seen_paths.contains(&p) {
- return FileDoesntMatch
+ return FileDoesntMatch;
};
seen_paths.insert(p.clone());
match found_kind {
- CrateFlavor::Rlib => { rlibs.insert(p, kind); }
- CrateFlavor::Rmeta => { rmetas.insert(p, kind); }
- CrateFlavor::Dylib => { dylibs.insert(p, kind); }
+ CrateFlavor::Rlib => {
+ rlibs.insert(p, kind);
+ }
+ CrateFlavor::Rmeta => {
+ rmetas.insert(p, kind);
+ }
+ CrateFlavor::Dylib => {
+ dylibs.insert(p, kind);
+ }
}
FileMatches
})
0 => None,
1 => Some(libraries.into_iter().next().unwrap().1),
_ => {
- let mut err = struct_span_err!(self.sess,
- self.span,
- E0464,
- "multiple matching crates for `{}`",
- self.crate_name);
- let candidates = libraries.iter().filter_map(|(_, lib)| {
- let crate_name = &lib.metadata.get_root().name().as_str();
- match &(&lib.source.dylib, &lib.source.rlib) {
- &(&Some((ref pd, _)), &Some((ref pr, _))) => {
- Some(format!("\ncrate `{}`: {}\n{:>padding$}",
- crate_name,
- pd.display(),
- pr.display(),
- padding=8 + crate_name.len()))
+ let mut err = struct_span_err!(
+ self.sess,
+ self.span,
+ E0464,
+ "multiple matching crates for `{}`",
+ self.crate_name
+ );
+ let candidates = libraries
+ .iter()
+ .filter_map(|(_, lib)| {
+ let crate_name = &lib.metadata.get_root().name().as_str();
+ match &(&lib.source.dylib, &lib.source.rlib) {
+ &(&Some((ref pd, _)), &Some((ref pr, _))) => Some(format!(
+ "\ncrate `{}`: {}\n{:>padding$}",
+ crate_name,
+ pd.display(),
+ pr.display(),
+ padding = 8 + crate_name.len()
+ )),
+ &(&Some((ref p, _)), &None) | &(&None, &Some((ref p, _))) => {
+ Some(format!("\ncrate `{}`: {}", crate_name, p.display()))
+ }
+ &(&None, &None) => None,
}
- &(&Some((ref p, _)), &None) | &(&None, &Some((ref p, _))) => {
- Some(format!("\ncrate `{}`: {}", crate_name, p.display()))
- }
- &(&None, &None) => None,
- }
- }).collect::<String>();
+ })
+ .collect::<String>();
err.note(&format!("candidates:{}", candidates));
err.emit();
None
// read the metadata from it if `*slot` is `None`. If the metadata couldn't
// be read, it is assumed that the file isn't a valid rust library (no
// errors are emitted).
- fn extract_one(&mut self,
- m: FxHashMap<PathBuf, PathKind>,
- flavor: CrateFlavor,
- slot: &mut Option<(Svh, MetadataBlob)>)
- -> Option<(PathBuf, PathKind)> {
+ fn extract_one(
+ &mut self,
+ m: FxHashMap<PathBuf, PathKind>,
+ flavor: CrateFlavor,
+ slot: &mut Option<(Svh, MetadataBlob)>,
+ ) -> Option<(PathBuf, PathKind)> {
let mut ret: Option<(PathBuf, PathKind)> = None;
let mut error = 0;
};
// If we see multiple hashes, emit an error about duplicate candidates.
if slot.as_ref().map_or(false, |s| s.0 != hash) {
- let mut e = struct_span_err!(self.sess,
- self.span,
- E0465,
- "multiple {} candidates for `{}` found",
- flavor,
- self.crate_name);
- e.span_note(self.span,
- &format!(r"candidate #1: {}",
- ret.as_ref()
- .unwrap()
- .0
- .display()));
+ let mut e = struct_span_err!(
+ self.sess,
+ self.span,
+ E0465,
+ "multiple {} candidates for `{}` found",
+ flavor,
+ self.crate_name
+ );
+ e.span_note(
+ self.span,
+ &format!(r"candidate #1: {}", ret.as_ref().unwrap().0.display()),
+ );
if let Some(ref mut e) = err {
e.emit();
}
}
if error > 0 {
error += 1;
- err.as_mut().unwrap().span_note(self.span,
- &format!(r"candidate #{}: {}",
- error,
- lib.display()));
+ err.as_mut()
+ .unwrap()
+ .span_note(self.span, &format!(r"candidate #{}: {}", error, lib.display()));
continue;
}
// as well.
if let Some((ref prev, _)) = ret {
let sysroot = &self.sess.sysroot;
- let sysroot = sysroot.canonicalize()
- .unwrap_or_else(|_| sysroot.to_path_buf());
+ let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf());
if prev.starts_with(&sysroot) {
- continue
+ continue;
}
}
*slot = Some((hash, metadata));
let rustc_version = rustc_version();
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.push(CrateMismatch {
- path: libpath.to_path_buf(),
- got: found_version,
- });
+ info!("Rejecting via version: expected {} got {}", rustc_version, found_version);
+ self.rejected_via_version
+ .push(CrateMismatch { path: libpath.to_path_buf(), got: found_version });
return None;
}
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);
+ info!(
+ "Rejecting via proc macro: expected {} got {}",
+ expected_is_proc_macro, is_proc_macro
+ );
return None;
}
}
}
if root.triple() != &self.triple {
- info!("Rejecting via crate triple: expected {} got {}",
- self.triple,
- root.triple());
+ info!("Rejecting via crate triple: expected {} got {}", self.triple, root.triple());
self.rejected_via_triple.push(CrateMismatch {
path: libpath.to_path_buf(),
got: root.triple().to_string(),
if let Some(expected_hash) = self.hash {
if hash != expected_hash {
info!("Rejecting via hash: expected {} got {}", expected_hash, hash);
- self.rejected_via_hash.push(CrateMismatch {
- path: libpath.to_path_buf(),
- got: hash.to_string(),
- });
+ self.rejected_via_hash
+ .push(CrateMismatch { path: libpath.to_path_buf(), got: hash.to_string() });
return None;
}
}
Some(hash)
}
-
// Returns the corresponding (prefix, suffix) that files need to have for
// dynamic libraries
fn dylibname(&self) -> (String, String) {
let mut rmetas = FxHashMap::default();
let mut dylibs = FxHashMap::default();
{
- let crate_name = self.crate_name;
- let rejected_via_filename = &mut self.rejected_via_filename;
- let locs = self.exact_paths.iter().filter(|loc| {
+ let crate_name = self.crate_name;
+ let rejected_via_filename = &mut self.rejected_via_filename;
+ let locs = self.exact_paths.iter().filter(|loc| {
if !loc.exists() {
- sess.err(&format!("extern location for {} does not exist: {}",
- crate_name,
- loc.display()));
+ sess.err(&format!(
+ "extern location for {} does not exist: {}",
+ crate_name,
+ loc.display()
+ ));
return false;
}
let file = match loc.file_name().and_then(|s| s.to_str()) {
Some(file) => file,
None => {
- sess.err(&format!("extern location for {} is not a file: {}",
- crate_name,
- loc.display()));
+ sess.err(&format!(
+ "extern location for {} is not a file: {}",
+ crate_name,
+ loc.display()
+ ));
return false;
}
};
- if file.starts_with("lib") &&
- (file.ends_with(".rlib") || file.ends_with(".rmeta")) {
+ if file.starts_with("lib") && (file.ends_with(".rlib") || file.ends_with(".rmeta"))
+ {
return true;
} else {
let (ref prefix, ref suffix) = dylibname;
}
}
- rejected_via_filename.push(CrateMismatch {
- path: (*loc).clone(),
- got: String::new(),
- });
+ rejected_via_filename
+ .push(CrateMismatch { path: (*loc).clone(), got: String::new() });
false
});
}
// Just a small wrapper to time how long reading metadata takes.
-fn get_metadata_section(target: &Target,
- flavor: CrateFlavor,
- filename: &Path,
- loader: &dyn MetadataLoader)
- -> Result<MetadataBlob, String> {
+fn get_metadata_section(
+ target: &Target,
+ flavor: CrateFlavor,
+ filename: &Path,
+ loader: &dyn MetadataLoader,
+) -> Result<MetadataBlob, String> {
let start = Instant::now();
let ret = get_metadata_section_imp(target, flavor, filename, loader);
- info!("reading {:?} => {:?}",
- filename.file_name().unwrap(),
- start.elapsed());
+ info!("reading {:?} => {:?}", filename.file_name().unwrap(), start.elapsed());
return ret;
}
unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {}
-fn get_metadata_section_imp(target: &Target,
- flavor: CrateFlavor,
- filename: &Path,
- loader: &dyn MetadataLoader)
- -> Result<MetadataBlob, String> {
+fn get_metadata_section_imp(
+ target: &Target,
+ flavor: CrateFlavor,
+ filename: &Path,
+ loader: &dyn MetadataLoader,
+) -> Result<MetadataBlob, String> {
if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display()));
}
debug!("checking {} bytes of metadata-version stamp", header_len);
let header = &buf[..cmp::min(header_len, buf.len())];
if header != METADATA_HEADER {
- return Err(format!("incompatible metadata version found: '{}'",
- filename.display()));
+ return Err(format!(
+ "incompatible metadata version found: '{}'",
+ filename.display()
+ ));
}
// Header is okay -> inflate the actual metadata
debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
let mut inflated = Vec::new();
match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
- Ok(_) => {
- rustc_erase_owner!(OwningRef::new(inflated).map_owner_box())
- }
+ Ok(_) => rustc_erase_owner!(OwningRef::new(inflated).map_owner_box()),
Err(_) => {
return Err(format!("failed to decompress metadata: {}", filename.display()));
}
}
CrateFlavor::Rmeta => {
// mmap the file, because only a small fraction of it is read.
- let file = std::fs::File::open(filename).map_err(|_|
- format!("failed to open rmeta metadata: '{}'", filename.display()))?;
+ let file = std::fs::File::open(filename)
+ .map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?;
let mmap = unsafe { memmap::Mmap::map(&file) };
- let mmap = mmap.map_err(|_|
- format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
+ let mmap = mmap
+ .map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box())
}
let library = locator.maybe_load_library_crate().or_else(|| {
if !is_cross {
- return None
+ return None;
}
// Try loading from target crates. This will abort later if we
// try to load a plugin registrar function,
if target_only {
// Need to abort before syntax expansion.
- let message = format!("plugin `{}` is not available for triple `{}` \
+ let message = format!(
+ "plugin `{}` is not available for triple `{}` \
(only found {})",
- name,
- config::host_triple(),
- sess.opts.target_triple);
+ name,
+ config::host_triple(),
+ sess.opts.target_triple
+ );
span_fatal!(sess, span, E0456, "{}", &message);
}
match library.source.dylib {
- Some(dylib) => {
- Some((dylib.0, library.metadata.get_root().disambiguator()))
- }
+ Some(dylib) => Some((dylib.0, library.metadata.get_root().disambiguator())),
None => {
- span_err!(sess, span, E0457,
- "plugin `{}` only found in rlib format, but must be available \
+ span_err!(
+ sess,
+ span,
+ E0457,
+ "plugin `{}` only found in rlib format, but must be available \
in dylib format",
- name);
+ name
+ );
// No need to abort because the loading code will just ignore this
// empty dylib.
None
}
/// A diagnostic function for dumping crate metadata to an output stream.
-pub fn list_file_metadata(target: &Target,
- path: &Path,
- metadata_loader: &dyn MetadataLoader,
- out: &mut dyn io::Write)
- -> io::Result<()> {
+pub fn list_file_metadata(
+ target: &Target,
+ path: &Path,
+ metadata_loader: &dyn MetadataLoader,
+ out: &mut dyn io::Write,
+) -> io::Result<()> {
let filename = path.file_name().unwrap().to_str().unwrap();
let flavor = if filename.ends_with(".rlib") {
CrateFlavor::Rlib