Skip to content

Commit a16c637

Browse files
authored
Rollup merge of rust-lang#65026 - petrochenkov:ice1, r=eddyb
metadata: Some crate loading cleanup So, my goal was to fix caching of loaded crates which is broken and causes ICEs like rust-lang#56935 or rust-lang#64450. While investigating I found that the code is pretty messy and likes to confuse various things that look similar but are actually different. This PR does some initial cleanup in that area, I hope to get to the caching itself a bit later.
2 parents cb4145e + 68aadcb commit a16c637

File tree

8 files changed

+85
-129
lines changed

8 files changed

+85
-129
lines changed

src/librustc/middle/cstore.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ pub enum ExternCrateSource {
148148
/// such ids
149149
DefId,
150150
),
151-
// Crate is loaded by `use`.
152-
Use,
153-
/// Crate is implicitly loaded by an absolute path.
151+
/// Crate is implicitly loaded by a path resolving through extern prelude.
154152
Path,
155153
}
156154

src/librustc_metadata/creader.rs

+62-87
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
44
use crate::locator::{self, CratePaths};
5-
use crate::schema::{CrateRoot};
5+
use crate::schema::{CrateRoot, CrateDep};
66
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
77

88
use rustc::hir::def_id::CrateNum;
@@ -20,7 +20,7 @@ use rustc::hir::map::Definitions;
2020
use rustc::hir::def_id::LOCAL_CRATE;
2121

2222
use std::ops::Deref;
23-
use std::path::PathBuf;
23+
use std::path::{Path, PathBuf};
2424
use std::{cmp, fs};
2525

2626
use syntax::ast;
@@ -112,7 +112,7 @@ impl<'a> CrateLoader<'a> {
112112
-> Option<CrateNum> {
113113
let mut ret = None;
114114
self.cstore.iter_crate_data(|cnum, data| {
115-
if data.name != name { return }
115+
if data.root.name != name { return }
116116

117117
match hash {
118118
Some(hash) if *hash == data.root.hash => { ret = Some(cnum); return }
@@ -190,8 +190,7 @@ impl<'a> CrateLoader<'a> {
190190
fn register_crate(
191191
&mut self,
192192
host_lib: Option<Library>,
193-
root: &Option<CratePaths>,
194-
ident: Symbol,
193+
root: Option<&CratePaths>,
195194
span: Span,
196195
lib: Library,
197196
dep_kind: DepKind,
@@ -204,40 +203,40 @@ impl<'a> CrateLoader<'a> {
204203
.map(|e| e.is_private_dep)
205204
.unwrap_or(false);
206205

207-
info!("register crate `extern crate {} as {}` (private_dep = {})",
208-
crate_root.name, ident, private_dep);
209-
206+
info!("register crate `{}` (private_dep = {})", crate_root.name, private_dep);
210207

211208
// Claim this crate number and cache it
212209
let cnum = self.cstore.alloc_new_crate_num();
213210

211+
// Maintain a reference to the top most crate.
214212
// Stash paths for top-most crate locally if necessary.
215-
let crate_paths = if root.is_none() {
216-
Some(CratePaths {
217-
ident: ident.to_string(),
213+
let crate_paths;
214+
let root = if let Some(root) = root {
215+
root
216+
} else {
217+
crate_paths = CratePaths {
218+
ident: crate_root.name.to_string(),
218219
dylib: lib.dylib.clone().map(|p| p.0),
219220
rlib: lib.rlib.clone().map(|p| p.0),
220221
rmeta: lib.rmeta.clone().map(|p| p.0),
221-
})
222-
} else {
223-
None
222+
};
223+
&crate_paths
224224
};
225-
// Maintain a reference to the top most crate.
226-
let root = if root.is_some() { root } else { &crate_paths };
227225

228226
let Library { dylib, rlib, rmeta, metadata } = lib;
229227
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
230228

231229
let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
232230

233231
let raw_proc_macros = crate_root.proc_macro_data.map(|_| {
234-
if self.sess.opts.debugging_opts.dual_proc_macros {
235-
let host_lib = host_lib.as_ref().unwrap();
236-
self.dlsym_proc_macros(host_lib.dylib.as_ref().map(|p| p.0.clone()),
237-
&host_lib.metadata.get_root(), span)
238-
} else {
239-
self.dlsym_proc_macros(dylib.clone().map(|p| p.0), &crate_root, span)
240-
}
232+
let temp_root;
233+
let (dlsym_dylib, dlsym_root) = match &host_lib {
234+
Some(host_lib) =>
235+
(&host_lib.dylib, { temp_root = host_lib.metadata.get_root(); &temp_root }),
236+
None => (&dylib, &crate_root),
237+
};
238+
let dlsym_dylib = dlsym_dylib.as_ref().expect("no dylib for a proc-macro crate");
239+
self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span)
241240
});
242241

243242
let interpret_alloc_index: Vec<u32> = crate_root.interpret_alloc_index
@@ -254,8 +253,6 @@ impl<'a> CrateLoader<'a> {
254253
});
255254

256255
let cmeta = cstore::CrateMetadata {
257-
name: crate_root.name,
258-
imported_name: ident,
259256
extern_crate: Lock::new(None),
260257
def_path_table: Lrc::new(def_path_table),
261258
trait_impls,
@@ -274,7 +271,6 @@ impl<'a> CrateLoader<'a> {
274271
},
275272
private_dep,
276273
span,
277-
host_lib,
278274
raw_proc_macros
279275
};
280276

@@ -340,24 +336,34 @@ impl<'a> CrateLoader<'a> {
340336

341337
fn resolve_crate<'b>(
342338
&'b mut self,
343-
root: &'b Option<CratePaths>,
344-
ident: Symbol,
345339
name: Symbol,
346-
hash: Option<&'b Svh>,
347-
extra_filename: Option<&'b str>,
348340
span: Span,
349-
path_kind: PathKind,
341+
dep_kind: DepKind,
342+
dep: Option<(&'b CratePaths, &'b CrateDep)>,
343+
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
344+
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
345+
}
346+
347+
fn maybe_resolve_crate<'b>(
348+
&'b mut self,
349+
name: Symbol,
350+
span: Span,
350351
mut dep_kind: DepKind,
352+
dep: Option<(&'b CratePaths, &'b CrateDep)>,
351353
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
352-
info!("resolving crate `extern crate {} as {}`", name, ident);
354+
info!("resolving crate `{}`", name);
355+
let (root, hash, extra_filename, path_kind) = match dep {
356+
Some((root, dep)) =>
357+
(Some(root), Some(&dep.hash), Some(&dep.extra_filename[..]), PathKind::Dependency),
358+
None => (None, None, None, PathKind::Crate),
359+
};
353360
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
354361
(LoadResult::Previous(cnum), None)
355362
} else {
356363
info!("falling back to a load");
357364
let mut locate_ctxt = locator::Context {
358365
sess: self.sess,
359366
span,
360-
ident,
361367
crate_name: name,
362368
hash,
363369
extra_filename,
@@ -393,7 +399,7 @@ impl<'a> CrateLoader<'a> {
393399
Ok((cnum, data))
394400
}
395401
(LoadResult::Loaded(library), host_library) => {
396-
Ok(self.register_crate(host_library, root, ident, span, library, dep_kind, name))
402+
Ok(self.register_crate(host_library, root, span, library, dep_kind, name))
397403
}
398404
_ => panic!()
399405
}
@@ -469,7 +475,7 @@ impl<'a> CrateLoader<'a> {
469475

470476
// Go through the crate metadata and load any crates that it references
471477
fn resolve_crate_deps(&mut self,
472-
root: &Option<CratePaths>,
478+
root: &CratePaths,
473479
crate_root: &CrateRoot<'_>,
474480
metadata: &MetadataBlob,
475481
krate: CrateNum,
@@ -484,9 +490,7 @@ impl<'a> CrateLoader<'a> {
484490
// The map from crate numbers in the crate we're resolving to local crate numbers.
485491
// We map 0 and all other holes in the map to our parent crate. The "additional"
486492
// self-dependencies should be harmless.
487-
std::iter::once(krate).chain(crate_root.crate_deps
488-
.decode(metadata)
489-
.map(|dep| {
493+
std::iter::once(krate).chain(crate_root.crate_deps.decode(metadata).map(|dep| {
490494
info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash,
491495
dep.extra_filename);
492496
if dep.kind == DepKind::UnexportedMacrosOnly {
@@ -496,32 +500,26 @@ impl<'a> CrateLoader<'a> {
496500
DepKind::MacrosOnly => DepKind::MacrosOnly,
497501
_ => dep.kind,
498502
};
499-
let (local_cnum, ..) = self.resolve_crate(
500-
root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
501-
PathKind::Dependency, dep_kind,
502-
).unwrap_or_else(|err| err.report());
503-
local_cnum
503+
self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0
504504
})).collect()
505505
}
506506

507-
fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
508-
-> ExtensionCrate {
509-
info!("read extension crate `extern crate {} as {}`", orig_name, rename);
507+
fn read_extension_crate(&mut self, name: Symbol, span: Span) -> ExtensionCrate {
508+
info!("read extension crate `{}`", name);
510509
let target_triple = self.sess.opts.target_triple.clone();
511510
let host_triple = TargetTriple::from_triple(config::host_triple());
512511
let is_cross = target_triple != host_triple;
513512
let mut target_only = false;
514513
let mut locate_ctxt = locator::Context {
515514
sess: self.sess,
516515
span,
517-
ident: orig_name,
518-
crate_name: rename,
516+
crate_name: name,
519517
hash: None,
520518
extra_filename: None,
521519
filesearch: self.sess.host_filesearch(PathKind::Crate),
522520
target: &self.sess.host,
523521
triple: host_triple,
524-
root: &None,
522+
root: None,
525523
rejected_via_hash: vec![],
526524
rejected_via_triple: vec![],
527525
rejected_via_kind: vec![],
@@ -570,25 +568,21 @@ impl<'a> CrateLoader<'a> {
570568
}
571569

572570
fn dlsym_proc_macros(&self,
573-
dylib: Option<PathBuf>,
574-
root: &CrateRoot<'_>,
571+
path: &Path,
572+
disambiguator: CrateDisambiguator,
575573
span: Span
576574
) -> &'static [ProcMacro] {
577575
use std::env;
578576
use crate::dynamic_lib::DynamicLibrary;
579577

580-
let path = match dylib {
581-
Some(dylib) => dylib,
582-
None => span_bug!(span, "proc-macro crate not dylib"),
583-
};
584578
// Make sure the path contains a / or the linker will search for it.
585579
let path = env::current_dir().unwrap().join(path);
586580
let lib = match DynamicLibrary::open(Some(&path)) {
587581
Ok(lib) => lib,
588582
Err(err) => self.sess.span_fatal(span, &err),
589583
};
590584

591-
let sym = self.sess.generate_proc_macro_decls_symbol(root.disambiguator);
585+
let sym = self.sess.generate_proc_macro_decls_symbol(disambiguator);
592586
let decls = unsafe {
593587
let sym = match lib.symbol(&sym) {
594588
Ok(f) => f,
@@ -610,7 +604,7 @@ impl<'a> CrateLoader<'a> {
610604
span: Span,
611605
name: Symbol)
612606
-> Option<(PathBuf, CrateDisambiguator)> {
613-
let ekrate = self.read_extension_crate(span, name, name);
607+
let ekrate = self.read_extension_crate(name, span);
614608

615609
if ekrate.target_only {
616610
// Need to abort before syntax expansion.
@@ -701,10 +695,7 @@ impl<'a> CrateLoader<'a> {
701695
};
702696
info!("panic runtime not found -- loading {}", name);
703697

704-
let dep_kind = DepKind::Implicit;
705-
let (cnum, data) =
706-
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind)
707-
.unwrap_or_else(|err| err.report());
698+
let (cnum, data) = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
708699

709700
// Sanity check the loaded crate to ensure it is indeed a panic runtime
710701
// and the panic strategy is indeed what we thought it was.
@@ -794,26 +785,21 @@ impl<'a> CrateLoader<'a> {
794785

795786
let mut uses_std = false;
796787
self.cstore.iter_crate_data(|_, data| {
797-
if data.name == sym::std {
788+
if data.root.name == sym::std {
798789
uses_std = true;
799790
}
800791
});
801792

802793
if uses_std {
803-
let name = match *sanitizer {
794+
let name = Symbol::intern(match sanitizer {
804795
Sanitizer::Address => "rustc_asan",
805796
Sanitizer::Leak => "rustc_lsan",
806797
Sanitizer::Memory => "rustc_msan",
807798
Sanitizer::Thread => "rustc_tsan",
808-
};
799+
});
809800
info!("loading sanitizer: {}", name);
810801

811-
let symbol = Symbol::intern(name);
812-
let dep_kind = DepKind::Explicit;
813-
let (_, data) =
814-
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
815-
PathKind::Crate, dep_kind)
816-
.unwrap_or_else(|err| err.report());
802+
let data = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None).1;
817803

818804
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
819805
if !data.root.sanitizer_runtime {
@@ -832,12 +818,8 @@ impl<'a> CrateLoader<'a> {
832818
{
833819
info!("loading profiler");
834820

835-
let symbol = Symbol::intern("profiler_builtins");
836-
let dep_kind = DepKind::Implicit;
837-
let (_, data) =
838-
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
839-
PathKind::Crate, dep_kind)
840-
.unwrap_or_else(|err| err.report());
821+
let name = Symbol::intern("profiler_builtins");
822+
let data = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None).1;
841823

842824
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
843825
if !data.root.profiler_runtime {
@@ -1004,7 +986,7 @@ impl<'a> CrateLoader<'a> {
1004986
ast::ItemKind::ExternCrate(orig_name) => {
1005987
debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
1006988
item.ident, orig_name);
1007-
let orig_name = match orig_name {
989+
let name = match orig_name {
1008990
Some(orig_name) => {
1009991
crate::validate_crate_name(Some(self.sess), &orig_name.as_str(),
1010992
Some(item.span));
@@ -1018,10 +1000,7 @@ impl<'a> CrateLoader<'a> {
10181000
DepKind::Explicit
10191001
};
10201002

1021-
let (cnum, ..) = self.resolve_crate(
1022-
&None, item.ident.name, orig_name, None, None,
1023-
item.span, PathKind::Crate, dep_kind,
1024-
).unwrap_or_else(|err| err.report());
1003+
let cnum = self.resolve_crate(name, item.span, dep_kind, None).0;
10251004

10261005
let def_id = definitions.opt_local_def_id(item.id).unwrap();
10271006
let path_len = definitions.def_path(def_id.index).data.len();
@@ -1047,9 +1026,7 @@ impl<'a> CrateLoader<'a> {
10471026
name: Symbol,
10481027
span: Span,
10491028
) -> CrateNum {
1050-
let cnum = self.resolve_crate(
1051-
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
1052-
).unwrap_or_else(|err| err.report()).0;
1029+
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0;
10531030

10541031
self.update_extern_crate(
10551032
cnum,
@@ -1071,9 +1048,7 @@ impl<'a> CrateLoader<'a> {
10711048
name: Symbol,
10721049
span: Span,
10731050
) -> Option<CrateNum> {
1074-
let cnum = self.resolve_crate(
1075-
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
1076-
).ok()?.0;
1051+
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0;
10771052

10781053
self.update_extern_crate(
10791054
cnum,

0 commit comments

Comments
 (0)