Skip to content

Commit c77897e

Browse files
Auto merge of #149273 - bjorn3:crate_locator_improvements, r=<try>
Don't leak sysroot crates through dependencies
2 parents 7b9905e + ac0aabb commit c77897e

File tree

17 files changed

+168
-91
lines changed

17 files changed

+168
-91
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub fn each_linked_rlib(
278278
}
279279
let crate_name = info.crate_name[&cnum];
280280
let used_crate_source = &info.used_crate_source[&cnum];
281-
if let Some((path, _)) = &used_crate_source.rlib {
281+
if let Some(path) = &used_crate_source.rlib {
282282
f(cnum, path);
283283
} else if used_crate_source.rmeta.is_some() {
284284
return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
@@ -542,7 +542,7 @@ fn link_staticlib(
542542
};
543543
let crate_name = codegen_results.crate_info.crate_name[&cnum];
544544
let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
545-
if let Some((path, _)) = &used_crate_source.dylib {
545+
if let Some(path) = &used_crate_source.dylib {
546546
all_rust_dylibs.push(&**path);
547547
} else if used_crate_source.rmeta.is_some() {
548548
sess.dcx().emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
@@ -620,7 +620,6 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
620620
.used_crate_source
621621
.items()
622622
.filter_map(|(_, csource)| csource.rlib.as_ref())
623-
.map(|(path, _)| path)
624623
.into_sorted_stable_ord();
625624

626625
for input_rlib in input_rlibs {
@@ -2178,12 +2177,7 @@ fn add_rpath_args(
21782177
.crate_info
21792178
.used_crates
21802179
.iter()
2181-
.filter_map(|cnum| {
2182-
codegen_results.crate_info.used_crate_source[cnum]
2183-
.dylib
2184-
.as_ref()
2185-
.map(|(path, _)| &**path)
2186-
})
2180+
.filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref())
21872181
.collect::<Vec<_>>();
21882182
let rpath_config = RPathConfig {
21892183
libs: &*libs,
@@ -2661,7 +2655,7 @@ fn add_native_libs_from_crate(
26612655

26622656
if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() {
26632657
// If rlib contains native libs as archives, unpack them to tmpdir.
2664-
let rlib = &codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap().0;
2658+
let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap();
26652659
archive_builder_builder
26662660
.extract_bundled_libs(rlib, tmpdir, bundled_libs)
26672661
.unwrap_or_else(|e| sess.dcx().emit_fatal(e));
@@ -2832,7 +2826,7 @@ fn add_upstream_rust_crates(
28322826
}
28332827
Linkage::Dynamic => {
28342828
let src = &codegen_results.crate_info.used_crate_source[&cnum];
2835-
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0);
2829+
add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap());
28362830
}
28372831
}
28382832

@@ -2960,7 +2954,7 @@ fn add_static_crate(
29602954
bundled_lib_file_names: &FxIndexSet<Symbol>,
29612955
) {
29622956
let src = &codegen_results.crate_info.used_crate_source[&cnum];
2963-
let cratepath = &src.rlib.as_ref().unwrap().0;
2957+
let cratepath = src.rlib.as_ref().unwrap();
29642958

29652959
let mut link_upstream =
29662960
|path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false);

compiler/rustc_data_structures/src/fx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::hash::BuildHasherDefault;
22

3-
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
3+
pub use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet, FxHasher};
44

55
pub type StdEntry<'a, K, V> = std::collections::hash_map::Entry<'a, K, V>;
66

compiler/rustc_interface/src/passes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,19 +684,19 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
684684

685685
for &cnum in tcx.crates(()) {
686686
let source = tcx.used_crate_source(cnum);
687-
if let Some((path, _)) = &source.dylib {
687+
if let Some(path) = &source.dylib {
688688
files.extend(hash_iter_files(
689689
iter::once(escape_dep_filename(&path.display().to_string())),
690690
checksum_hash_algo,
691691
));
692692
}
693-
if let Some((path, _)) = &source.rlib {
693+
if let Some(path) = &source.rlib {
694694
files.extend(hash_iter_files(
695695
iter::once(escape_dep_filename(&path.display().to_string())),
696696
checksum_hash_algo,
697697
));
698698
}
699-
if let Some((path, _)) = &source.rmeta {
699+
if let Some(path) = &source.rmeta {
700700
files.extend(hash_iter_files(
701701
iter::once(escape_dep_filename(&path.display().to_string())),
702702
checksum_hash_algo,

compiler/rustc_metadata/src/creader.rs

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,16 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
135135
writeln!(fmt, " priv: {:?}", data.is_private_dep())?;
136136
let CrateSource { dylib, rlib, rmeta, sdylib_interface } = data.source();
137137
if let Some(dylib) = dylib {
138-
writeln!(fmt, " dylib: {}", dylib.0.display())?;
138+
writeln!(fmt, " dylib: {}", dylib.display())?;
139139
}
140140
if let Some(rlib) = rlib {
141-
writeln!(fmt, " rlib: {}", rlib.0.display())?;
141+
writeln!(fmt, " rlib: {}", rlib.display())?;
142142
}
143143
if let Some(rmeta) = rmeta {
144-
writeln!(fmt, " rmeta: {}", rmeta.0.display())?;
144+
writeln!(fmt, " rmeta: {}", rmeta.display())?;
145145
}
146146
if let Some(sdylib_interface) = sdylib_interface {
147-
writeln!(fmt, " sdylib interface: {}", sdylib_interface.0.display())?;
147+
writeln!(fmt, " sdylib interface: {}", sdylib_interface.display())?;
148148
}
149149
}
150150
Ok(())
@@ -516,10 +516,9 @@ impl CStore {
516516

517517
fn existing_match(
518518
&self,
519-
externs: &Externs,
519+
_externs: &Externs,
520520
name: Symbol,
521521
hash: Option<Svh>,
522-
kind: PathKind,
523522
) -> Option<CrateNum> {
524523
for (cnum, data) in self.iter_crate_data() {
525524
if data.name() != name {
@@ -536,6 +535,13 @@ impl CStore {
536535
None => {}
537536
}
538537

538+
/*
539+
if !data.used() {
540+
// Ignore speculatively loaded crates. Using them can hide ambiguity errors:
541+
// https://github.com/rust-lang/rust/issues/147966#issuecomment-3444198198
542+
continue;
543+
}
544+
539545
// When the hash is None we're dealing with a top-level dependency
540546
// in which case we may have a specification on the command line for
541547
// this library. Even though an upstream library may have loaded
@@ -551,37 +557,20 @@ impl CStore {
551557
if let Some(mut files) = entry.files() {
552558
if files.any(|l| {
553559
let l = l.canonicalized();
554-
source.dylib.as_ref().map(|(p, _)| p) == Some(l)
555-
|| source.rlib.as_ref().map(|(p, _)| p) == Some(l)
556-
|| source.rmeta.as_ref().map(|(p, _)| p) == Some(l)
560+
source.dylib.as_ref() == Some(l)
561+
|| source.rlib.as_ref() == Some(l)
562+
|| source.rmeta.as_ref() == Some(l)
557563
}) {
558564
return Some(cnum);
559565
}
560566
}
561567
continue;
562568
}
563569
564-
// Alright, so we've gotten this far which means that `data` has the
565-
// right name, we don't have a hash, and we don't have a --extern
566-
// pointing for ourselves. We're still not quite yet done because we
567-
// have to make sure that this crate was found in the crate lookup
568-
// path (this is a top-level dependency) as we don't want to
569-
// implicitly load anything inside the dependency lookup path.
570-
let prev_kind = source
571-
.dylib
572-
.as_ref()
573-
.or(source.rlib.as_ref())
574-
.or(source.rmeta.as_ref())
575-
.expect("No sources for crate")
576-
.1;
577-
if kind.matches(prev_kind) {
578-
return Some(cnum);
579-
} else {
580-
debug!(
581-
"failed to load existing crate {}; kind {:?} did not match prev_kind {:?}",
582-
name, kind, prev_kind
583-
);
584-
}
570+
// While the crate name matched, no --extern crate_name=path matched. It is possible
571+
// that we have already loaded the target crate, but if that happens CStore::load will
572+
// indicate so and we gracefully handle this, just potentially wasting a bit of time.
573+
*/
585574
}
586575

587576
None
@@ -677,7 +666,7 @@ impl CStore {
677666
None => (&source, &crate_root),
678667
};
679668
let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate");
680-
Some(self.dlsym_proc_macros(tcx.sess, &dlsym_dylib.0, dlsym_root.stable_crate_id())?)
669+
Some(self.dlsym_proc_macros(tcx.sess, dlsym_dylib, dlsym_root.stable_crate_id())?)
681670
} else {
682671
None
683672
};
@@ -818,9 +807,7 @@ impl CStore {
818807
let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
819808
let private_dep = origin.private_dep();
820809

821-
let result = if let Some(cnum) =
822-
self.existing_match(&tcx.sess.opts.externs, name, hash, path_kind)
823-
{
810+
let result = if let Some(cnum) = self.existing_match(&tcx.sess.opts.externs, name, hash) {
824811
(LoadResult::Previous(cnum), None)
825812
} else {
826813
info!("falling back to a load");

compiler/rustc_metadata/src/locator.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ use std::ops::Deref;
218218
use std::path::{Path, PathBuf};
219219
use std::{cmp, fmt};
220220

221-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
221+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
222222
use rustc_data_structures::memmap::Mmap;
223223
use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
224224
use rustc_data_structures::svh::Svh;
@@ -401,7 +401,7 @@ impl<'a> CrateLocator<'a> {
401401

402402
let mut candidates: FxIndexMap<
403403
_,
404-
(FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>),
404+
(FxIndexSet<_>, FxIndexSet<_>, FxIndexSet<_>, FxIndexSet<_>),
405405
> = Default::default();
406406

407407
// First, find all possible candidate rlibs and dylibs purely based on
@@ -460,10 +460,10 @@ impl<'a> CrateLocator<'a> {
460460
// filesystem code should not care, but this is nicer for diagnostics.
461461
let path = spf.path.to_path_buf();
462462
match kind {
463-
CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
464-
CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),
465-
CrateFlavor::Dylib => dylibs.insert(path, search_path.kind),
466-
CrateFlavor::SDylib => interfaces.insert(path, search_path.kind),
463+
CrateFlavor::Rlib => rlibs.insert(path),
464+
CrateFlavor::Rmeta => rmetas.insert(path),
465+
CrateFlavor::Dylib => dylibs.insert(path),
466+
CrateFlavor::SDylib => interfaces.insert(path),
467467
};
468468
}
469469
}
@@ -524,10 +524,10 @@ impl<'a> CrateLocator<'a> {
524524
fn extract_lib(
525525
&self,
526526
crate_rejections: &mut CrateRejections,
527-
rlibs: FxIndexMap<PathBuf, PathKind>,
528-
rmetas: FxIndexMap<PathBuf, PathKind>,
529-
dylibs: FxIndexMap<PathBuf, PathKind>,
530-
interfaces: FxIndexMap<PathBuf, PathKind>,
527+
rlibs: FxIndexSet<PathBuf>,
528+
rmetas: FxIndexSet<PathBuf>,
529+
dylibs: FxIndexSet<PathBuf>,
530+
interfaces: FxIndexSet<PathBuf>,
531531
) -> Result<Option<(Svh, Library)>, CrateError> {
532532
let mut slot = None;
533533
// Order here matters, rmeta should come first.
@@ -575,10 +575,10 @@ impl<'a> CrateLocator<'a> {
575575
fn extract_one(
576576
&self,
577577
crate_rejections: &mut CrateRejections,
578-
m: FxIndexMap<PathBuf, PathKind>,
578+
m: FxIndexSet<PathBuf>,
579579
flavor: CrateFlavor,
580580
slot: &mut Option<(Svh, MetadataBlob, PathBuf, CrateFlavor)>,
581-
) -> Result<Option<(PathBuf, PathKind)>, CrateError> {
581+
) -> Result<Option<PathBuf>, CrateError> {
582582
// If we are producing an rlib, and we've already loaded metadata, then
583583
// we should not attempt to discover further crate sources (unless we're
584584
// locating a proc macro; exact logic is in needs_crate_flavor). This means
@@ -594,9 +594,9 @@ impl<'a> CrateLocator<'a> {
594594
}
595595
}
596596

597-
let mut ret: Option<(PathBuf, PathKind)> = None;
597+
let mut ret: Option<PathBuf> = None;
598598
let mut err_data: Option<Vec<PathBuf>> = None;
599-
for (lib, kind) in m {
599+
for lib in m {
600600
info!("{} reading metadata from: {}", flavor, lib.display());
601601
if flavor == CrateFlavor::Rmeta && lib.metadata().is_ok_and(|m| m.len() == 0) {
602602
// Empty files will cause get_metadata_section to fail. Rmeta
@@ -640,7 +640,7 @@ impl<'a> CrateLocator<'a> {
640640
info!("no metadata found: {}", err);
641641
// Metadata was loaded from interface file earlier.
642642
if let Some((.., CrateFlavor::SDylib)) = slot {
643-
ret = Some((lib, kind));
643+
ret = Some(lib);
644644
continue;
645645
}
646646
// The file was present and created by the same compiler version, but we
@@ -689,7 +689,7 @@ impl<'a> CrateLocator<'a> {
689689
// As a result, we favor the sysroot crate here. Note that the
690690
// candidates are all canonicalized, so we canonicalize the sysroot
691691
// as well.
692-
if let Some((prev, _)) = &ret {
692+
if let Some(prev) = &ret {
693693
let sysroot = self.sysroot;
694694
let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf());
695695
if prev.starts_with(&sysroot) {
@@ -714,7 +714,7 @@ impl<'a> CrateLocator<'a> {
714714
} else {
715715
*slot = Some((hash, metadata, lib.clone(), flavor));
716716
}
717-
ret = Some((lib, kind));
717+
ret = Some(lib);
718718
}
719719

720720
if let Some(candidates) = err_data {
@@ -774,10 +774,10 @@ impl<'a> CrateLocator<'a> {
774774
// First, filter out all libraries that look suspicious. We only accept
775775
// files which actually exist that have the correct naming scheme for
776776
// rlibs/dylibs.
777-
let mut rlibs = FxIndexMap::default();
778-
let mut rmetas = FxIndexMap::default();
779-
let mut dylibs = FxIndexMap::default();
780-
let mut sdylib_interfaces = FxIndexMap::default();
777+
let mut rlibs = FxIndexSet::default();
778+
let mut rmetas = FxIndexSet::default();
779+
let mut dylibs = FxIndexSet::default();
780+
let mut sdylib_interfaces = FxIndexSet::default();
781781
for loc in &self.exact_paths {
782782
let loc_canon = loc.canonicalized();
783783
let loc_orig = loc.original();
@@ -798,21 +798,21 @@ impl<'a> CrateLocator<'a> {
798798
};
799799
if file.starts_with("lib") {
800800
if file.ends_with(".rlib") {
801-
rlibs.insert(loc_canon.clone(), PathKind::ExternFlag);
801+
rlibs.insert(loc_canon.clone());
802802
continue;
803803
}
804804
if file.ends_with(".rmeta") {
805-
rmetas.insert(loc_canon.clone(), PathKind::ExternFlag);
805+
rmetas.insert(loc_canon.clone());
806806
continue;
807807
}
808808
if file.ends_with(".rs") {
809-
sdylib_interfaces.insert(loc_canon.clone(), PathKind::ExternFlag);
809+
sdylib_interfaces.insert(loc_canon.clone());
810810
}
811811
}
812812
let dll_prefix = self.target.dll_prefix.as_ref();
813813
let dll_suffix = self.target.dll_suffix.as_ref();
814814
if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) {
815-
dylibs.insert(loc_canon.clone(), PathKind::ExternFlag);
815+
dylibs.insert(loc_canon.clone());
816816
continue;
817817
}
818818
crate_rejections

compiler/rustc_session/src/cstore.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,22 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
1515
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1616
use rustc_span::{Span, Symbol};
1717

18-
use crate::search_paths::PathKind;
19-
2018
// lonely orphan structs and enums looking for a better home
2119

2220
/// Where a crate came from on the local filesystem. One of these three options
2321
/// must be non-None.
2422
#[derive(PartialEq, Clone, Debug, HashStable_Generic, Encodable, Decodable)]
2523
pub struct CrateSource {
26-
pub dylib: Option<(PathBuf, PathKind)>,
27-
pub rlib: Option<(PathBuf, PathKind)>,
28-
pub rmeta: Option<(PathBuf, PathKind)>,
29-
pub sdylib_interface: Option<(PathBuf, PathKind)>,
24+
pub dylib: Option<PathBuf>,
25+
pub rlib: Option<PathBuf>,
26+
pub rmeta: Option<PathBuf>,
27+
pub sdylib_interface: Option<PathBuf>,
3028
}
3129

3230
impl CrateSource {
3331
#[inline]
3432
pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
35-
self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0)
33+
self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter())
3634
}
3735
}
3836

compiler/rustc_session/src/search_paths.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ pub enum PathKind {
7171
Crate,
7272
Dependency,
7373
Framework,
74-
ExternFlag,
7574
All,
7675
}
7776

0 commit comments

Comments
 (0)