Skip to content

Commit 5c718e6

Browse files
committed
Properly handle transitive dependencies
1 parent b10cb26 commit 5c718e6

File tree

4 files changed

+54
-22
lines changed

4 files changed

+54
-22
lines changed

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub struct ResolverOutputs {
138138
pub extern_prelude: FxHashMap<Name, bool>,
139139
/// All crates that ended up getting loaded.
140140
/// Used to determine which `--extern` entries are unused
141-
pub used_crates: FxHashSet<Symbol>,
141+
pub used_crates: Option<FxHashSet<Symbol>>,
142142
}
143143

144144
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]

src/librustc_interface/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ pub fn create_global_ctxt<'tcx>(
738738
}
739739

740740
let extern_prelude = resolver_outputs.extern_prelude.clone();
741-
let used_crates = resolver_outputs.used_crates.clone();
741+
let used_crates = resolver_outputs.used_crates.as_ref().unwrap().clone();
742742

743743
let gcx = sess.time("setup_global_ctxt", || {
744744
global_ctxt.init_locking(|| {

src/librustc_metadata/creader.rs

+39-12
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,23 @@ impl<'a> CrateLoader<'a> {
436436
fn resolve_crate<'b>(
437437
&'b mut self,
438438
name: Symbol,
439+
orig_name: Option<Symbol>,
440+
transitive: bool,
439441
span: Span,
440442
dep_kind: DepKind,
441443
dep: Option<(&'b CratePaths, &'b CrateDep)>,
442444
) -> CrateNum {
443-
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
445+
self.maybe_resolve_crate(name, orig_name, transitive, span, dep_kind, dep)
446+
.unwrap_or_else(|err| err.report())
444447
}
445448

446449
fn maybe_resolve_crate<'b>(
447450
&'b mut self,
448451
name: Symbol,
452+
orig_name: Option<Symbol>,
453+
// Whether this is a direct dependency of the current compilation session,
454+
// or a transitive dependency
455+
transitive: bool,
449456
span: Span,
450457
mut dep_kind: DepKind,
451458
dep: Option<(&'b CratePaths, &'b CrateDep)>,
@@ -479,15 +486,33 @@ impl<'a> CrateLoader<'a> {
479486
Some(false), // is_proc_macro
480487
);
481488

482-
self.load(&mut locator)
489+
let res = self
490+
.load(&mut locator)
483491
.map(|r| (r, None))
484492
.or_else(|| {
485493
dep_kind = DepKind::MacrosOnly;
486494
self.load_proc_macro(&mut locator, path_kind)
487495
})
488-
.ok_or_else(move || LoadError::LocatorError(locator))?
496+
.ok_or_else(move || LoadError::LocatorError(locator))?;
497+
498+
res
489499
};
490500

501+
// Loading a transitive dependency doesn't mark that dependency as used
502+
// Note that we need to perform this check even when the crate was already loaded
503+
// (e.g. `existing_match` finds the crate), since the crate may have been
504+
// initially loaded as a transitive dependency
505+
if !transitive {
506+
self.loaded_crates.as_mut().unwrap().insert(name);
507+
// If this crate was renamed via `extern crate foo as bar`,
508+
// mark both names as loaded. An `extern crate` always forces
509+
// the crate to be loaded, so we don't want the UNUSED_EXTERN_OPTION lint
510+
// will never fire (though the UNUSED_EXTERN_CRATES lint might still fire)
511+
if let Some(orig_name) = orig_name {
512+
self.loaded_crates.as_mut().unwrap().insert(orig_name);
513+
}
514+
}
515+
491516
match result {
492517
(LoadResult::Previous(cnum), None) => {
493518
let data = self.cstore.get_crate_data(cnum);
@@ -498,7 +523,6 @@ impl<'a> CrateLoader<'a> {
498523
Ok(cnum)
499524
}
500525
(LoadResult::Loaded(library), host_library) => {
501-
self.loaded_crates.as_mut().unwrap().insert(name);
502526
Ok(self.register_crate(host_library, root, span, library, dep_kind, name))
503527
}
504528
_ => panic!(),
@@ -571,7 +595,7 @@ impl<'a> CrateLoader<'a> {
571595
DepKind::MacrosOnly => DepKind::MacrosOnly,
572596
_ => dep.kind,
573597
};
574-
self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep)))
598+
self.resolve_crate(dep.name, None, true, span, dep_kind, Some((root, &dep)))
575599
}))
576600
.collect()
577601
}
@@ -666,7 +690,7 @@ impl<'a> CrateLoader<'a> {
666690
};
667691
info!("panic runtime not found -- loading {}", name);
668692

669-
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
693+
let cnum = self.resolve_crate(name, None, false, DUMMY_SP, DepKind::Implicit, None);
670694
let data = self.cstore.get_crate_data(cnum);
671695

672696
// Sanity check the loaded crate to ensure it is indeed a panic runtime
@@ -692,7 +716,7 @@ impl<'a> CrateLoader<'a> {
692716
info!("loading profiler");
693717

694718
let name = Symbol::intern("profiler_builtins");
695-
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
719+
let cnum = self.resolve_crate(name, None, false, DUMMY_SP, DepKind::Implicit, None);
696720
let data = self.cstore.get_crate_data(cnum);
697721

698722
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
@@ -834,15 +858,18 @@ impl<'a> CrateLoader<'a> {
834858
});
835859
}
836860

837-
pub fn postprocess(&mut self, krate: &ast::Crate) -> FxHashSet<Symbol> {
861+
pub fn take_loaded_crates(&mut self) -> FxHashSet<Symbol> {
862+
self.loaded_crates.take().unwrap()
863+
}
864+
865+
pub fn postprocess(&mut self, krate: &ast::Crate) {
838866
self.inject_profiler_runtime();
839867
self.inject_allocator_crate(krate);
840868
self.inject_panic_runtime(krate);
841869

842870
if log_enabled!(log::Level::Info) {
843871
dump_crates(&self.cstore);
844872
}
845-
self.loaded_crates.take().unwrap()
846873
}
847874

848875
pub fn process_extern_crate(
@@ -873,7 +900,7 @@ impl<'a> CrateLoader<'a> {
873900
DepKind::Explicit
874901
};
875902

876-
let cnum = self.resolve_crate(name, item.span, dep_kind, None);
903+
let cnum = self.resolve_crate(name, orig_name, false, item.span, dep_kind, None);
877904

878905
let def_id = definitions.opt_local_def_id(item.id).unwrap();
879906
let path_len = definitions.def_path(def_id.index).data.len();
@@ -893,7 +920,7 @@ impl<'a> CrateLoader<'a> {
893920
}
894921

895922
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
896-
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None);
923+
let cnum = self.resolve_crate(name, None, false, span, DepKind::Explicit, None);
897924

898925
self.update_extern_crate(
899926
cnum,
@@ -910,6 +937,6 @@ impl<'a> CrateLoader<'a> {
910937
}
911938

912939
pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
913-
self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()
940+
self.maybe_resolve_crate(name, None, false, span, DepKind::Explicit, None).ok()
914941
}
915942
}

src/librustc_resolve/lib.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use rustc_session::Session;
4747
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
4848
use rustc_span::source_map::Spanned;
4949
use rustc_span::symbol::{kw, sym};
50-
use rustc_span::{Span, Symbol, DUMMY_SP};
50+
use rustc_span::{Span, DUMMY_SP};
5151

5252
use log::debug;
5353
use std::cell::{Cell, RefCell};
@@ -962,8 +962,6 @@ pub struct Resolver<'a> {
962962
lint_buffer: LintBuffer,
963963

964964
next_node_id: NodeId,
965-
966-
used_crates: FxHashSet<Symbol>,
967965
}
968966

969967
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1241,7 +1239,6 @@ impl<'a> Resolver<'a> {
12411239
variant_vis: Default::default(),
12421240
lint_buffer: LintBuffer::default(),
12431241
next_node_id: NodeId::from_u32(1),
1244-
used_crates: Default::default(),
12451242
}
12461243
}
12471244

@@ -1263,7 +1260,8 @@ impl<'a> Resolver<'a> {
12631260
Default::default()
12641261
}
12651262

1266-
pub fn into_outputs(self) -> ResolverOutputs {
1263+
pub fn into_outputs(mut self) -> ResolverOutputs {
1264+
let used_crates = self.crate_loader.take_loaded_crates();
12671265
ResolverOutputs {
12681266
definitions: self.definitions,
12691267
cstore: Box::new(self.crate_loader.into_cstore()),
@@ -1278,7 +1276,8 @@ impl<'a> Resolver<'a> {
12781276
.iter()
12791277
.map(|(ident, entry)| (ident.name, entry.introduced_by_item))
12801278
.collect(),
1281-
used_crates: self.used_crates,
1279+
// The used crates are finalized at this point
1280+
used_crates: Some(used_crates),
12821281
}
12831282
}
12841283

@@ -1297,7 +1296,13 @@ impl<'a> Resolver<'a> {
12971296
.iter()
12981297
.map(|(ident, entry)| (ident.name, entry.introduced_by_item))
12991298
.collect(),
1300-
used_crates: self.used_crates.clone(),
1299+
// The used crates are not finalized at this point - lowering the AST
1300+
// may cause us to call `Resolver.extern_prelude_get`,
1301+
// which may update the set of used crates even if a
1302+
// new crate is not loaded from disk
1303+
// We should never actually need to access this, but we set it to
1304+
// `None` so that we get an ICE if we try to unwrap it
1305+
used_crates: None,
13011306
}
13021307
}
13031308

@@ -1348,7 +1353,7 @@ impl<'a> Resolver<'a> {
13481353

13491354
self.check_unused(krate);
13501355
self.report_errors(krate);
1351-
self.used_crates = self.crate_loader.postprocess(krate);
1356+
self.crate_loader.postprocess(krate);
13521357
}
13531358

13541359
fn new_module(

0 commit comments

Comments
 (0)