Skip to content

Commit ab04010

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 4e1356b commit ab04010

File tree

1 file changed

+82
-20
lines changed

1 file changed

+82
-20
lines changed

compiler/rustc_metadata/src/creader.rs

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,43 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
162162
}
163163
}
164164

165+
/// Reason that a crate is being sourced as a dependency.
166+
#[derive(Clone, Copy)]
167+
enum CrateOrigin<'a> {
168+
/// This crate was a dependency of another crate.
169+
Dependency {
170+
dep_root: &'a CratePaths,
171+
/// Dependency info about this crate.
172+
dep: &'a CrateDep,
173+
},
174+
/// Injected by `rustc`.
175+
Injected,
176+
/// An extern that has been provided with the `force` option.
177+
ForcedExtern,
178+
/// Part of the extern prelude.
179+
ExternPrelude,
180+
/// Provided by `extern crate foo`.
181+
AstExtern,
182+
}
183+
184+
impl<'a> CrateOrigin<'a> {
185+
/// Return the dependency root, if any.
186+
fn dep_root(&self) -> Option<&'a CratePaths> {
187+
match self {
188+
CrateOrigin::Dependency { dep_root, .. } => Some(dep_root),
189+
_ => None,
190+
}
191+
}
192+
193+
/// Return dependency information, if any.
194+
fn dep(&self) -> Option<&'a CrateDep> {
195+
match self {
196+
CrateOrigin::Dependency { dep, .. } => Some(dep),
197+
_ => None,
198+
}
199+
}
200+
}
201+
165202
impl CStore {
166203
pub fn from_tcx(tcx: TyCtxt<'_>) -> FreezeReadGuard<'_, CStore> {
167204
FreezeReadGuard::map(tcx.untracked().cstore.read(), |cstore| {
@@ -497,7 +534,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
497534
&self,
498535
name: Symbol,
499536
private_dep: Option<bool>,
500-
dep_root: Option<&CratePaths>,
537+
origin: CrateOrigin<'_>,
501538
) -> bool {
502539
// Standard library crates are never private.
503540
if STDLIB_STABLE_CRATES.contains(&name) {
@@ -507,10 +544,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
507544

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

547+
if matches!(origin, CrateOrigin::Injected) {
548+
return true;
549+
}
550+
510551
// Any descendants of `std` should be private. These crates are usually not marked
511552
// private in metadata, so we ignore that field.
512553
if extern_private.is_none()
513-
&& let Some(dep) = dep_root
554+
&& let Some(dep) = origin.dep_root()
514555
&& STDLIB_STABLE_CRATES.contains(&dep.name)
515556
{
516557
return true;
@@ -528,7 +569,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
528569
fn register_crate(
529570
&mut self,
530571
host_lib: Option<Library>,
531-
dep_root: Option<&CratePaths>,
572+
origin: CrateOrigin<'_>,
532573
lib: Library,
533574
dep_kind: CrateDepKind,
534575
name: Symbol,
@@ -540,7 +581,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
540581
let Library { source, metadata } = lib;
541582
let crate_root = metadata.get_root();
542583
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
543-
let private_dep = self.is_private_dep(name, private_dep, dep_root);
584+
let private_dep = self.is_private_dep(name, private_dep, origin);
544585

545586
// Claim this crate number and cache it
546587
let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
@@ -556,7 +597,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
556597
// Maintain a reference to the top most crate.
557598
// Stash paths for top-most crate locally if necessary.
558599
let crate_paths;
559-
let dep_root = if let Some(dep_root) = dep_root {
600+
let dep_root = if let Some(dep_root) = origin.dep_root() {
560601
dep_root
561602
} else {
562603
crate_paths = CratePaths::new(crate_root.name(), source.clone());
@@ -664,17 +705,23 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
664705
name: Symbol,
665706
span: Span,
666707
dep_kind: CrateDepKind,
708+
origin: CrateOrigin<'_>,
667709
) -> Option<CrateNum> {
668710
self.used_extern_options.insert(name);
669-
match self.maybe_resolve_crate(name, dep_kind, None) {
711+
match self.maybe_resolve_crate(name, dep_kind, origin) {
670712
Ok(cnum) => {
671713
self.cstore.set_used_recursively(cnum);
672714
Some(cnum)
673715
}
674716
Err(err) => {
675717
debug!("failed to resolve crate {} {:?}", name, dep_kind);
676-
let missing_core =
677-
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
718+
let missing_core = self
719+
.maybe_resolve_crate(
720+
sym::core,
721+
CrateDepKind::Explicit,
722+
CrateOrigin::ExternPrelude,
723+
)
724+
.is_err();
678725
err.report(self.sess, span, missing_core);
679726
None
680727
}
@@ -685,15 +732,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
685732
&'b mut self,
686733
name: Symbol,
687734
mut dep_kind: CrateDepKind,
688-
dep_of: Option<(&'b CratePaths, &'b CrateDep)>,
735+
origin: CrateOrigin<'b>,
689736
) -> Result<CrateNum, CrateError> {
690737
info!("resolving crate `{}`", name);
691738
if !name.as_str().is_ascii() {
692739
return Err(CrateError::NonAsciiName(name));
693740
}
694741

695-
let dep_root = dep_of.map(|d| d.0);
696-
let dep = dep_of.map(|d| d.1);
742+
let dep_root = origin.dep_root();
743+
let dep = origin.dep();
697744
let hash = dep.map(|d| d.hash);
698745
let host_hash = dep.map(|d| d.host_hash).flatten();
699746
let extra_filename = dep.map(|d| &d.extra_filename[..]);
@@ -736,7 +783,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
736783
// not specified by `--extern` on command line parameters, it may be
737784
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
738785
// `public-dependency` here.
739-
let private_dep = self.is_private_dep(name, private_dep, dep_root);
786+
let private_dep = self.is_private_dep(name, private_dep, origin);
740787
let data = self.cstore.get_crate_data_mut(cnum);
741788
if data.is_proc_macro_crate() {
742789
dep_kind = CrateDepKind::MacrosOnly;
@@ -747,7 +794,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
747794
}
748795
(LoadResult::Loaded(library), host_library) => {
749796
info!("register newly loaded library for `{}`", name);
750-
self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep)
797+
self.register_crate(host_library, origin, library, dep_kind, name, private_dep)
751798
}
752799
_ => panic!(),
753800
}
@@ -823,7 +870,11 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
823870
CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
824871
_ => dep.kind,
825872
};
826-
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?;
873+
let cnum = self.maybe_resolve_crate(
874+
dep.name,
875+
dep_kind,
876+
CrateOrigin::Dependency { dep_root, dep: &dep },
877+
)?;
827878
crate_num_map.push(cnum);
828879
}
829880

@@ -917,7 +968,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
917968
};
918969
info!("panic runtime not found -- loading {}", name);
919970

920-
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
971+
let Some(cnum) =
972+
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
973+
else {
921974
return;
922975
};
923976
let data = self.cstore.get_crate_data(cnum);
@@ -946,7 +999,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
946999
info!("loading profiler");
9471000

9481001
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
949-
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
1002+
let Some(cnum) =
1003+
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
1004+
else {
9501005
return;
9511006
};
9521007
let data = self.cstore.get_crate_data(cnum);
@@ -1059,7 +1114,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10591114
if entry.force {
10601115
let name_interned = Symbol::intern(name);
10611116
if !self.used_extern_options.contains(&name_interned) {
1062-
self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit);
1117+
self.resolve_crate(
1118+
name_interned,
1119+
DUMMY_SP,
1120+
CrateDepKind::Explicit,
1121+
CrateOrigin::ForcedExtern,
1122+
);
10631123
}
10641124
}
10651125
}
@@ -1185,6 +1245,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11851245
info!("{:?}", CrateDump(self.cstore));
11861246
}
11871247

1248+
/// Process an `extern crate foo` AST node.
11881249
pub fn process_extern_crate(
11891250
&mut self,
11901251
item: &ast::Item,
@@ -1210,7 +1271,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
12101271
CrateDepKind::Explicit
12111272
};
12121273

1213-
let cnum = self.resolve_crate(name, item.span, dep_kind)?;
1274+
let cnum = self.resolve_crate(name, item.span, dep_kind, CrateOrigin::AstExtern)?;
12141275

12151276
let path_len = definitions.def_path(def_id).data.len();
12161277
self.cstore.update_extern_crate(
@@ -1229,7 +1290,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
12291290
}
12301291

12311292
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
1232-
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
1293+
let cnum =
1294+
self.resolve_crate(name, span, CrateDepKind::Explicit, CrateOrigin::ExternPrelude)?;
12331295

12341296
self.cstore.update_extern_crate(
12351297
cnum,
@@ -1246,7 +1308,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
12461308
}
12471309

12481310
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
1249-
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
1311+
self.maybe_resolve_crate(name, CrateDepKind::Explicit, CrateOrigin::ExternPrelude).ok()
12501312
}
12511313
}
12521314

0 commit comments

Comments
 (0)