From 37bf97a0f9cc764a19dfcff21d62384b2445dcbc Mon Sep 17 00:00:00 2001 From: gentlefolk Date: Sun, 9 Feb 2014 22:29:21 -0500 Subject: [PATCH] Updated metadata::creader::resolve_crate_deps to use the correct span. Clarified error message when an external crate's dependency is missing. Closes #2404. --- src/librustc/metadata/creader.rs | 29 ++++++++++++++----- src/librustc/metadata/loader.rs | 12 +++++--- .../missing-crate-dependency/Makefile | 9 ++++++ .../missing-crate-dependency/crateA.rs | 12 ++++++++ .../missing-crate-dependency/crateB.rs | 11 +++++++ .../missing-crate-dependency/crateC.rs | 13 +++++++++ 6 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 src/test/run-make/missing-crate-dependency/Makefile create mode 100644 src/test/run-make/missing-crate-dependency/crateA.rs create mode 100644 src/test/run-make/missing-crate-dependency/crateB.rs create mode 100644 src/test/run-make/missing-crate-dependency/crateC.rs diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 901e8982c83d2..df250937a57c2 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -24,7 +24,7 @@ use syntax::ast; use syntax::abi; use syntax::attr; use syntax::attr::AttrMetaMethods; -use syntax::codemap::{Span, DUMMY_SP}; +use syntax::codemap::{Span}; use syntax::diagnostic::SpanHandler; use syntax::ext::base::{CrateLoader, MacroCrate}; use syntax::parse::token::{IdentInterner, InternedString}; @@ -147,6 +147,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) { match extract_crate_info(i) { Some(info) => { let cnum = resolve_crate(e, + None, info.ident.clone(), info.name.clone(), info.version.clone(), @@ -299,6 +300,7 @@ fn existing_match(e: &Env, name: &str, version: &str, hash: &str) -> Option, ident: ~str, name: ~str, version: ~str, @@ -319,7 +321,7 @@ fn resolve_crate(e: &mut Env, }; let loader::Library { dylib, rlib, metadata - } = load_ctxt.load_library_crate(); + } = load_ctxt.load_library_crate(root_ident.clone()); let attrs = decoder::get_crate_attributes(metadata.as_slice()); let crateid = attr::find_crateid(attrs).unwrap(); @@ -338,8 +340,17 @@ fn resolve_crate(e: &mut Env, } e.next_crate_num += 1; + // Maintain a reference to the top most crate. + let root_crate = match root_ident { + Some(c) => c, + None => load_ctxt.ident.clone() + }; + // Now resolve the crates referenced by this crate - let cnum_map = resolve_crate_deps(e, metadata.as_slice()); + let cnum_map = resolve_crate_deps(e, + Some(root_crate), + metadata.as_slice(), + span); let cmeta = @cstore::crate_metadata { name: load_ctxt.name, @@ -364,7 +375,10 @@ fn resolve_crate(e: &mut Env, } // Go through the crate metadata and load any crates that it references -fn resolve_crate_deps(e: &mut Env, cdata: &[u8]) -> cstore::cnum_map { +fn resolve_crate_deps(e: &mut Env, + root_ident: Option<~str>, + cdata: &[u8], span : Span) + -> cstore::cnum_map { debug!("resolving deps of external crate"); // The map from crate numbers in the crate we're resolving to local crate // numbers @@ -387,15 +401,13 @@ fn resolve_crate_deps(e: &mut Env, cdata: &[u8]) -> cstore::cnum_map { None => { debug!("need to load it"); // This is a new one so we've got to load it - // FIXME (#2404): Need better error reporting than just a bogus - // span. - let fake_span = DUMMY_SP; let local_cnum = resolve_crate(e, + root_ident.clone(), cname_str.get().to_str(), cname_str.get().to_str(), dep.vers.clone(), dep.hash.clone(), - fake_span); + span); cnum_map.insert(extrn_cnum, local_cnum); } } @@ -427,6 +439,7 @@ impl CrateLoader for Loader { fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate { let info = extract_crate_info(krate).unwrap(); let cnum = resolve_crate(&mut self.env, + None, info.ident.clone(), info.name.clone(), info.version.clone(), diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 8a7964fcf6b53..5539347949a6c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -65,13 +65,17 @@ pub struct ArchiveMetadata { } impl Context { - pub fn load_library_crate(&self) -> Library { + pub fn load_library_crate(&self, root_ident: Option<~str>) -> Library { match self.find_library_crate() { Some(t) => t, None => { - self.sess.span_fatal(self.span, - format!("can't find crate for `{}`", - self.ident)); + let message = match root_ident { + None => format!("can't find crate for `{}`", self.ident), + Some(c) => format!("can't find crate for `{}` which `{}` depends on", + self.ident, + c) + }; + self.sess.span_fatal(self.span, message); } } } diff --git a/src/test/run-make/missing-crate-dependency/Makefile b/src/test/run-make/missing-crate-dependency/Makefile new file mode 100644 index 0000000000000..a470ee0a7c1bb --- /dev/null +++ b/src/test/run-make/missing-crate-dependency/Makefile @@ -0,0 +1,9 @@ +-include ../tools.mk + +all: + $(RUSTC) --crate-type=rlib crateA.rs + $(RUSTC) --crate-type=rlib crateB.rs + rm $(TMPDIR)/$(call RLIB_GLOB,crateA) + # Ensure crateC fails to compile since dependency crateA is missing + $(RUSTC) crateC.rs 2>&1 | \ + grep "error: can't find crate for \`crateA\` which \`crateB\` depends on" diff --git a/src/test/run-make/missing-crate-dependency/crateA.rs b/src/test/run-make/missing-crate-dependency/crateA.rs new file mode 100644 index 0000000000000..4e111f29e8afa --- /dev/null +++ b/src/test/run-make/missing-crate-dependency/crateA.rs @@ -0,0 +1,12 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Base crate +pub fn func() {} diff --git a/src/test/run-make/missing-crate-dependency/crateB.rs b/src/test/run-make/missing-crate-dependency/crateB.rs new file mode 100644 index 0000000000000..bf55017c6463f --- /dev/null +++ b/src/test/run-make/missing-crate-dependency/crateB.rs @@ -0,0 +1,11 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate crateA; diff --git a/src/test/run-make/missing-crate-dependency/crateC.rs b/src/test/run-make/missing-crate-dependency/crateC.rs new file mode 100644 index 0000000000000..174d9382b76be --- /dev/null +++ b/src/test/run-make/missing-crate-dependency/crateC.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate crateB; + +fn main() {}