Skip to content

Commit 6388b91

Browse files
committed
Rollup merge of rust-lang#33602 - eddyb:no-trans--check, r=michaelwoerister
Save metadata even with -Z no-trans (e.g. for multi-crate cargo check). Removes the item symbol map in metadata, as we can now generate them in a deterministic manner. The `-Z no-trans` change lets the LLVM passes and linking run, but with just metadata and no code. It fails while trying to link a binary because there's no `main` function, which is correct but not good UX. There's also no way to easily throw away all of the artifacts to rebuild with actual code generation. We might want `cargo check` to do that using cargo-internal information and then it would just work. cc @alexcrichton @nikomatsakis @Aatch @michaelwoerister
2 parents 62ee403 + 07e8975 commit 6388b91

34 files changed

+565
-401
lines changed

src/librustc/middle/cstore.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ use mir::mir_map::MirMap;
3333
use session::Session;
3434
use session::config::PanicStrategy;
3535
use session::search_paths::PathKind;
36-
use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
36+
use util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
3737
use std::any::Any;
38-
use std::cell::RefCell;
3938
use std::rc::Rc;
4039
use std::path::PathBuf;
4140
use syntax::ast;
@@ -174,7 +173,6 @@ pub trait CrateStore<'tcx> : Any {
174173
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
175174
-> ty::GenericPredicates<'tcx>;
176175
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
177-
fn item_symbol(&self, def: DefId) -> String;
178176
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
179177
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
180178
fn method_arg_names(&self, did: DefId) -> Vec<String>;
@@ -210,6 +208,7 @@ pub trait CrateStore<'tcx> : Any {
210208
fn is_impl(&self, did: DefId) -> bool;
211209
fn is_default_impl(&self, impl_did: DefId) -> bool;
212210
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
211+
fn is_foreign_item(&self, did: DefId) -> bool;
213212
fn is_static_method(&self, did: DefId) -> bool;
214213
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
215214
fn is_typedef(&self, did: DefId) -> bool;
@@ -275,7 +274,6 @@ pub trait CrateStore<'tcx> : Any {
275274
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
276275
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
277276
reexports: &def::ExportMap,
278-
item_symbols: &RefCell<NodeMap<String>>,
279277
link_meta: &LinkMeta,
280278
reachable: &NodeSet,
281279
mir_map: &MirMap<'tcx>,
@@ -353,7 +351,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
353351
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
354352
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
355353
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
356-
fn item_symbol(&self, def: DefId) -> String { bug!("item_symbol") }
357354
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
358355
{ bug!("trait_def") }
359356
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
@@ -394,6 +391,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
394391
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
395392
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
396393
{ bug!("is_extern_item") }
394+
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
397395
fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
398396
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
399397
fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
@@ -476,7 +474,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
476474
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
477475
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
478476
reexports: &def::ExportMap,
479-
item_symbols: &RefCell<NodeMap<String>>,
480477
link_meta: &LinkMeta,
481478
reachable: &NodeSet,
482479
mir_map: &MirMap<'tcx>,

src/librustc/middle/dependency_format.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ fn calculate_type(sess: &session::Session,
115115
// got long ago), so don't bother with anything.
116116
config::CrateTypeRlib => return Vec::new(),
117117

118-
// Staticlibs must have all static dependencies. If any fail to be
119-
// found, we generate some nice pretty errors.
120-
config::CrateTypeStaticlib => {
118+
// Staticlibs and cdylibs must have all static dependencies. If any fail
119+
// to be found, we generate some nice pretty errors.
120+
config::CrateTypeStaticlib |
121+
config::CrateTypeCdylib => {
121122
match attempt_static(sess) {
122123
Some(v) => return v,
123124
None => {}

src/librustc/middle/reachable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
145145
// Creates a new reachability computation context.
146146
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ReachableContext<'a, 'tcx> {
147147
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
148-
*ty != config::CrateTypeExecutable
148+
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib
149149
});
150150
ReachableContext {
151151
tcx: tcx,

src/librustc/middle/weak_lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
7070
let needs_check = sess.crate_types.borrow().iter().any(|kind| {
7171
match *kind {
7272
config::CrateTypeDylib |
73+
config::CrateTypeCdylib |
7374
config::CrateTypeExecutable |
7475
config::CrateTypeStaticlib => true,
7576
config::CrateTypeRlib => false,

src/librustc/session/config.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ pub enum CrateType {
300300
CrateTypeDylib,
301301
CrateTypeRlib,
302302
CrateTypeStaticlib,
303+
CrateTypeCdylib,
303304
}
304305

305306
#[derive(Clone)]
@@ -1103,7 +1104,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
11031104
let no_analysis = debugging_opts.no_analysis;
11041105

11051106
let mut output_types = HashMap::new();
1106-
if !debugging_opts.parse_only && !no_trans {
1107+
if !debugging_opts.parse_only {
11071108
for list in matches.opt_strs("emit") {
11081109
for output_type in list.split(',') {
11091110
let mut parts = output_type.splitn(2, '=');
@@ -1326,6 +1327,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
13261327
"rlib" => CrateTypeRlib,
13271328
"staticlib" => CrateTypeStaticlib,
13281329
"dylib" => CrateTypeDylib,
1330+
"cdylib" => CrateTypeCdylib,
13291331
"bin" => CrateTypeExecutable,
13301332
_ => {
13311333
return Err(format!("unknown crate type: `{}`",
@@ -1413,7 +1415,8 @@ impl fmt::Display for CrateType {
14131415
CrateTypeExecutable => "bin".fmt(f),
14141416
CrateTypeDylib => "dylib".fmt(f),
14151417
CrateTypeRlib => "rlib".fmt(f),
1416-
CrateTypeStaticlib => "staticlib".fmt(f)
1418+
CrateTypeStaticlib => "staticlib".fmt(f),
1419+
CrateTypeCdylib => "cdylib".fmt(f),
14171420
}
14181421
}
14191422
}

src/librustc/session/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use hir::def_id::DefIndex;
12+
use hir::svh::Svh;
1113
use lint;
1214
use middle::cstore::CrateStore;
1315
use middle::dependency_format;
@@ -310,6 +312,14 @@ impl Session {
310312
pub fn nonzeroing_move_hints(&self) -> bool {
311313
self.opts.debugging_opts.enable_nonzeroing_move_hints
312314
}
315+
316+
/// Returns the symbol name for the registrar function,
317+
/// given the crate Svh and the function DefIndex.
318+
pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex)
319+
-> String {
320+
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
321+
}
322+
313323
pub fn sysroot<'a>(&'a self) -> &'a Path {
314324
match self.opts.maybe_sysroot {
315325
Some (ref sysroot) => sysroot,

src/librustc/ty/item_path.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
1414
use ty::{self, Ty, TyCtxt};
1515
use syntax::ast;
1616

17+
use std::cell::Cell;
18+
19+
thread_local! {
20+
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false)
21+
}
22+
23+
/// Enforces that item_path_str always returns an absolute path.
24+
/// This is useful when building symbols that contain types,
25+
/// where we want the crate name to be part of the symbol.
26+
pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
27+
FORCE_ABSOLUTE.with(|force| {
28+
let old = force.get();
29+
force.set(true);
30+
let result = f();
31+
force.set(old);
32+
result
33+
})
34+
}
35+
1736
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1837
/// Returns a string identifying this def-id. This string is
1938
/// suitable for user output. It is relative to the current crate
20-
/// root.
39+
/// root, unless with_forced_absolute_paths was used.
2140
pub fn item_path_str(self, def_id: DefId) -> String {
22-
let mut buffer = LocalPathBuffer::new(RootMode::Local);
41+
let mode = FORCE_ABSOLUTE.with(|force| {
42+
if force.get() {
43+
RootMode::Absolute
44+
} else {
45+
RootMode::Local
46+
}
47+
});
48+
let mut buffer = LocalPathBuffer::new(mode);
2349
self.push_item_path(&mut buffer, def_id);
2450
buffer.into_string()
2551
}
@@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
75101
RootMode::Absolute => {
76102
// In absolute mode, just write the crate name
77103
// unconditionally.
78-
buffer.push(&self.crate_name(cnum));
104+
if cnum == LOCAL_CRATE {
105+
buffer.push(&self.crate_name(cnum));
106+
} else {
107+
buffer.push(&self.sess.cstore.original_crate_name(cnum));
108+
}
79109
}
80110
}
81111
}

src/librustc_driver/driver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
11751175
Some(ref n) if *n == "dylib" => {
11761176
Some(config::CrateTypeDylib)
11771177
}
1178+
Some(ref n) if *n == "cdylib" => {
1179+
Some(config::CrateTypeCdylib)
1180+
}
11781181
Some(ref n) if *n == "lib" => {
11791182
Some(config::default_lib_output())
11801183
}

src/librustc_driver/lib.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -504,10 +504,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
504504
control.after_write_deps.stop = Compilation::Stop;
505505
}
506506

507-
if sess.opts.no_trans {
508-
control.after_analysis.stop = Compilation::Stop;
509-
}
510-
511507
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
512508
control.after_llvm.stop = Compilation::Stop;
513509
}

src/librustc_metadata/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub const tag_items_data_item_family: usize = 0x24;
3333

3434
pub const tag_items_data_item_type: usize = 0x25;
3535

36-
pub const tag_items_data_item_symbol: usize = 0x26;
36+
// GAP 0x26
3737

3838
pub const tag_items_data_item_variant: usize = 0x27;
3939

src/librustc_metadata/creader.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
1717
use decoder;
1818
use loader::{self, CratePaths};
1919

20+
use rustc::hir::def_id::DefIndex;
2021
use rustc::hir::svh::Svh;
2122
use rustc::dep_graph::{DepGraph, DepNode};
2223
use rustc::session::{config, Session};
@@ -578,9 +579,10 @@ impl<'a> CrateReader<'a> {
578579
macros
579580
}
580581

581-
/// Look for a plugin registrar. Returns library path and symbol name.
582+
/// Look for a plugin registrar. Returns library path, crate
583+
/// SVH and DefIndex of the registrar function.
582584
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
583-
-> Option<(PathBuf, String)> {
585+
-> Option<(PathBuf, Svh, DefIndex)> {
584586
let ekrate = self.read_extension_crate(span, &CrateInfo {
585587
name: name.to_string(),
586588
ident: name.to_string(),
@@ -598,12 +600,14 @@ impl<'a> CrateReader<'a> {
598600
span_fatal!(self.sess, span, E0456, "{}", &message[..]);
599601
}
600602

603+
let svh = decoder::get_crate_hash(ekrate.metadata.as_slice());
601604
let registrar =
602-
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
603-
.map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
605+
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice());
604606

605607
match (ekrate.dylib.as_ref(), registrar) {
606-
(Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
608+
(Some(dylib), Some(reg)) => {
609+
Some((dylib.to_path_buf(), svh, reg))
610+
}
607611
(None, Some(_)) => {
608612
span_err!(self.sess, span, E0457,
609613
"plugin `{}` only found in rlib format, but must be available \
@@ -743,6 +747,7 @@ impl<'a> CrateReader<'a> {
743747
match *ct {
744748
config::CrateTypeExecutable => need_exe_alloc = true,
745749
config::CrateTypeDylib |
750+
config::CrateTypeCdylib |
746751
config::CrateTypeStaticlib => need_lib_alloc = true,
747752
config::CrateTypeRlib => {}
748753
}

src/librustc_metadata/csearch.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
2323
use rustc::hir::map as hir_map;
2424
use rustc::mir::repr::Mir;
2525
use rustc::mir::mir_map::MirMap;
26-
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
26+
use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
2727
use rustc::session::config::PanicStrategy;
2828

2929
use std::cell::RefCell;
@@ -105,12 +105,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
105105
decoder::get_item_attrs(&cdata, def_id.index)
106106
}
107107

108-
fn item_symbol(&self, def: DefId) -> String
109-
{
110-
let cdata = self.get_crate_data(def.krate);
111-
decoder::get_symbol(&cdata, def.index)
112-
}
113-
114108
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
115109
{
116110
let cdata = self.get_crate_data(def.krate);
@@ -252,6 +246,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
252246
decoder::is_extern_item(&cdata, did.index, tcx)
253247
}
254248

249+
fn is_foreign_item(&self, did: DefId) -> bool {
250+
let cdata = self.get_crate_data(did.krate);
251+
decoder::is_foreign_item(&cdata, did.index)
252+
}
253+
255254
fn is_static_method(&self, def: DefId) -> bool
256255
{
257256
let cdata = self.get_crate_data(def.krate);
@@ -512,7 +511,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
512511

513512
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
514513
reexports: &def::ExportMap,
515-
item_symbols: &RefCell<NodeMap<String>>,
516514
link_meta: &LinkMeta,
517515
reachable: &NodeSet,
518516
mir_map: &MirMap<'tcx>,
@@ -522,7 +520,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
522520
diag: tcx.sess.diagnostic(),
523521
tcx: tcx,
524522
reexports: reexports,
525-
item_symbols: item_symbols,
526523
link_meta: link_meta,
527524
cstore: self,
528525
reachable: reachable,

src/librustc_metadata/decoder.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,6 @@ fn item_sort(item: rbml::Doc) -> Option<char> {
186186
})
187187
}
188188

189-
fn item_symbol(item: rbml::Doc) -> String {
190-
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
191-
}
192-
193189
fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
194190
let id = reader::doc_as_u64(d);
195191
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
@@ -609,18 +605,6 @@ pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd,
609605
}
610606
}
611607

612-
pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
613-
return item_symbol(cdata.lookup_item(id));
614-
}
615-
616-
/// If you have a crate_metadata, call get_symbol instead
617-
pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
618-
let index = load_index(data);
619-
let pos = index.lookup_item(data, id).unwrap();
620-
let doc = reader::doc_at(data, pos as usize).unwrap().doc;
621-
item_symbol(doc)
622-
}
623-
624608
/// Iterates over the language items in the given crate.
625609
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
626610
F: FnMut(DefIndex, usize) -> bool,
@@ -1611,6 +1595,16 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
16111595
}
16121596
}
16131597

1598+
pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
1599+
let item_doc = cdata.lookup_item(id);
1600+
let parent_item_id = match item_parent_item(cdata, item_doc) {
1601+
None => return false,
1602+
Some(item_id) => item_id,
1603+
};
1604+
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
1605+
item_family(parent_item_doc) == ForeignMod
1606+
}
1607+
16141608
pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
16151609
let item_doc = cdata.lookup_item(id);
16161610
match item_family(item_doc) {

0 commit comments

Comments
 (0)