Skip to content

Commit 042fba1

Browse files
committed
Track where crate dependencies come from in creader
Introduce an enum that represents the different possible sources for dependencies, and use them where possible. This will enable more fine grained control and provides better context than passing the `dep_root` tuple. Use this to ensure that injected crates always show up as private by default.
1 parent ae5de6c commit 042fba1

File tree

1 file changed

+81
-20
lines changed

1 file changed

+81
-20
lines changed

compiler/rustc_metadata/src/creader.rs

+81-20
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,43 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
157157
}
158158
}
159159

160+
/// Reason that a crate is being sourced as a dependency.
161+
#[derive(Clone, Copy)]
162+
enum CrateOrigin<'a> {
163+
/// This crate was a dependency of another crate.
164+
Dependency {
165+
dep_root: &'a CratePaths,
166+
/// Dependency info about this crate.
167+
dep: &'a CrateDep,
168+
},
169+
/// Injected by `rustc`.
170+
Injected,
171+
/// An extern that has been provided with the `force` option.
172+
ForcedExtern,
173+
/// Part of the extern prelude.
174+
ExternPrelude,
175+
/// Provided by `extern crate foo`.
176+
AstExtern,
177+
}
178+
179+
impl<'a> CrateOrigin<'a> {
180+
/// Return the dependency root, if any.
181+
fn dep_root(&self) -> Option<&'a CratePaths> {
182+
match self {
183+
CrateOrigin::Dependency { dep_root, .. } => Some(dep_root),
184+
_ => None,
185+
}
186+
}
187+
188+
/// Return dependency information, if any.
189+
fn dep(&self) -> Option<&'a CrateDep> {
190+
match self {
191+
CrateOrigin::Dependency { dep, .. } => Some(dep),
192+
_ => None,
193+
}
194+
}
195+
}
196+
160197
impl CStore {
161198
pub fn from_tcx(tcx: TyCtxt<'_>) -> FreezeReadGuard<'_, CStore> {
162199
FreezeReadGuard::map(tcx.untracked().cstore.read(), |cstore| {
@@ -404,7 +441,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
404441
&self,
405442
name: Symbol,
406443
private_dep: Option<bool>,
407-
dep_root: Option<&CratePaths>,
444+
origin: CrateOrigin<'_>,
408445
) -> bool {
409446
// Standard library crates are never private.
410447
if STDLIB_STABLE_CRATES.contains(&name) {
@@ -414,10 +451,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414451

415452
let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep);
416453

454+
if matches!(origin, CrateOrigin::Injected) {
455+
return true;
456+
}
457+
417458
// Any descendants of `std` should be private. These crates are usually not marked
418459
// private in metadata, so we ignore that field.
419460
if extern_private.is_none()
420-
&& let Some(dep) = dep_root
461+
&& let Some(dep) = origin.dep_root()
421462
&& STDLIB_STABLE_CRATES.contains(&dep.name)
422463
{
423464
return true;
@@ -435,7 +476,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
435476
fn register_crate(
436477
&mut self,
437478
host_lib: Option<Library>,
438-
dep_root: Option<&CratePaths>,
479+
origin: CrateOrigin<'_>,
439480
lib: Library,
440481
dep_kind: CrateDepKind,
441482
name: Symbol,
@@ -447,7 +488,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
447488
let Library { source, metadata } = lib;
448489
let crate_root = metadata.get_root();
449490
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
450-
let private_dep = self.is_private_dep(name, private_dep, dep_root);
491+
let private_dep = self.is_private_dep(name, private_dep, origin);
451492

452493
// Claim this crate number and cache it
453494
let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
@@ -463,7 +504,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
463504
// Maintain a reference to the top most crate.
464505
// Stash paths for top-most crate locally if necessary.
465506
let crate_paths;
466-
let dep_root = if let Some(dep_root) = dep_root {
507+
let dep_root = if let Some(dep_root) = origin.dep_root() {
467508
dep_root
468509
} else {
469510
crate_paths = CratePaths::new(crate_root.name(), source.clone());
@@ -571,17 +612,23 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
571612
name: Symbol,
572613
span: Span,
573614
dep_kind: CrateDepKind,
615+
origin: CrateOrigin<'_>,
574616
) -> Option<CrateNum> {
575617
self.used_extern_options.insert(name);
576-
match self.maybe_resolve_crate(name, dep_kind, None) {
618+
match self.maybe_resolve_crate(name, dep_kind, origin) {
577619
Ok(cnum) => {
578620
self.cstore.set_used_recursively(cnum);
579621
Some(cnum)
580622
}
581623
Err(err) => {
582624
debug!("failed to resolve crate {} {:?}", name, dep_kind);
583-
let missing_core =
584-
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
625+
let missing_core = self
626+
.maybe_resolve_crate(
627+
sym::core,
628+
CrateDepKind::Explicit,
629+
CrateOrigin::ExternPrelude,
630+
)
631+
.is_err();
585632
err.report(self.sess, span, missing_core);
586633
None
587634
}
@@ -592,15 +639,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
592639
&'b mut self,
593640
name: Symbol,
594641
mut dep_kind: CrateDepKind,
595-
dep_of: Option<(&'b CratePaths, &'b CrateDep)>,
642+
origin: CrateOrigin<'b>,
596643
) -> Result<CrateNum, CrateError> {
597644
info!("resolving crate `{}`", name);
598645
if !name.as_str().is_ascii() {
599646
return Err(CrateError::NonAsciiName(name));
600647
}
601648

602-
let dep_root = dep_of.map(|d| d.0);
603-
let dep = dep_of.map(|d| d.1);
649+
let dep_root = origin.dep_root();
650+
let dep = origin.dep();
604651
let hash = dep.map(|d| d.hash);
605652
let host_hash = dep.map(|d| d.host_hash).flatten();
606653
let extra_filename = dep.map(|d| &d.extra_filename[..]);
@@ -643,7 +690,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
643690
// not specified by `--extern` on command line parameters, it may be
644691
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
645692
// `public-dependency` here.
646-
let private_dep = self.is_private_dep(name, private_dep, dep_root);
693+
let private_dep = self.is_private_dep(name, private_dep, origin);
647694
let data = self.cstore.get_crate_data_mut(cnum);
648695
if data.is_proc_macro_crate() {
649696
dep_kind = CrateDepKind::MacrosOnly;
@@ -654,7 +701,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
654701
}
655702
(LoadResult::Loaded(library), host_library) => {
656703
info!("register newly loaded library for `{}`", name);
657-
self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep)
704+
self.register_crate(host_library, origin, library, dep_kind, name, private_dep)
658705
}
659706
_ => panic!(),
660707
}
@@ -730,7 +777,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
730777
CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
731778
_ => dep.kind,
732779
};
733-
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?;
780+
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, CrateOrigin::Dependency {
781+
dep_root,
782+
dep: &dep,
783+
})?;
734784
crate_num_map.push(cnum);
735785
}
736786

@@ -824,7 +874,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
824874
};
825875
info!("panic runtime not found -- loading {}", name);
826876

827-
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
877+
let Some(cnum) =
878+
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
879+
else {
828880
return;
829881
};
830882
let data = self.cstore.get_crate_data(cnum);
@@ -853,7 +905,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
853905
info!("loading profiler");
854906

855907
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
856-
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
908+
let Some(cnum) =
909+
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
910+
else {
857911
return;
858912
};
859913
let data = self.cstore.get_crate_data(cnum);
@@ -966,7 +1020,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
9661020
if entry.force {
9671021
let name_interned = Symbol::intern(name);
9681022
if !self.used_extern_options.contains(&name_interned) {
969-
self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit);
1023+
self.resolve_crate(
1024+
name_interned,
1025+
DUMMY_SP,
1026+
CrateDepKind::Explicit,
1027+
CrateOrigin::ForcedExtern,
1028+
);
9701029
}
9711030
}
9721031
}
@@ -1092,6 +1151,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10921151
info!("{:?}", CrateDump(self.cstore));
10931152
}
10941153

1154+
/// Process an `extern crate foo` AST node.
10951155
pub fn process_extern_crate(
10961156
&mut self,
10971157
item: &ast::Item,
@@ -1117,7 +1177,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11171177
CrateDepKind::Explicit
11181178
};
11191179

1120-
let cnum = self.resolve_crate(name, item.span, dep_kind)?;
1180+
let cnum = self.resolve_crate(name, item.span, dep_kind, CrateOrigin::AstExtern)?;
11211181

11221182
let path_len = definitions.def_path(def_id).data.len();
11231183
self.cstore.update_extern_crate(cnum, ExternCrate {
@@ -1133,7 +1193,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11331193
}
11341194

11351195
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
1136-
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
1196+
let cnum =
1197+
self.resolve_crate(name, span, CrateDepKind::Explicit, CrateOrigin::ExternPrelude)?;
11371198

11381199
self.cstore.update_extern_crate(cnum, ExternCrate {
11391200
src: ExternCrateSource::Path,
@@ -1147,7 +1208,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11471208
}
11481209

11491210
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
1150-
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
1211+
self.maybe_resolve_crate(name, CrateDepKind::Explicit, CrateOrigin::ExternPrelude).ok()
11511212
}
11521213
}
11531214

0 commit comments

Comments
 (0)