Skip to content

Commit

Permalink
Auto merge of #33602 - eddyb:no-trans--check, r=michaelwoerister
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed May 25, 2016
2 parents 487de42 + a619901 commit 5229e0e
Show file tree
Hide file tree
Showing 24 changed files with 371 additions and 350 deletions.
9 changes: 3 additions & 6 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ use mir::mir_map::MirMap;
use session::Session;
use session::config::PanicStrategy;
use session::search_paths::PathKind;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
use std::cell::RefCell;
use util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
use std::rc::Rc;
use std::path::PathBuf;
use syntax::ast;
Expand Down Expand Up @@ -169,7 +168,6 @@ pub trait CrateStore<'tcx> {
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx>;
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
fn item_symbol(&self, def: DefId) -> String;
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
fn method_arg_names(&self, did: DefId) -> Vec<String>;
Expand Down Expand Up @@ -205,6 +203,7 @@ pub trait CrateStore<'tcx> {
fn is_impl(&self, did: DefId) -> bool;
fn is_default_impl(&self, impl_did: DefId) -> bool;
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
fn is_foreign_item(&self, did: DefId) -> bool;
fn is_static_method(&self, did: DefId) -> bool;
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
fn is_typedef(&self, did: DefId) -> bool;
Expand Down Expand Up @@ -274,7 +273,6 @@ pub trait CrateStore<'tcx> {
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>,
Expand Down Expand Up @@ -352,7 +350,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
fn item_symbol(&self, def: DefId) -> String { bug!("item_symbol") }
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
{ bug!("trait_def") }
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
Expand Down Expand Up @@ -399,6 +396,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
{ bug!("is_extern_item") }
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
Expand Down Expand Up @@ -481,7 +479,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let no_analysis = debugging_opts.no_analysis;

let mut output_types = HashMap::new();
if !debugging_opts.parse_only && !no_trans {
if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") {
for output_type in list.split(',') {
let mut parts = output_type.splitn(2, '=');
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// except according to those terms.

use dep_graph::DepGraph;
use hir::def_id::DefIndex;
use hir::svh::Svh;
use lint;
use middle::cstore::CrateStore;
use middle::dependency_format;
Expand Down Expand Up @@ -312,6 +314,14 @@ impl Session {
pub fn nonzeroing_move_hints(&self) -> bool {
self.opts.debugging_opts.enable_nonzeroing_move_hints
}

/// Returns the symbol name for the registrar function,
/// given the crate Svh and the function DefIndex.
pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex)
-> String {
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
}

pub fn sysroot<'a>(&'a self) -> &'a Path {
match self.opts.maybe_sysroot {
Some (ref sysroot) => sysroot,
Expand Down
36 changes: 33 additions & 3 deletions src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
use ty::{self, Ty, TyCtxt};
use syntax::ast;

use std::cell::Cell;

thread_local! {
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false)
}

/// Enforces that item_path_str always returns an absolute path.
/// This is useful when building symbols that contain types,
/// where we want the crate name to be part of the symbol.
pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
FORCE_ABSOLUTE.with(|force| {
let old = force.get();
force.set(true);
let result = f();
force.set(old);
result
})
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Returns a string identifying this def-id. This string is
/// suitable for user output. It is relative to the current crate
/// root.
/// root, unless with_forced_absolute_paths was used.
pub fn item_path_str(self, def_id: DefId) -> String {
let mut buffer = LocalPathBuffer::new(RootMode::Local);
let mode = FORCE_ABSOLUTE.with(|force| {
if force.get() {
RootMode::Absolute
} else {
RootMode::Local
}
});
let mut buffer = LocalPathBuffer::new(mode);
self.push_item_path(&mut buffer, def_id);
buffer.into_string()
}
Expand Down Expand Up @@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
RootMode::Absolute => {
// In absolute mode, just write the crate name
// unconditionally.
buffer.push(&self.crate_name(cnum));
if cnum == LOCAL_CRATE {
buffer.push(&self.crate_name(cnum));
} else {
buffer.push(&self.sess.cstore.original_crate_name(cnum));
}
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
control.after_write_deps.stop = Compilation::Stop;
}

if sess.opts.no_trans {
control.after_analysis.stop = Compilation::Stop;
}

if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
control.after_llvm.stop = Compilation::Stop;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub const tag_items_data_item_family: usize = 0x24;

pub const tag_items_data_item_type: usize = 0x25;

pub const tag_items_data_item_symbol: usize = 0x26;
// GAP 0x26

pub const tag_items_data_item_variant: usize = 0x27;

Expand Down
14 changes: 9 additions & 5 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
use decoder;
use loader::{self, CratePaths};

use rustc::hir::def_id::DefIndex;
use rustc::hir::svh::Svh;
use rustc::dep_graph::{DepGraph, DepNode};
use rustc::session::{config, Session};
Expand Down Expand Up @@ -610,9 +611,10 @@ impl<'a> CrateReader<'a> {
macros
}

/// Look for a plugin registrar. Returns library path and symbol name.
/// Look for a plugin registrar. Returns library path, crate
/// SVH and DefIndex of the registrar function.
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
-> Option<(PathBuf, String)> {
-> Option<(PathBuf, Svh, DefIndex)> {
let ekrate = self.read_extension_crate(span, &CrateInfo {
name: name.to_string(),
ident: name.to_string(),
Expand All @@ -630,12 +632,14 @@ impl<'a> CrateReader<'a> {
span_fatal!(self.sess, span, E0456, "{}", &message[..]);
}

let svh = decoder::get_crate_hash(ekrate.metadata.as_slice());
let registrar =
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
.map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice());

match (ekrate.dylib.as_ref(), registrar) {
(Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
(Some(dylib), Some(reg)) => {
Some((dylib.to_path_buf(), svh, reg))
}
(None, Some(_)) => {
span_err!(self.sess, span, E0457,
"plugin `{}` only found in rlib format, but must be available \
Expand Down
16 changes: 6 additions & 10 deletions src/librustc_metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc::hir::map as hir_map;
use rustc::hir::map::DefKey;
use rustc::mir::repr::Mir;
use rustc::mir::mir_map::MirMap;
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
use rustc::session::config::PanicStrategy;

use std::cell::RefCell;
Expand Down Expand Up @@ -115,13 +115,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::get_item_attrs(&cdata, def_id.index)
}

fn item_symbol(&self, def: DefId) -> String
{
self.dep_graph.read(DepNode::MetaData(def));
let cdata = self.get_crate_data(def.krate);
decoder::get_symbol(&cdata, def.index)
}

fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
{
self.dep_graph.read(DepNode::MetaData(def));
Expand Down Expand Up @@ -284,6 +277,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::is_extern_item(&cdata, did.index, tcx)
}

fn is_foreign_item(&self, did: DefId) -> bool {
let cdata = self.get_crate_data(did.krate);
decoder::is_foreign_item(&cdata, did.index)
}

fn is_static_method(&self, def: DefId) -> bool
{
self.dep_graph.read(DepNode::MetaData(def));
Expand Down Expand Up @@ -564,7 +562,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {

fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>,
Expand All @@ -574,7 +571,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
diag: tcx.sess.diagnostic(),
tcx: tcx,
reexports: reexports,
item_symbols: item_symbols,
link_meta: link_meta,
cstore: self,
reachable: reachable,
Expand Down
26 changes: 10 additions & 16 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,6 @@ fn item_sort(item: rbml::Doc) -> Option<char> {
})
}

fn item_symbol(item: rbml::Doc) -> String {
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
}

fn untranslated_def_id(d: rbml::Doc) -> DefId {
let id = reader::doc_as_u64(d);
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
Expand Down Expand Up @@ -640,18 +636,6 @@ pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd,
}
}

pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
return item_symbol(cdata.lookup_item(id));
}

/// If you have a crate_metadata, call get_symbol instead
pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
let index = load_index(data);
let pos = index.lookup_item(data, id).unwrap();
let doc = reader::doc_at(data, pos as usize).unwrap().doc;
item_symbol(doc)
}

/// Iterates over the language items in the given crate.
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
F: FnMut(DefIndex, usize) -> bool,
Expand Down Expand Up @@ -1642,6 +1626,16 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
}
}

pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
let item_doc = cdata.lookup_item(id);
let parent_item_id = match item_parent_item(cdata, item_doc) {
None => return false,
Some(item_id) => item_id,
};
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
item_family(parent_item_doc) == ForeignMod
}

pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
let item_doc = cdata.lookup_item(id);
match item_family(item_doc) {
Expand Down
Loading

0 comments on commit 5229e0e

Please sign in to comment.