diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 617a8654eed..60478f3543f 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -298,9 +298,9 @@ impl<'a> Context<'a> { let lib = m.move_iter().next().unwrap(); if slot.is_none() { - info!("{} reading meatadata from: {}", flavor, lib.display()); + info!("{} reading metadata from: {}", flavor, lib.display()); match get_metadata_section(self.os, &lib) { - Some(blob) => { + Ok(blob) => { if self.crate_matches(blob.as_slice()) { *slot = Some(blob); } else { @@ -308,7 +308,7 @@ impl<'a> Context<'a> { return None; } } - None => { + Err(_) => { info!("no metadata found"); return None } @@ -387,7 +387,7 @@ impl ArchiveMetadata { } // Just a small wrapper to time how long reading metadata takes. -fn get_metadata_section(os: Os, filename: &Path) -> Option { +fn get_metadata_section(os: Os, filename: &Path) -> Result { let start = time::precise_time_ns(); let ret = get_metadata_section_imp(os, filename); info!("reading {} => {}ms", filename.filename_display(), @@ -395,7 +395,10 @@ fn get_metadata_section(os: Os, filename: &Path) -> Option { return ret; } -fn get_metadata_section_imp(os: Os, filename: &Path) -> Option { +fn get_metadata_section_imp(os: Os, filename: &Path) -> Result { + if !filename.exists() { + return Err(format!("no such file: '{}'", filename.display())); + } if filename.filename_str().unwrap().ends_with(".rlib") { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by @@ -404,19 +407,26 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option { Some(ar) => ar, None => { debug!("llvm didn't like `{}`", filename.display()); - return None; + return Err(format!("failed to read rlib metadata: '{}'", + filename.display())); } }; - return ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)); + return match ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)) { + None => return Err(format!("failed to read rlib metadata: '{}'", + filename.display())), + Some(blob) => return Ok(blob) + } } unsafe { let mb = filename.with_c_str(|buf| { llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) }); - if mb as int == 0 { return None } + if mb as int == 0 { + return Err(format!("error reading library: '{}'",filename.display())) + } let of = match ObjectFile::new(mb) { Some(of) => of, - _ => return None + _ => return Err(format!("provided path not an object file: '{}'", filename.display())) }; let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { @@ -426,7 +436,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option { if read_meta_section_name(os) == name { let cbuf = llvm::LLVMGetSectionContents(si.llsi); let csz = llvm::LLVMGetSectionSize(si.llsi) as uint; - let mut found = None; + let mut found = Err(format!("metadata not found: '{}'", filename.display())); let cvbuf: *u8 = cast::transmute(cbuf); let vlen = encoder::metadata_encoding_version.len(); debug!("checking {} bytes of metadata-version stamp", @@ -434,22 +444,23 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option { let minsz = cmp::min(vlen, csz); let version_ok = vec::raw::buf_as_slice(cvbuf, minsz, |buf0| buf0 == encoder::metadata_encoding_version); - if !version_ok { return None; } + if !version_ok { return Err(format!("incompatible metadata version found: '{}'", + filename.display()));} let cvbuf1 = cvbuf.offset(vlen as int); debug!("inflating {} bytes of compressed metadata", csz - vlen); vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| { let inflated = flate::inflate_bytes(bytes); - found = Some(MetadataVec(inflated)); + found = Ok(MetadataVec(inflated)); }); - if found.is_some() { + if found.is_ok() { return found; } } llvm::LLVMMoveToNextSection(si.llsi); } - return None; + return Err(format!("metadata not found: '{}'", filename.display())); } } @@ -477,9 +488,9 @@ pub fn read_meta_section_name(os: Os) -> &'static str { pub fn list_file_metadata(os: Os, path: &Path, out: &mut io::Writer) -> io::IoResult<()> { match get_metadata_section(os, path) { - Some(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), - None => { - write!(out, "could not find metadata in {}.\n", path.display()) + Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), + Err(msg) => { + write!(out, "{}\n", msg) } } }