提交 ffee9566 编写于 作者: A Ariel Ben-Yehuda

move Instance to rustc and use it in the collector

上级 0af3775d
......@@ -89,6 +89,7 @@ pub enum DepNode<D: Clone + Debug> {
// things read/modify that MIR.
MirKrate,
Mir(D),
MirShim(Vec<D>),
BorrowCheckKrate,
BorrowCheck(D),
......@@ -258,6 +259,10 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
MatchCheck(ref d) => op(d).map(MatchCheck),
Mir(ref d) => op(d).map(Mir),
MirShim(ref def_ids) => {
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
def_ids.map(MirShim)
}
BorrowCheck(ref d) => op(d).map(BorrowCheck),
RvalueCheck(ref d) => op(d).map(RvalueCheck),
StabilityCheck(ref d) => op(d).map(StabilityCheck),
......
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use dep_graph::DepNode;
use hir::def_id::DefId;
use ty::{self, Ty, TypeFoldable, Substs};
use util::ppaux;
use std::borrow::Cow;
use std::fmt;
use syntax::ast;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Instance<'tcx> {
pub def: InstanceDef<'tcx>,
pub substs: &'tcx Substs<'tcx>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum InstanceDef<'tcx> {
Item(DefId),
// <fn() as FnTrait>::call_*
FnPtrShim(DefId, Ty<'tcx>),
}
impl<'tcx> InstanceDef<'tcx> {
#[inline]
pub fn def_id(&self) -> DefId {
match *self {
InstanceDef::Item(def_id) |
InstanceDef::FnPtrShim(def_id, _)
=> def_id
}
}
#[inline]
pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
tcx.item_type(self.def_id())
}
#[inline]
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
tcx.get_attrs(self.def_id())
}
pub(crate) fn dep_node(&self) -> DepNode<DefId> {
// HACK: def-id binning, project-style; someone replace this with
// real on-demand.
let ty = match self {
&InstanceDef::FnPtrShim(_, ty) => Some(ty),
_ => None
}.into_iter();
DepNode::MirShim(
Some(self.def_id()).into_iter().chain(
ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
ty::TyAdt(adt_def, _) => Some(adt_def.did),
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
_ => None,
})
).collect()
)
}
}
impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.def {
InstanceDef::Item(def) => {
ppaux::parameterized(f, self.substs, def, &[])
}
InstanceDef::FnPtrShim(def, ty) => {
ppaux::parameterized(f, self.substs, def, &[])?;
write!(f, " - shim({:?})", ty)
}
}
}
}
impl<'a, 'b, 'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
-> Instance<'tcx> {
assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
"substs of instance {:?} not normalized for trans: {:?}",
def_id, substs);
Instance { def: InstanceDef::Item(def_id), substs: substs }
}
pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
}
#[inline]
pub fn def_id(&self) -> DefId {
self.def.def_id()
}
}
......@@ -9,7 +9,7 @@
// except according to those terms.
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
use hir::def_id::{CrateNum, DefId};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use middle::const_val::ConstVal;
use mir;
use ty::{self, Ty, TyCtxt};
......@@ -24,6 +24,16 @@ trait Key {
fn default_span(&self, tcx: TyCtxt) -> Span;
}
impl<'tcx> Key for ty::InstanceDef<'tcx> {
fn map_crate(&self) -> CrateNum {
LOCAL_CRATE
}
fn default_span(&self, tcx: TyCtxt) -> Span {
tcx.def_span(self.def_id())
}
}
impl Key for CrateNum {
fn map_crate(&self) -> CrateNum {
*self
......@@ -83,9 +93,9 @@ fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
}
}
pub struct CycleError<'a> {
pub struct CycleError<'a, 'tcx: 'a> {
span: Span,
cycle: RefMut<'a, [(Span, Query)]>,
cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
......@@ -110,8 +120,8 @@ pub fn report_cycle(self, CycleError { span, cycle }: CycleError) {
err.emit();
}
fn cycle_check<F, R>(self, span: Span, query: Query, compute: F)
-> Result<R, CycleError<'a>>
fn cycle_check<F, R>(self, span: Span, query: Query<'gcx>, compute: F)
-> Result<R, CycleError<'a, 'gcx>>
where F: FnOnce() -> R
{
{
......@@ -172,13 +182,20 @@ fn describe(_: TyCtxt, _: CrateNum) -> String {
}
}
impl<'tcx> QueryDescription for queries::mir_shims<'tcx> {
fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
format!("generating MIR shim for `{}`",
tcx.item_path_str(def.def_id()))
}
}
macro_rules! define_maps {
(<$tcx:tt>
$($(#[$attr:meta])*
pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => {
pub struct Maps<$tcx> {
providers: IndexVec<CrateNum, Providers<$tcx>>,
query_stack: RefCell<Vec<(Span, Query)>>,
query_stack: RefCell<Vec<(Span, Query<$tcx>)>>,
$($(#[$attr])* pub $name: RefCell<DepTrackingMap<queries::$name<$tcx>>>),*
}
......@@ -196,11 +213,11 @@ pub fn new(dep_graph: DepGraph,
#[allow(bad_style)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Query {
pub enum Query<$tcx> {
$($(#[$attr])* $name($K)),*
}
impl Query {
impl<$tcx> Query<$tcx> {
pub fn describe(&self, tcx: TyCtxt) -> String {
match *self {
$(Query::$name(key) => queries::$name::describe(tcx, key)),*
......@@ -233,7 +250,7 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
mut span: Span,
key: $K,
f: F)
-> Result<R, CycleError<'a>>
-> Result<R, CycleError<'a, $tcx>>
where F: FnOnce(&$V) -> R
{
if let Some(result) = tcx.maps.$name.borrow().get(&key) {
......@@ -256,7 +273,7 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
}
pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
-> Result<$V, CycleError<'a>> {
-> Result<$V, CycleError<'a, $tcx>> {
Self::try_get_with(tcx, span, key, Clone::clone)
}
......@@ -387,7 +404,9 @@ fn default() -> Self {
/// Results of evaluating monomorphic constants embedded in
/// other items, such as enum variant explicit discriminants.
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
}
fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
......@@ -397,3 +416,7 @@ fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
fn coherent_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
DepNode::Coherence
}
fn mir_shim(instance: ty::InstanceDef) -> DepNode<DefId> {
instance.dep_node()
}
......@@ -73,6 +73,8 @@
pub use self::context::{TyCtxt, GlobalArenas, tls};
pub use self::context::{Lift, TypeckTables};
pub use self::instance::{Instance, InstanceDef};
pub use self::trait_def::{TraitDef, TraitFlags};
pub use self::maps::queries;
......@@ -98,6 +100,7 @@
mod contents;
mod context;
mod flags;
mod instance;
mod structural_impls;
mod sty;
......@@ -2309,6 +2312,16 @@ pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
queries::mir::get(self, DUMMY_SP, did).borrow()
}
/// Return the possibly-auto-generated MIR of a (DefId, Subst) pair.
pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
-> Ref<'gcx, Mir<'gcx>>
{
match instance {
ty::InstanceDef::Item(did) if true => self.item_mir(did),
_ => queries::mir_shims::get(self, DUMMY_SP, instance).borrow(),
}
}
/// Given the DefId of an item, returns its MIR, borrowed immutably.
/// Returns None if there is no MIR for the DefId
pub fn maybe_item_mir(self, did: DefId) -> Option<Ref<'gcx, Mir<'gcx>>> {
......
......@@ -398,6 +398,18 @@ pub fn closure_base_def_id(&self, def_id: DefId) -> DefId {
}
def_id
}
/// Given the def-id of some item that has no type parameters, make
/// a suitable "empty substs" for it.
pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> &'tcx ty::Substs<'tcx> {
ty::Substs::for_item(self, item_def_id,
|_, _| self.mk_region(ty::ReErased),
|_, _| {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}
}
pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
......
......@@ -60,5 +60,6 @@
pub fn provide(providers: &mut Providers) {
mir_map::provide(providers);
shim::provide(providers);
transform::qualify_consts::provide(providers);
}
\ No newline at end of file
......@@ -13,14 +13,31 @@
use rustc::mir::*;
use rustc::mir::transform::MirSource;
use rustc::ty;
use rustc::ty::maps::Providers;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use syntax::ast;
use syntax_pos::Span;
use std::cell::RefCell;
use std::iter;
pub fn provide(providers: &mut Providers) {
providers.mir_shims = make_shim;
}
fn make_shim<'a, 'tcx>(_tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
instance: ty::InstanceDef<'tcx>)
-> &'tcx RefCell<Mir<'tcx>>
{
match instance {
ty::InstanceDef::Item(..) =>
bug!("item {:?} passed to make_shim", instance),
ty::InstanceDef::FnPtrShim(..) => unimplemented!()
}
}
fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>)
-> IndexVec<Local, LocalDecl<'tcx>>
{
......
......@@ -11,6 +11,7 @@
use context::SharedCrateContext;
use monomorphize::Instance;
use symbol_map::SymbolMap;
use back::symbol_names::symbol_name;
use util::nodemap::FxHashMap;
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use rustc::session::config;
......@@ -106,7 +107,7 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
.exported_symbols(cnum)
.iter()
.map(|&def_id| {
let name = Instance::mono(scx, def_id).symbol_name(scx);
let name = symbol_name(Instance::mono(scx.tcx(), def_id), scx);
let export_level = if special_runtime_crate {
// We can probably do better here by just ensuring that
// it has hidden visibility rather than public
......@@ -218,9 +219,9 @@ fn symbol_for_def_id<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
}
}
let instance = Instance::mono(scx, def_id);
let instance = Instance::mono(scx.tcx(), def_id);
symbol_map.get(TransItem::Fn(instance))
.map(str::to_owned)
.unwrap_or_else(|| instance.symbol_name(scx))
.unwrap_or_else(|| symbol_name(instance, scx))
}
......@@ -168,105 +168,105 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
format!("h{:016x}", hasher.finish())
}
impl<'a, 'tcx> Instance<'tcx> {
pub fn symbol_name(self, scx: &SharedCrateContext<'a, 'tcx>) -> String {
let Instance { def: def_id, substs } = self;
pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
scx: &SharedCrateContext<'a, 'tcx>) -> String {
let def_id = instance.def_id();
let substs = instance.substs;
debug!("symbol_name(def_id={:?}, substs={:?})",
def_id, substs);
debug!("symbol_name(def_id={:?}, substs={:?})",
def_id, substs);
let node_id = scx.tcx().hir.as_local_node_id(def_id);
let node_id = scx.tcx().hir.as_local_node_id(def_id);
if let Some(id) = node_id {
if scx.sess().plugin_registrar_fn.get() == Some(id) {
let svh = &scx.link_meta().crate_hash;
let idx = def_id.index;
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
}
if scx.sess().derive_registrar_fn.get() == Some(id) {
let svh = &scx.link_meta().crate_hash;
let idx = def_id.index;
return scx.sess().generate_derive_registrar_symbol(svh, idx);
}
if let Some(id) = node_id {
if scx.sess().plugin_registrar_fn.get() == Some(id) {
let svh = &scx.link_meta().crate_hash;
let idx = def_id.index;
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
}
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
let attrs = scx.tcx().get_attrs(def_id);
let is_foreign = if let Some(id) = node_id {
match scx.tcx().hir.get(id) {
hir_map::NodeForeignItem(_) => true,
_ => false
}
} else {
scx.sess().cstore.is_foreign_item(def_id)
};
if let Some(name) = weak_lang_items::link_name(&attrs) {
return name.to_string();
if scx.sess().derive_registrar_fn.get() == Some(id) {
let svh = &scx.link_meta().crate_hash;
let idx = def_id.index;
return scx.sess().generate_derive_registrar_symbol(svh, idx);
}
}
if is_foreign {
if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "link_name") {
return name.to_string();
}
// Don't mangle foreign items.
return scx.tcx().item_name(def_id).as_str().to_string();
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
let attrs = scx.tcx().get_attrs(def_id);
let is_foreign = if let Some(id) = node_id {
match scx.tcx().hir.get(id) {
hir_map::NodeForeignItem(_) => true,
_ => false
}
} else {
scx.sess().cstore.is_foreign_item(def_id)
};
if let Some(name) = attr::find_export_name_attr(scx.sess().diagnostic(), &attrs) {
// Use provided name
if let Some(name) = weak_lang_items::link_name(&attrs) {
return name.to_string();
}
if is_foreign {
if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "link_name") {
return name.to_string();
}
// Don't mangle foreign items.
return scx.tcx().item_name(def_id).as_str().to_string();
}
if attr::contains_name(&attrs, "no_mangle") {
// Don't mangle
return scx.tcx().item_name(def_id).as_str().to_string();
}
if let Some(name) = attr::find_export_name_attr(scx.sess().diagnostic(), &attrs) {
// Use provided name
return name.to_string();
}
let def_path = scx.tcx().def_path(def_id);
// We want to compute the "type" of this item. Unfortunately, some
// kinds of items (e.g., closures) don't have an entry in the
// item-type array. So walk back up the find the closest parent
// that DOES have an entry.
let mut ty_def_id = def_id;
let instance_ty;
loop {
let key = scx.tcx().def_key(ty_def_id);
match key.disambiguated_data.data {
DefPathData::TypeNs(_) |
DefPathData::ValueNs(_) => {
instance_ty = scx.tcx().item_type(ty_def_id);
break;
}
_ => {
// if we're making a symbol for something, there ought
// to be a value or type-def or something in there
// *somewhere*
ty_def_id.index = key.parent.unwrap_or_else(|| {
bug!("finding type for {:?}, encountered def-id {:?} with no \
parent", def_id, ty_def_id);
});
}
if attr::contains_name(&attrs, "no_mangle") {
// Don't mangle
return scx.tcx().item_name(def_id).as_str().to_string();
}
let def_path = scx.tcx().def_path(def_id);
// We want to compute the "type" of this item. Unfortunately, some
// kinds of items (e.g., closures) don't have an entry in the
// item-type array. So walk back up the find the closest parent
// that DOES have an entry.
let mut ty_def_id = def_id;
let instance_ty;
loop {
let key = scx.tcx().def_key(ty_def_id);
match key.disambiguated_data.data {
DefPathData::TypeNs(_) |
DefPathData::ValueNs(_) => {
instance_ty = scx.tcx().item_type(ty_def_id);
break;
}
_ => {
// if we're making a symbol for something, there ought
// to be a value or type-def or something in there
// *somewhere*
ty_def_id.index = key.parent.unwrap_or_else(|| {
bug!("finding type for {:?}, encountered def-id {:?} with no \
parent", def_id, ty_def_id);
});
}
}
}
// Erase regions because they may not be deterministic when hashed
// and should not matter anyhow.
let instance_ty = scx.tcx().erase_regions(&instance_ty);
// Erase regions because they may not be deterministic when hashed
// and should not matter anyhow.
let instance_ty = scx.tcx().erase_regions(&instance_ty);
let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs));
let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs));
let mut buffer = SymbolPathBuffer {
names: Vec::with_capacity(def_path.data.len())
};
let mut buffer = SymbolPathBuffer {
names: Vec::with_capacity(def_path.data.len())
};
item_path::with_forced_absolute_paths(|| {
scx.tcx().push_item_path(&mut buffer, def_id);
});
item_path::with_forced_absolute_paths(|| {
scx.tcx().push_item_path(&mut buffer, def_id);
});
mangle(buffer.names.into_iter(), &hash)
}
mangle(buffer.names.into_iter(), &hash)
}
struct SymbolPathBuffer {
......
......@@ -565,11 +565,11 @@ pub fn memcpy_ty<'a, 'tcx>(
}
pub fn call_memset<'a, 'tcx>(b: &Builder<'a, 'tcx>,
ptr: ValueRef,
fill_byte: ValueRef,
size: ValueRef,
align: ValueRef,
volatile: bool) -> ValueRef {
ptr: ValueRef,
fill_byte: ValueRef,
size: ValueRef,
align: ValueRef,
volatile: bool) -> ValueRef {
let ptr_width = &b.ccx.sess().target.target.target_pointer_width[..];
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
let llintrinsicfn = b.ccx.get_intrinsic(&intrinsic_key);
......@@ -581,7 +581,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
let _s = if ccx.sess().trans_stats() {
let mut instance_name = String::new();
DefPathBasedNames::new(ccx.tcx(), true, true)
.push_def_path(instance.def, &mut instance_name);
.push_def_path(instance.def_id(), &mut instance_name);
Some(StatRecorder::new(ccx, instance_name))
} else {
None
......@@ -592,7 +592,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
// release builds.
info!("trans_instance({})", instance);
let fn_ty = common::def_ty(ccx.shared(), instance.def, instance.substs);
let fn_ty = common::instance_ty(ccx.shared(), &instance);
let sig = common::ty_fn_sig(ccx, fn_ty);
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);
......@@ -607,7 +607,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
attributes::emit_uwtable(lldecl, true);
}
let mir = ccx.tcx().item_mir(instance.def);
let mir = ccx.tcx().instance_mir(instance.def);
mir::trans_mir(ccx, lldecl, &mir, instance, sig);
}
......@@ -668,7 +668,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
ccx.tcx().sess.span_fatal(span, "compilation successful");
}
let instance = Instance::mono(ccx.shared(), main_def_id);
let instance = Instance::mono(ccx.tcx(), main_def_id);
if !ccx.codegen_unit().contains_item(&TransItem::Fn(instance)) {
// We want to create the wrapper in the same codegen unit as Rust's main
......
......@@ -27,11 +27,12 @@
use cleanup::CleanupScope;
use mir::lvalue::LvalueRef;
use consts;
use common::def_ty;
use common::instance_ty;
use declare;
use value::Value;
use meth;
use monomorphize::Instance;
use back::symbol_names::symbol_name;
use trans_item::TransItem;
use type_of;
use rustc::ty::{self, Ty, TypeFoldable};
......@@ -77,7 +78,8 @@ pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs
return Callee::trait_method(ccx, trait_id, def_id, substs);
}
let fn_ty = def_ty(ccx.shared(), def_id, substs);
let instance = ty::Instance::new(def_id, substs);
let fn_ty = instance_ty(ccx.shared(), &instance);
if let ty::TyFnDef(.., f) = fn_ty.sty {
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
return Callee {
......@@ -87,7 +89,7 @@ pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs
}
}
let (llfn, ty) = get_fn(ccx, def_id, substs);
let (llfn, ty) = get_fn(ccx, instance);
Callee::ptr(llfn, ty)
}
......@@ -104,13 +106,13 @@ pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) {
traits::VtableImpl(vtable_impl) => {
let name = tcx.item_name(def_id);
let (def_id, substs) = traits::find_method(tcx, name, substs, &vtable_impl);
let instance = common::find_method(tcx, name, substs, &vtable_impl);
// Translate the function, bypassing Callee::def.
// That is because default methods have the same ID as the
// trait method used to look up the impl method that ended
// up here, so calling Callee::def would infinitely recurse.
let (llfn, ty) = get_fn(ccx, def_id, substs);
let (llfn, ty) = get_fn(ccx, instance);
Callee::ptr(llfn, ty)
}
traits::VtableClosure(vtable_closure) => {
......@@ -125,7 +127,7 @@ pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
instance,
trait_closure_kind);
let method_ty = def_ty(ccx.shared(), def_id, substs);
let method_ty = instance_ty(ccx.shared(), &instance);
Callee::ptr(llfn, method_ty)
}
traits::VtableFnPointer(vtable_fn_pointer) => {
......@@ -135,13 +137,13 @@ pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
trait_closure_kind,
vtable_fn_pointer.fn_ty);
let method_ty = def_ty(ccx.shared(), def_id, substs);
let method_ty = instance_ty(ccx.shared(), &instance);
Callee::ptr(llfn, method_ty)
}
traits::VtableObject(ref data) => {
Callee {
data: Virtual(tcx.get_vtable_index_of_object_method(data, def_id)),
ty: def_ty(ccx.shared(), def_id, substs)
ty: instance_ty(ccx.shared(), &Instance::new(def_id, substs))
}
}
vtable => {
......@@ -183,7 +185,7 @@ fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
-> ValueRef
{
// If this is a closure, redirect to it.
let (llfn, _) = get_fn(ccx, def_id, substs.substs);
let (llfn, _) = get_fn(ccx, Instance::new(def_id, substs.substs));
// If the closure is a Fn closure, but a FnOnce is needed (etc),
// then adapt the self type
......@@ -292,7 +294,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let llonce_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig));
// Create the by-value helper.
let function_name = method_instance.symbol_name(ccx.shared());
let function_name = symbol_name(method_instance, ccx.shared());
let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
attributes::set_frame_pointer_elimination(ccx, lloncefn);
......@@ -438,7 +440,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
debug!("tuple_fn_ty: {:?}", tuple_fn_ty);
//
let function_name = method_instance.symbol_name(ccx.shared());
let function_name = symbol_name(method_instance, ccx.shared());
let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
attributes::set_frame_pointer_elimination(ccx, llfn);
//
......@@ -489,21 +491,17 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
/// - `def_id`: def id of the fn or method item being referenced
/// - `substs`: values for each of the fn/method's parameters
fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>)
instance: Instance<'tcx>)
-> (ValueRef, Ty<'tcx>) {
let tcx = ccx.tcx();
debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs);
debug!("get_fn(instance={:?})", instance);
assert!(!substs.needs_infer());
assert!(!substs.has_escaping_regions());
assert!(!substs.has_param_types());
let substs = tcx.normalize_associated_type(&substs);
let instance = Instance::new(def_id, substs);
let fn_ty = common::def_ty(ccx.shared(), def_id, substs);
assert!(!instance.substs.needs_infer());
assert!(!instance.substs.has_escaping_regions());
assert!(!instance.substs.has_param_types());
let fn_ty = common::instance_ty(ccx.shared(), &instance);
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
return (llfn, fn_ty);
}
......@@ -553,7 +551,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
assert_eq!(common::val_ty(llfn), llptrty);
debug!("get_fn: not casting pointer!");
let attrs = ccx.tcx().get_attrs(def_id);
let attrs = instance.def.attrs(ccx.tcx());
attributes::from_fn_attrs(ccx, &attrs, llfn);
let is_local_def = ccx.shared().translation_items().borrow()
......@@ -565,7 +563,9 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
}
}
if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
if ccx.use_dll_storage_attrs() &&
ccx.sess().cstore.is_dllimport_foreign_item(instance.def_id())
{
unsafe {
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
}
......
此差异已折叠。
......@@ -602,7 +602,14 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
pub fn requests_inline(tcx: TyCtxt, def_id: DefId) -> bool {
pub fn requests_inline<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
instance: &ty::Instance<'tcx>
) -> bool {
let def_id = match instance.def {
ty::InstanceDef::Item(def_id) => def_id,
_ => return true
};
match tcx.def_key(def_id).disambiguated_data.data {
DefPathData::StructCtor |
DefPathData::EnumVariant(..) |
......@@ -610,7 +617,6 @@ pub fn requests_inline(tcx: TyCtxt, def_id: DefId) -> bool {
_ => attr::requests_inline(&tcx.get_attrs(def_id)[..]),
}
}
/// Given a DefId and some Substs, produces the monomorphic item type.
pub fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
def_id: DefId,
......@@ -620,3 +626,23 @@ pub fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
let ty = shared.tcx().item_type(def_id);
monomorphize::apply_param_substs(shared, substs, &ty)
}
/// Return the substituted type of an instance.
pub fn instance_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
instance: &ty::Instance<'tcx>)
-> Ty<'tcx>
{
let ty = instance.def.def_ty(shared.tcx());
monomorphize::apply_param_substs(shared, instance.substs, &ty)
}
pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
name: ast::Name,
substs: &'tcx Substs<'tcx>,
impl_data: &traits::VtableImplData<'tcx, ()>)
-> ty::Instance<'tcx>
{
let (def_id, substs) = traits::find_method(tcx, name, substs, impl_data);
let substs = tcx.erase_regions(&substs);
ty::Instance::new(def_id, substs)
}
......@@ -9,6 +9,7 @@
// except according to those terms.
use back::symbol_names;
use llvm;
use llvm::{SetUnnamedAddr};
use llvm::{ValueRef, True};
......@@ -24,7 +25,6 @@
use type_::Type;
use type_of;
use rustc::ty;
use rustc::ty::subst::Substs;
use rustc::hir;
......@@ -80,12 +80,12 @@ pub fn addr_of(ccx: &CrateContext,
}
pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
let instance = Instance::mono(ccx.shared(), def_id);
let instance = Instance::mono(ccx.tcx(), def_id);
if let Some(&g) = ccx.instances().borrow().get(&instance) {
return g;
}
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
let ty = common::instance_ty(ccx.shared(), &instance);
let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) {
let llty = type_of::type_of(ccx, ty);
......@@ -114,7 +114,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, span, node: hir::ForeignItemStatic(..), ..
}) => {
let sym = instance.symbol_name(ccx.shared());
let sym = symbol_names::symbol_name(instance, ccx.shared());
let g = if let Some(name) =
attr::first_attr_value_str_by_name(&attrs, "linkage") {
// If this is a static with a linkage specified, then we need to handle
......@@ -174,7 +174,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
g
} else {
let sym = instance.symbol_name(ccx.shared());
let sym = symbol_names::symbol_name(instance, ccx.shared());
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
// FIXME(nagisa): investigate whether it can be changed into define_global
......@@ -235,7 +235,8 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
v
};
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
let instance = Instance::mono(ccx.tcx(), def_id);
let ty = common::instance_ty(ccx.shared(), &instance);
let llty = type_of::type_of(ccx, ty);
let g = if val_llty == llty {
g
......
......@@ -546,16 +546,6 @@ pub fn translation_items(&self) -> &RefCell<FxHashSet<TransItem<'tcx>>> {
&self.translation_items
}
/// Given the def-id of some item that has no type parameters, make
/// a suitable "empty substs" for it.
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
Substs::for_item(self.tcx(), item_def_id,
|_, _| self.tcx().mk_region(ty::ReErased),
|_, _| {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}
pub fn metadata_symbol_name(&self) -> String {
format!("rust_metadata_{}_{}",
self.link_meta().crate_name,
......@@ -886,7 +876,7 @@ pub fn translation_items(&self) -> &RefCell<FxHashSet<TransItem<'tcx>>> {
/// Given the def-id of some item that has no type parameters, make
/// a suitable "empty substs" for it.
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
self.shared().empty_substs_for_def_id(item_def_id)
self.tcx().empty_substs_for_def_id(item_def_id)
}
/// Generate a new symbol name with the given prefix. This symbol name must
......
......@@ -205,7 +205,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
return FunctionDebugContext::DebugInfoDisabled;
}
for attr in cx.tcx().get_attrs(instance.def).iter() {
for attr in instance.def.attrs(cx.tcx()).iter() {
if attr.check_name("no_debug") {
return FunctionDebugContext::FunctionWithoutDebugInfo;
}
......@@ -229,11 +229,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
};
// Find the enclosing function, in case this is a closure.
let def_key = cx.tcx().def_key(instance.def);
let def_key = cx.tcx().def_key(instance.def_id());
let mut name = def_key.disambiguated_data.data.to_string();
let name_len = name.len();
let fn_def_id = cx.tcx().closure_base_def_id(instance.def);
let fn_def_id = cx.tcx().closure_base_def_id(instance.def_id());
// Get_template_parameters() will append a `<...>` clause to the function
// name if necessary.
......@@ -246,11 +246,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
&mut name);
// Build the linkage_name out of the item path and "template" parameters.
let linkage_name = mangled_name_of_item(cx, instance.def, &name[name_len..]);
let linkage_name = mangled_name_of_item(cx, instance.def_id(), &name[name_len..]);
let scope_line = span_start(cx, span).line;
let local_id = cx.tcx().hir.as_local_node_id(instance.def);
let local_id = cx.tcx().hir.as_local_node_id(instance.def_id());
let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id));
let function_name = CString::new(name).unwrap();
......@@ -394,7 +394,7 @@ fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
// First, let's see if this is a method within an inherent impl. Because
// if yes, we want to make the result subroutine DIE a child of the
// subroutine's self-type.
let self_type = cx.tcx().impl_of_method(instance.def).and_then(|impl_def_id| {
let self_type = cx.tcx().impl_of_method(instance.def_id()).and_then(|impl_def_id| {
// If the method does *not* belong to a trait, proceed
if cx.tcx().trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty =
......@@ -417,9 +417,9 @@ fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
self_type.unwrap_or_else(|| {
namespace::item_namespace(cx, DefId {
krate: instance.def.krate,
krate: instance.def_id().krate,
index: cx.tcx()
.def_key(instance.def)
.def_key(instance.def_id())
.parent
.expect("get_containing_scope: missing parent?")
})
......
......@@ -21,6 +21,7 @@
use monomorphize::Instance;
use type_::Type;
use type_of::*;
use back::symbol_names;
use value::Value;
use rustc::ty;
......@@ -70,7 +71,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
let function_name = match callee.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
let instance = Instance::new(def_id, substs);
instance.symbol_name(ccx.shared())
symbol_names::symbol_name(instance, ccx.shared())
}
_ => bug!()
};
......
......@@ -30,7 +30,7 @@
use common::{C_null, C_struct, C_str_slice, C_undef, C_uint, C_vector, is_undef};
use common::const_to_opt_u128;
use consts;
use monomorphize::{self, Instance};
use monomorphize;
use type_of;
use type_::Type;
use value::Value;
......@@ -245,11 +245,12 @@ fn new(ccx: &'a CrateContext<'a, 'tcx>,
}
fn trans_def(ccx: &'a CrateContext<'a, 'tcx>,
instance: Instance<'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>,
args: IndexVec<mir::Local, Const<'tcx>>)
-> Result<Const<'tcx>, ConstEvalErr<'tcx>> {
let instance = instance.resolve_const(ccx.shared());
let mir = ccx.tcx().item_mir(instance.def);
let instance = monomorphize::resolve_const(ccx.shared(), def_id, substs);
let mir = ccx.tcx().instance_mir(instance.def);
MirConstContext::new(ccx, &mir, instance.substs, args).trans()
}
......@@ -332,10 +333,8 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> {
mir::TerminatorKind::Call { ref func, ref args, ref destination, .. } => {
let fn_ty = func.ty(self.mir, tcx);
let fn_ty = self.monomorphize(&fn_ty);
let instance = match fn_ty.sty {
ty::TyFnDef(def_id, substs, _) => {
Instance::new(def_id, substs)
}
let (def_id, substs) = match fn_ty.sty {
ty::TyFnDef(def_id, substs, _) => (def_id, substs),
_ => span_bug!(span, "calling {:?} (of type {}) in constant",
func, fn_ty)
};
......@@ -348,7 +347,7 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> {
}
}
if let Some((ref dest, target)) = *destination {
match MirConstContext::trans_def(self.ccx, instance, const_args) {
match MirConstContext::trans_def(self.ccx, def_id, substs, const_args) {
Ok(value) => self.store(dest, value, span),
Err(err) => if failure.is_ok() { failure = Err(err); }
}
......@@ -485,8 +484,7 @@ fn const_operand(&self, operand: &mir::Operand<'tcx>, span: Span)
}
let substs = self.monomorphize(&substs);
let instance = Instance::new(def_id, substs);
MirConstContext::trans_def(self.ccx, instance, IndexVec::new())
MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new())
}
mir::Literal::Promoted { index } => {
let mir = &self.mir.promoted[index];
......@@ -588,7 +586,8 @@ fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>,
// Now create its substs [Closure, Tuple]
let input = tcx.closure_type(def_id)
.subst(tcx, substs.substs).input(0);
let substs = tcx.mk_substs([operand.ty, input.skip_binder()]
let input = tcx.erase_late_bound_regions_and_normalize(&input);
let substs = tcx.mk_substs([operand.ty, input]
.iter().cloned().map(Kind::from));
Callee::def(self.ccx, call_once, substs)
.reify(self.ccx)
......@@ -935,8 +934,7 @@ pub fn trans_constant(&mut self,
}
let substs = self.monomorphize(&substs);
let instance = Instance::new(def_id, substs);
MirConstContext::trans_def(bcx.ccx, instance, IndexVec::new())
MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new())
}
mir::Literal::Promoted { index } => {
let mir = &self.mir.promoted[index];
......@@ -964,8 +962,8 @@ pub fn trans_static_initializer<'a, 'tcx>(
def_id: DefId)
-> Result<ValueRef, ConstEvalErr<'tcx>>
{
let instance = Instance::mono(ccx.shared(), def_id);
MirConstContext::trans_def(ccx, instance, IndexVec::new()).map(|c| c.llval)
MirConstContext::trans_def(ccx, def_id, Substs::empty(), IndexVec::new())
.map(|c| c.llval)
}
/// Construct a constant value, suitable for initializing a
......
......@@ -203,7 +203,9 @@ pub fn trans_rvalue_operand(&mut self,
// Now create its substs [Closure, Tuple]
let input = bcx.tcx().closure_type(def_id)
.subst(bcx.tcx(), substs.substs).input(0);
let substs = bcx.tcx().mk_substs([operand.ty, input.skip_binder()]
let input =
bcx.tcx().erase_late_bound_regions_and_normalize(&input);
let substs = bcx.tcx().mk_substs([operand.ty, input]
.iter().cloned().map(Kind::from));
OperandValue::Immediate(
Callee::def(bcx.ccx, call_once, substs)
......
......@@ -15,54 +15,31 @@
use rustc::ty::fold::{TypeFolder, TypeFoldable};
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::ppaux;
use rustc::util::common::MemoizationMap;
use syntax::codemap::DUMMY_SP;
use std::fmt;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Instance<'tcx> {
pub def: DefId,
pub substs: &'tcx Substs<'tcx>,
}
impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ppaux::parameterized(f, &self.substs, self.def, &[])
}
}
impl<'a, 'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
-> Instance<'tcx> {
assert!(substs.regions().all(|&r| r == ty::ReErased));
Instance { def: def_id, substs: substs }
}
pub fn mono(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {
Instance::new(def_id, scx.empty_substs_for_def_id(def_id))
}
/// For associated constants from traits, return the impl definition.
pub fn resolve_const(&self, scx: &SharedCrateContext<'a, 'tcx>) -> Self {
if let Some(trait_id) = scx.tcx().trait_of_item(self.def) {
let trait_ref = ty::TraitRef::new(trait_id, self.substs);
let trait_ref = ty::Binder(trait_ref);
let vtable = fulfill_obligation(scx, DUMMY_SP, trait_ref);
if let traits::VtableImpl(vtable_impl) = vtable {
let name = scx.tcx().item_name(self.def);
let ac = scx.tcx().associated_items(vtable_impl.impl_def_id)
.find(|item| item.kind == ty::AssociatedKind::Const && item.name == name);
if let Some(ac) = ac {
return Instance::new(ac.def_id, vtable_impl.substs);
}
pub use rustc::ty::Instance;
/// For associated constants from traits, return the impl definition.
pub fn resolve_const<'a, 'tcx>(
scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>
) -> Instance<'tcx> {
if let Some(trait_id) = scx.tcx().trait_of_item(def_id) {
let trait_ref = ty::TraitRef::new(trait_id, substs);
let trait_ref = ty::Binder(trait_ref);
let vtable = fulfill_obligation(scx, DUMMY_SP, trait_ref);
if let traits::VtableImpl(vtable_impl) = vtable {
let name = scx.tcx().item_name(def_id);
let ac = scx.tcx().associated_items(vtable_impl.impl_def_id)
.find(|item| item.kind == ty::AssociatedKind::Const && item.name == name);
if let Some(ac) = ac {
return Instance::new(ac.def_id, vtable_impl.substs);
}
}
*self
}
Instance::new(def_id, substs)
}
/// Monomorphizes a type from the AST by first applying the in-scope
......
......@@ -110,7 +110,7 @@
use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::{self, TyCtxt};
use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc_incremental::IchHasher;
use std::cmp::Ordering;
......@@ -186,7 +186,8 @@ pub fn compute_symbol_name_hash(&self,
symbol_name.hash(&mut state);
let exported = match item {
TransItem::Fn(ref instance) => {
let node_id = scx.tcx().hir.as_local_node_id(instance.def);
let node_id =
scx.tcx().hir.as_local_node_id(instance.def_id());
node_id.map(|node_id| exported_symbols.contains(&node_id))
.unwrap_or(false)
}
......@@ -241,7 +242,7 @@ pub fn items_in_deterministic_order(&self,
fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option<NodeId> {
match trans_item {
TransItem::Fn(instance) => {
tcx.hir.as_local_node_id(instance.def)
tcx.hir.as_local_node_id(instance.def_id())
}
TransItem::Static(node_id) => Some(node_id),
TransItem::DropGlue(_) => None,
......@@ -455,17 +456,22 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't
let tcx = scx.tcx();
match trans_item {
TransItem::Fn(instance) => {
let def_id = match instance.def {
ty::InstanceDef::Item(def_id) => def_id,
ty::InstanceDef::FnPtrShim(..) => return None
};
// If this is a method, we want to put it into the same module as
// its self-type. If the self-type does not provide a characteristic
// DefId, we use the location of the impl after all.
if tcx.trait_of_item(instance.def).is_some() {
if tcx.trait_of_item(def_id).is_some() {
let self_ty = instance.substs.type_at(0);
// This is an implementation of a trait method.
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
return characteristic_def_id_of_type(self_ty).or(Some(def_id));
}
if let Some(impl_def_id) = tcx.impl_of_method(instance.def) {
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
// This is a method within an inherent impl, find out what the
// self-type is:
let impl_self_ty = common::def_ty(scx, impl_def_id, instance.substs);
......@@ -474,7 +480,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't
}
}
Some(instance.def)
Some(def_id)
}
TransItem::DropGlue(dg) => characteristic_def_id_of_type(dg.ty()),
TransItem::Static(node_id) => Some(tcx.hir.local_def_id(node_id)),
......
......@@ -97,7 +97,7 @@ fn get_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trans_item: TransItem<'tcx>) -> Option<Span> {
match trans_item {
TransItem::Fn(Instance { def, .. }) => {
tcx.hir.as_local_node_id(def)
tcx.hir.as_local_node_id(def.def_id())
}
TransItem::Static(node_id) => Some(node_id),
TransItem::DropGlue(_) => None,
......
......@@ -14,6 +14,7 @@
//! item-path. This is used for unit testing the code that generates
//! paths etc in all kinds of annoying scenarios.
use back::symbol_names;
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use syntax::ast;
......@@ -51,8 +52,8 @@ fn process_attrs(&mut self,
for attr in tcx.get_attrs(def_id).iter() {
if attr.check_name(SYMBOL_NAME) {
// for now, can only use on monomorphic names
let instance = Instance::mono(self.scx, def_id);
let name = instance.symbol_name(self.scx);
let instance = Instance::mono(tcx, def_id);
let name = symbol_names::symbol_name(instance, self.scx);
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
} else if attr.check_name(ITEM_PATH) {
let path = tcx.item_path_str(def_id);
......@@ -86,4 +87,3 @@ fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
intravisit::walk_impl_item(self, ii)
}
}
......@@ -96,7 +96,7 @@ pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) {
}
TransItem::Fn(instance) => {
let _task = ccx.tcx().dep_graph.in_task(
DepNode::TransCrateItem(instance.def)); // (*)
DepNode::TransCrateItem(instance.def_id())); // (*)
base::trans_instance(&ccx, instance);
}
......@@ -147,7 +147,8 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
linkage: llvm::Linkage,
symbol_name: &str) {
let def_id = ccx.tcx().hir.local_def_id(node_id);
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
let instance = Instance::mono(ccx.tcx(), def_id);
let ty = common::instance_ty(ccx.shared(), &instance);
let llty = type_of::type_of(ccx, ty);
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
......@@ -157,7 +158,6 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
unsafe { llvm::LLVMRustSetLinkage(g, linkage) };
let instance = Instance::mono(ccx.shared(), def_id);
ccx.instances().borrow_mut().insert(instance, g);
ccx.statics().borrow_mut().insert(g, def_id);
}
......@@ -169,8 +169,8 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
assert!(!instance.substs.needs_infer() &&
!instance.substs.has_param_types());
let mono_ty = common::def_ty(ccx.shared(), instance.def, instance.substs);
let attrs = ccx.tcx().get_attrs(instance.def);
let mono_ty = common::instance_ty(ccx.shared(), &instance);
let attrs = instance.def.attrs(ccx.tcx());
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
unsafe { llvm::LLVMRustSetLinkage(lldecl, linkage) };
base::set_link_section(ccx, lldecl, &attrs);
......@@ -180,7 +180,7 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
}
debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
match ccx.tcx().def_key(instance.def).disambiguated_data.data {
match ccx.tcx().def_key(instance.def_id()).disambiguated_data.data {
DefPathData::StructCtor |
DefPathData::EnumVariant(..) |
DefPathData::ClosureExpr => {
......@@ -229,10 +229,10 @@ fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
pub fn compute_symbol_name(&self,
scx: &SharedCrateContext<'a, 'tcx>) -> String {
match *self {
TransItem::Fn(instance) => instance.symbol_name(scx),
TransItem::Fn(instance) => symbol_names::symbol_name(instance, scx),
TransItem::Static(node_id) => {
let def_id = scx.tcx().hir.local_def_id(node_id);
Instance::mono(scx, def_id).symbol_name(scx)
symbol_names::symbol_name(Instance::mono(scx.tcx(), def_id), scx)
}
TransItem::DropGlue(dg) => {
let prefix = match dg {
......@@ -244,21 +244,13 @@ pub fn compute_symbol_name(&self,
}
}
pub fn is_from_extern_crate(&self) -> bool {
match *self {
TransItem::Fn(ref instance) => !instance.def.is_local(),
TransItem::DropGlue(..) |
TransItem::Static(..) => false,
}
}
pub fn instantiation_mode(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> InstantiationMode {
match *self {
TransItem::Fn(ref instance) => {
if self.explicit_linkage(tcx).is_none() &&
common::requests_inline(tcx, instance.def)
common::requests_inline(tcx, instance)
{
InstantiationMode::LocalCopy
} else {
......@@ -282,7 +274,7 @@ pub fn is_generic_fn(&self) -> bool {
pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<llvm::Linkage> {
let def_id = match *self {
TransItem::Fn(ref instance) => instance.def,
TransItem::Fn(ref instance) => instance.def_id(),
TransItem::Static(node_id) => tcx.hir.local_def_id(node_id),
TransItem::DropGlue(..) => return None,
};
......@@ -587,7 +579,7 @@ fn push_type_params<I>(&self,
pub fn push_instance_as_string(&self,
instance: Instance<'tcx>,
output: &mut String) {
self.push_def_path(instance.def, output);
self.push_def_path(instance.def_id(), output);
self.push_type_params(instance.substs, iter::empty(), output);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册