Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save metadata even with -Z no-trans (e.g. for multi-crate cargo check). #33602

Merged
merged 8 commits into from
May 25, 2016
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