From 8af151b30a31fef48a2173d7cc6aee50baa6d276 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 12:15:48 -0500 Subject: [PATCH 01/12] remove reexport of rustc::ty::Instance --- src/librustc_codegen_llvm/callee.rs | 3 +-- src/librustc_codegen_llvm/consts.rs | 3 +-- src/librustc_codegen_llvm/context.rs | 3 +-- src/librustc_codegen_llvm/debuginfo/mod.rs | 3 +-- src/librustc_codegen_llvm/debuginfo/namespace.rs | 2 +- src/librustc_codegen_llvm/mono_item.rs | 3 +-- src/librustc_codegen_ssa/base.rs | 3 +-- src/librustc_codegen_ssa/mir/mod.rs | 3 +-- src/librustc_codegen_ssa/traits/debuginfo.rs | 3 +-- src/librustc_codegen_ssa/traits/declare.rs | 3 +-- src/librustc_codegen_utils/symbol_names.rs | 3 +-- src/librustc_codegen_utils/symbol_names/legacy.rs | 3 +-- src/librustc_codegen_utils/symbol_names/v0.rs | 3 +-- src/librustc_codegen_utils/symbol_names_test.rs | 3 +-- src/librustc_mir/monomorphize/mod.rs | 3 +-- 15 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 2d732adcb9138..2c0a6f631b739 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -6,12 +6,11 @@ use crate::attributes; use crate::llvm; -use crate::monomorphize::Instance; use crate::context::CodegenCx; use crate::value::Value; use rustc_codegen_ssa::traits::*; -use rustc::ty::TypeFoldable; +use rustc::ty::{TypeFoldable, Instance}; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; /// Codegens a reference to a fn/method item, monomorphizing and diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 99b5cf42551fa..f7a06a9b23c37 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -2,7 +2,6 @@ use crate::llvm::{self, SetUnnamedAddr, True}; use crate::debuginfo; use crate::monomorphize::MonoItem; use crate::common::CodegenCx; -use crate::monomorphize::Instance; use crate::base; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; @@ -16,7 +15,7 @@ use syntax_pos::Span; use rustc_target::abi::HasDataLayout; use syntax::symbol::sym; use syntax_pos::symbol::LocalInternedString; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; use rustc_codegen_ssa::traits::*; use rustc::ty::layout::{self, Size, Align, LayoutOf}; diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index b6b47d047c8b1..f863d91e17c89 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,7 +1,6 @@ use crate::attributes; use crate::llvm; use crate::debuginfo; -use crate::monomorphize::Instance; use crate::value::Value; use rustc::dep_graph::DepGraphSafe; use rustc::hir; @@ -17,7 +16,7 @@ use rustc::session::Session; use rustc::ty::layout::{ LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, HasParamEnv }; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::util::nodemap::FxHashMap; use rustc_target::spec::{HasTargetSpec, Target}; use rustc_codegen_ssa::callee::resolve_and_get_fn; diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 6fa594d445300..548ea0b1036e0 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -20,9 +20,8 @@ use rustc::ty::subst::{SubstsRef, UnpackedKind}; use crate::abi::Abi; use crate::common::CodegenCx; use crate::builder::Builder; -use crate::monomorphize::Instance; use crate::value::Value; -use rustc::ty::{self, ParamEnv, Ty, InstanceDef}; +use rustc::ty::{self, ParamEnv, Ty, InstanceDef, Instance}; use rustc::mir; use rustc::session::config::{self, DebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index f7c377adf3529..c0e8acbbde940 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -2,7 +2,6 @@ use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER}; use super::utils::{DIB, debug_context}; -use crate::monomorphize::Instance; use rustc::ty; use crate::llvm; @@ -10,6 +9,7 @@ use crate::llvm::debuginfo::DIScope; use crate::common::CodegenCx; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; +use rustc::ty::Instance; use rustc_data_structures::small_c_str::SmallCStr; diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 7f0cdb9f58008..c1703ffd0c753 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -2,11 +2,10 @@ use crate::attributes; use crate::base; use crate::context::CodegenCx; use crate::llvm; -use crate::monomorphize::Instance; use crate::type_of::LayoutLlvmExt; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::mono::{Linkage, Visibility}; -use rustc::ty::TypeFoldable; +use rustc::ty::{TypeFoldable, Instance}; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use rustc_codegen_ssa::traits::*; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 172b5b39987d4..b1603a5f6c678 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -21,14 +21,13 @@ use rustc::middle::cstore::EncodedMetadata; use rustc::middle::lang_items::StartFnLangItem; use rustc::middle::weak_lang_items; use rustc::mir::mono::CodegenUnitNameBuilder; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; -use rustc_mir::monomorphize::Instance; use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 5d6f7036c3e29..1d40d004e2ddc 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,8 +1,7 @@ -use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; +use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts, Instance}; use rustc::ty::layout::{TyLayout, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Body}; use rustc::session::config::DebugInfo; -use rustc_mir::monomorphize::Instance; use rustc_target::abi::call::{FnType, PassMode, IgnoreMode}; use rustc_target::abi::{Variants, VariantIdx}; use crate::base; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 37b7a15e2ba5e..be2fa7279aa7c 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -2,9 +2,8 @@ use super::BackendTypes; use crate::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind}; use rustc::hir::def_id::CrateNum; use rustc::mir; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_mir::monomorphize::Instance; use syntax::ast::Name; use syntax_pos::{SourceFile, Span}; diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs index 6a400a7d7a45d..624a982b619ee 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/src/librustc_codegen_ssa/traits/declare.rs @@ -1,8 +1,7 @@ use super::BackendTypes; use rustc::hir::def_id::DefId; use rustc::mir::mono::{Linkage, Visibility}; -use rustc::ty; -use rustc_mir::monomorphize::Instance; +use rustc::ty::{self, Instance}; pub trait DeclareMethods<'tcx>: BackendTypes { /// Declare a global value. diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 37847b1b0988f..a8addcff318f7 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -92,9 +92,8 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::session::config::SymbolManglingVersion; use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, TyCtxt, Instance}; use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt}; -use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::InternedString; diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index 6eaa22afce19a..b6ece06fa6c5d 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -4,10 +4,9 @@ use rustc::ich::NodeIdHashingMode; use rustc::mir::interpret::{ConstValue, Scalar}; use rustc::ty::print::{PrettyPrinter, Printer, Print}; use rustc::ty::subst::{Kind, UnpackedKind}; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Instance}; use rustc::util::common::record_time; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_mir::monomorphize::Instance; use log::debug; diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs index 1615a097b3bf9..d83d7e5244e65 100644 --- a/src/librustc_codegen_utils/symbol_names/v0.rs +++ b/src/librustc_codegen_utils/symbol_names/v0.rs @@ -1,12 +1,11 @@ use rustc::hir; use rustc::hir::def_id::{CrateNum, DefId}; use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Instance}; use rustc::ty::print::{Printer, Print}; use rustc::ty::subst::{Kind, Subst, UnpackedKind}; use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_mir::monomorphize::Instance; use rustc_target::spec::abi::Abi; use syntax::ast::{IntTy, UintTy, FloatTy}; diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index b935ccb7398e2..9f7e483395244 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -5,8 +5,7 @@ //! paths etc in all kinds of annoying scenarios. use rustc::hir; -use rustc::ty::TyCtxt; -use rustc_mir::monomorphize::Instance; +use rustc::ty::{TyCtxt, Instance}; use syntax::symbol::{Symbol, sym}; const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index ff48c86817b49..5cf03a6a35b85 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -2,9 +2,8 @@ use rustc::hir::def_id::DefId; use rustc::middle::lang_items::DropInPlaceFnLangItem; use rustc::traits; use rustc::ty::adjustment::CustomCoerceUnsized; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, Instance}; -pub use rustc::ty::Instance; pub use self::item::{MonoItem, MonoItemExt}; pub mod collector; From 58bd0ea73201747441a76c56a9b74252ef08e6ba Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 12:45:22 -0500 Subject: [PATCH 02/12] deduplicate ty::Instance constructors --- src/librustc/ty/instance.rs | 65 ++++++++++------- src/librustc_codegen_ssa/meth.rs | 4 +- src/librustc_codegen_ssa/mir/block.rs | 4 +- src/librustc_codegen_ssa/mir/rvalue.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 3 +- src/librustc_mir/interpret/traits.rs | 5 +- src/librustc_mir/monomorphize/collector.rs | 8 +- src/librustc_mir/monomorphize/mod.rs | 85 ---------------------- 8 files changed, 53 insertions(+), 125 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index be15b1e3cc9e4..f0251917074d4 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -4,6 +4,7 @@ use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; +use crate::middle::lang_items::DropInPlaceFnLangItem; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; @@ -325,11 +326,47 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { let actual_kind = substs.closure_kind(def_id, tcx); match needs_fn_once_adapter_shim(actual_kind, requested_kind) { - Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), + Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs), _ => Instance::new(def_id, substs.substs) } } + pub fn resolve_drop_in_place( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx>) + -> ty::Instance<'tcx> + { + let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); + let substs = tcx.intern_substs(&[ty.into()]); + Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap() + } + + pub fn fn_once_adapter_instance( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + closure_did: DefId, + substs: ty::ClosureSubsts<'tcx>) + -> Instance<'tcx> + { + debug!("fn_once_adapter_shim({:?}, {:?})", + closure_did, + substs); + let fn_once = tcx.lang_items().fn_once_trait().unwrap(); + let call_once = tcx.associated_items(fn_once) + .find(|it| it.kind == ty::AssocKind::Method) + .unwrap().def_id; + let def = ty::InstanceDef::ClosureOnceShim { call_once }; + + let self_ty = tcx.mk_closure(closure_did, substs); + + let sig = substs.closure_sig(closure_did, tcx); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + assert_eq!(sig.inputs().len(), 1); + let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); + + debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); + Instance { def, substs } + } + pub fn is_vtable_shim(&self) -> bool { if let InstanceDef::VtableShim(..) = self.def { true @@ -438,29 +475,3 @@ fn needs_fn_once_adapter_shim<'a, 'tcx>(actual_closure_kind: ty::ClosureKind, (ty::ClosureKind::FnOnce, _) => Err(()) } } - -fn fn_once_adapter_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - closure_did: DefId, - substs: ty::ClosureSubsts<'tcx>) - -> Instance<'tcx> -{ - debug!("fn_once_adapter_shim({:?}, {:?})", - closure_did, - substs); - let fn_once = tcx.lang_items().fn_once_trait().unwrap(); - let call_once = tcx.associated_items(fn_once) - .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; - let def = ty::InstanceDef::ClosureOnceShim { call_once }; - - let self_ty = tcx.mk_closure(closure_did, substs); - - let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); - - debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); - Instance { def, substs } -} diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 49f3c87ee2d9d..73065be997092 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -4,7 +4,7 @@ use rustc_mir::monomorphize; use crate::callee; use crate::traits::*; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; #[derive(Copy, Clone, Debug)] pub struct VirtualIndex(u64); @@ -103,7 +103,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( // `get_vtable` in rust_mir/interpret/traits.rs // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ - cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)), + cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)), cx.const_usize(layout.size.bytes()), cx.const_usize(layout.align.abi.bytes()) ].iter().cloned().chain(methods).collect(); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index c7dd019fc3eb8..f2d4cd33229ce 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,5 +1,5 @@ use rustc::middle::lang_items; -use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::InterpError; @@ -310,7 +310,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) { let ty = location.ty(self.mir, bx.tcx()).ty; let ty = self.monomorphize(&ty); - let drop_fn = monomorphize::resolve_drop_in_place(bx.tcx(), ty); + let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty); if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 586db5cfabea4..b11fe236833c1 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -1,4 +1,4 @@ -use rustc::ty::{self, Ty, adjustment::{PointerCast}}; +use rustc::ty::{self, Ty, adjustment::{PointerCast}, Instance}; use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc::mir; @@ -196,7 +196,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => { match operand.layout.ty.sty { ty::Closure(def_id, substs) => { - let instance = monomorphize::resolve_closure( + let instance = Instance::resolve_closure( bx.cx().tcx(), def_id, substs, ty::ClosureKind::FnOnce); OperandValue::Immediate(bx.cx().get_fn(instance)) } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index ba48a28fc8315..a39af9640ac34 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use rustc::{mir, ty}; +use rustc::ty::Instance; use rustc::ty::layout::{self, TyLayout, LayoutOf}; use syntax::source_map::Span; use rustc_target::spec::abi::Abi; @@ -112,7 +113,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); - let instance = crate::monomorphize::resolve_drop_in_place(*self.tcx, ty); + let instance = Instance::resolve_drop_in_place(*self.tcx, ty); self.drop_in_place( place, instance, diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 208bba60bf2f2..33cb1a097175d 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,4 +1,4 @@ -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; @@ -55,8 +55,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> ); let tcx = &*self.tcx; - let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty); + let drop = Instance::resolve_drop_in_place(*tcx, ty); let drop = self.memory.create_fn_alloc(drop); + // no need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index dae5f1b8cd254..b808f64b0077f 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -181,7 +181,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; -use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind}; +use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; @@ -189,7 +189,7 @@ use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::MonoItem; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; -use crate::monomorphize::{self, Instance}; +use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; @@ -580,7 +580,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ); match source_ty.sty { ty::Closure(def_id, substs) => { - let instance = monomorphize::resolve_closure( + let instance = Instance::resolve_closure( self.tcx, def_id, substs, ty::ClosureKind::FnOnce); if should_monomorphize_locally(self.tcx, &instance) { self.output.push(create_fn_mono_item(instance)); @@ -684,7 +684,7 @@ fn visit_drop_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, is_direct_call: bool, output: &mut Vec>) { - let instance = monomorphize::resolve_drop_in_place(tcx, ty); + let instance = Instance::resolve_drop_in_place(tcx, ty); visit_instance_use(tcx, instance, is_direct_call, output); } diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 5cf03a6a35b85..8dda352d5e665 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -1,5 +1,3 @@ -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::DropInPlaceFnLangItem; use rustc::traits; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::ty::{self, Ty, TyCtxt, Instance}; @@ -54,89 +52,6 @@ pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mon } } -fn fn_once_adapter_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - closure_did: DefId, - substs: ty::ClosureSubsts<'tcx>, - ) -> Instance<'tcx> { - debug!("fn_once_adapter_shim({:?}, {:?})", - closure_did, - substs); - let fn_once = tcx.lang_items().fn_once_trait().unwrap(); - let call_once = tcx.associated_items(fn_once) - .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; - let def = ty::InstanceDef::ClosureOnceShim { call_once }; - - let self_ty = tcx.mk_closure(closure_did, substs); - - let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); - - debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); - Instance { def, substs } -} - -fn needs_fn_once_adapter_shim(actual_closure_kind: ty::ClosureKind, - trait_closure_kind: ty::ClosureKind) - -> Result -{ - match (actual_closure_kind, trait_closure_kind) { - (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | - (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => { - // No adapter needed. - Ok(false) - } - (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { - // The closure fn `llfn` is a `fn(&self, ...)`. We want a - // `fn(&mut self, ...)`. In fact, at codegen time, these are - // basically the same thing, so we can just return llfn. - Ok(false) - } - (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: - // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } - // - // These are both the same at codegen time. - Ok(true) - } - _ => Err(()), - } -} - -pub fn resolve_closure<'a, 'tcx> ( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - substs: ty::ClosureSubsts<'tcx>, - requested_kind: ty::ClosureKind) - -> Instance<'tcx> -{ - let actual_kind = substs.closure_kind(def_id, tcx); - - match needs_fn_once_adapter_shim(actual_kind, requested_kind) { - Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), - _ => Instance::new(def_id, substs.substs) - } -} - -pub fn resolve_drop_in_place<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>) - -> ty::Instance<'tcx> -{ - let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); - let substs = tcx.intern_substs(&[ty.into()]); - Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap() -} - pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>) From 594068955399264cd8f12b9abfa18c35662bc07f Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 13:00:08 -0500 Subject: [PATCH 03/12] move single-use function --- src/librustc_mir/monomorphize/mod.rs | 44 ------------------ src/librustc_mir/monomorphize/partitioning.rs | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 8dda352d5e665..ab93a84153094 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -8,50 +8,6 @@ pub mod collector; pub mod item; pub mod partitioning; -#[inline(never)] // give this a place in the profiler -pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mono_items: I) - where I: Iterator> -{ - let mut symbols: Vec<_> = mono_items.map(|mono_item| { - (mono_item, mono_item.symbol_name(tcx)) - }).collect(); - - symbols.sort_by_key(|sym| sym.1); - - for pair in symbols.windows(2) { - let sym1 = &pair[0].1; - let sym2 = &pair[1].1; - - if sym1 == sym2 { - let mono_item1 = pair[0].0; - let mono_item2 = pair[1].0; - - let span1 = mono_item1.local_span(tcx); - let span2 = mono_item2.local_span(tcx); - - // Deterministically select one of the spans for error reporting - let span = match (span1, span2) { - (Some(span1), Some(span2)) => { - Some(if span1.lo().0 > span2.lo().0 { - span1 - } else { - span2 - }) - } - (span1, span2) => span1.or(span2), - }; - - let error_message = format!("symbol `{}` is already defined", sym1); - - if let Some(span) = span { - tcx.sess.span_fatal(span, &error_message) - } else { - tcx.sess.fatal(&error_message) - } - } - } -} - pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index f321e05d68115..2e3d1e618aeda 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -882,6 +882,50 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } +#[inline(never)] // give this a place in the profiler +fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mono_items: I) + where I: Iterator> +{ + let mut symbols: Vec<_> = mono_items.map(|mono_item| { + (mono_item, mono_item.symbol_name(tcx)) + }).collect(); + + symbols.sort_by_key(|sym| sym.1); + + for pair in symbols.windows(2) { + let sym1 = &pair[0].1; + let sym2 = &pair[1].1; + + if sym1 == sym2 { + let mono_item1 = pair[0].0; + let mono_item2 = pair[1].0; + + let span1 = mono_item1.local_span(tcx); + let span2 = mono_item2.local_span(tcx); + + // Deterministically select one of the spans for error reporting + let span = match (span1, span2) { + (Some(span1), Some(span2)) => { + Some(if span1.lo().0 > span2.lo().0 { + span1 + } else { + span2 + }) + } + (span1, span2) => span1.or(span2), + }; + + let error_message = format!("symbol `{}` is already defined", sym1); + + if let Some(span) = span { + tcx.sess.span_fatal(span, &error_message) + } else { + tcx.sess.fatal(&error_message) + } + } + } +} + fn collect_and_partition_mono_items<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum, @@ -922,7 +966,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( tcx.sess.abort_if_errors(); - crate::monomorphize::assert_symbols_are_distinct(tcx, items.iter()); + assert_symbols_are_distinct(tcx, items.iter()); let strategy = if tcx.sess.opts.incremental.is_some() { PartitioningStrategy::PerModule From 3287ddf937d873f8a4e5dbbd0fe2937904dfdd88 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 13:10:11 -0500 Subject: [PATCH 04/12] remove reexports of mir::mono::{MonoItem,CodegenUnit} --- src/librustc_codegen_llvm/consts.rs | 1 + src/librustc_codegen_llvm/context.rs | 2 +- src/librustc_codegen_ssa/base.rs | 4 ++-- src/librustc_codegen_ssa/traits/misc.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 3 ++- src/librustc_mir/monomorphize/item.rs | 5 ++--- src/librustc_mir/monomorphize/mod.rs | 4 ++-- src/librustc_mir/monomorphize/partitioning.rs | 4 +--- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index f7a06a9b23c37..c05a7a35665d5 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -10,6 +10,7 @@ use libc::c_uint; use rustc::hir::def_id::DefId; use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint, Pointer, ErrorHandled, GlobalId}; +use rustc::mir::mono::MonoItem; use rustc::hir::Node; use syntax_pos::Span; use rustc_target::abi::HasDataLayout; diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index f863d91e17c89..ead9bad656db5 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -5,12 +5,12 @@ use crate::value::Value; use rustc::dep_graph::DepGraphSafe; use rustc::hir; -use crate::monomorphize::partitioning::CodegenUnit; use crate::type_::Type; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; use rustc_data_structures::small_c_str::SmallCStr; +use rustc::mir::mono::CodegenUnit; use rustc::session::config::{self, DebugInfo}; use rustc::session::Session; use rustc::ty::layout::{ diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index b1603a5f6c678..2f134e6e358b6 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -20,7 +20,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::lang_items::StartFnLangItem; use rustc::middle::weak_lang_items; -use rustc::mir::mono::CodegenUnitNameBuilder; +use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; @@ -28,7 +28,7 @@ use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; -use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; +use rustc_mir::monomorphize::partitioning::CodegenUnitExt; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr}; diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index 5ea86df6e9459..46c88a6113ebe 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -1,8 +1,8 @@ use super::BackendTypes; +use rustc::mir::mono::CodegenUnit; use rustc::session::Session; use rustc::ty::{self, Instance, Ty}; use rustc::util::nodemap::FxHashMap; -use rustc_mir::monomorphize::partitioning::CodegenUnit; use std::cell::RefCell; use std::sync::Arc; diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index a8addcff318f7..9f710d7932dcf 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -93,7 +93,8 @@ use rustc::hir::CodegenFnAttrFlags; use rustc::session::config::SymbolManglingVersion; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, Instance}; -use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt}; +use rustc::mir::mono::MonoItem; +use rustc_mir::monomorphize::item::{InstantiationMode, MonoItemExt}; use syntax_pos::symbol::InternedString; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 8b44f148facf6..c685283b3dc0a 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -1,9 +1,9 @@ -use crate::monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::ConstValue; +use rustc::mir::mono::MonoItem; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts}; +use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, Instance}; use rustc::ty::subst::{SubstsRef, InternalSubsts}; use syntax::ast; use syntax::attr::InlineAttr; @@ -12,7 +12,6 @@ use std::iter; use rustc::mir::mono::Linkage; use syntax_pos::symbol::InternedString; use syntax::source_map::Span; -pub use rustc::mir::mono::MonoItem; /// Describes how a monomorphization will be instantiated in object files. #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index ab93a84153094..f7b32dc84bdd5 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -1,8 +1,8 @@ use rustc::traits; use rustc::ty::adjustment::CustomCoerceUnsized; -use rustc::ty::{self, Ty, TyCtxt, Instance}; +use rustc::ty::{self, Ty, TyCtxt}; -pub use self::item::{MonoItem, MonoItemExt}; +pub use self::item::MonoItemExt; pub mod collector; pub mod item; diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 2e3d1e618aeda..cc90d6c95c915 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -101,7 +101,7 @@ use rustc::dep_graph::{WorkProductId, WorkProduct, DepNode, DepConstructor}; use rustc::hir::{CodegenFnAttrFlags, HirId}; use rustc::hir::def::DefKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; -use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder}; +use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder, CodegenUnit}; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::ty::{self, DefIdTree, TyCtxt, InstanceDef}; use rustc::ty::print::characteristic_def_id_of_type; @@ -114,8 +114,6 @@ use crate::monomorphize::collector::InliningMap; use crate::monomorphize::collector::{self, MonoItemCollectionMode}; use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; -pub use rustc::mir::mono::CodegenUnit; - pub enum PartitioningStrategy { /// Generates one codegen unit per source-level module. PerModule, From f2b9b2d13bb14dd80d5bacbbb63d9d5cc6003a35 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 13:48:27 -0500 Subject: [PATCH 05/12] move DefPathBasedNames to ty::print::obsolete --- src/librustc/ty/print/mod.rs | 1 + src/librustc/ty/print/obsolete.rs | 286 ++++++++++++++++++++ src/librustc_codegen_llvm/type_of.rs | 2 +- src/librustc_codegen_ssa/base.rs | 1 + src/librustc_mir/monomorphize/collector.rs | 3 +- src/librustc_mir/monomorphize/item.rs | 300 +-------------------- 6 files changed, 296 insertions(+), 297 deletions(-) create mode 100644 src/librustc/ty/print/obsolete.rs diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 53d4466cfef68..a3986f7c055e6 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet; // `pretty` is a separate module only for organization. mod pretty; +pub mod obsolete; pub use self::pretty::*; pub trait Print<'gcx, 'tcx, P> { diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs new file mode 100644 index 0000000000000..85d338699b0e0 --- /dev/null +++ b/src/librustc/ty/print/obsolete.rs @@ -0,0 +1,286 @@ +//! Allows for producing a unique string key for a mono item. +//! These keys are used by the handwritten auto-tests, so they need to be +//! predictable and human-readable. +//! +//! Note: A lot of this could looks very similar to what's already in `ty::print`. +//! FIXME(eddyb) implement a custom `PrettyPrinter` for this. + +use rustc::hir::def_id::DefId; +use rustc::mir::interpret::ConstValue; +use rustc::ty::subst::SubstsRef; +use rustc::ty::{self, ClosureSubsts, Const, GeneratorSubsts, Instance, Ty, TyCtxt}; +use rustc::{bug, hir}; +use std::fmt::Write; +use std::iter; +use syntax::ast; + +/// Same as `unique_type_name()` but with the result pushed onto the given +/// `output` parameter. +pub struct DefPathBasedNames<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + omit_disambiguators: bool, + omit_local_crate_name: bool, +} + +impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { + pub fn new( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + omit_disambiguators: bool, + omit_local_crate_name: bool, + ) -> Self { + DefPathBasedNames { tcx, omit_disambiguators, omit_local_crate_name } + } + + // Pushes the type name of the specified type to the provided string. + // If `debug` is true, printing normally unprintable types is allowed + // (e.g. `ty::GeneratorWitness`). This parameter should only be set when + // this method is being used for logging purposes (e.g. with `debug!` or `info!`) + // When being used for codegen purposes, `debug` should be set to `false` + // in order to catch unexpected types that should never end up in a type name. + pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { + match t.sty { + ty::Bool => output.push_str("bool"), + ty::Char => output.push_str("char"), + ty::Str => output.push_str("str"), + ty::Never => output.push_str("!"), + ty::Int(ast::IntTy::Isize) => output.push_str("isize"), + ty::Int(ast::IntTy::I8) => output.push_str("i8"), + ty::Int(ast::IntTy::I16) => output.push_str("i16"), + ty::Int(ast::IntTy::I32) => output.push_str("i32"), + ty::Int(ast::IntTy::I64) => output.push_str("i64"), + ty::Int(ast::IntTy::I128) => output.push_str("i128"), + ty::Uint(ast::UintTy::Usize) => output.push_str("usize"), + ty::Uint(ast::UintTy::U8) => output.push_str("u8"), + ty::Uint(ast::UintTy::U16) => output.push_str("u16"), + ty::Uint(ast::UintTy::U32) => output.push_str("u32"), + ty::Uint(ast::UintTy::U64) => output.push_str("u64"), + ty::Uint(ast::UintTy::U128) => output.push_str("u128"), + ty::Float(ast::FloatTy::F32) => output.push_str("f32"), + ty::Float(ast::FloatTy::F64) => output.push_str("f64"), + ty::Adt(adt_def, substs) => { + self.push_def_path(adt_def.did, output); + self.push_generic_params(substs, iter::empty(), output, debug); + } + ty::Tuple(component_types) => { + output.push('('); + for &component_type in component_types { + self.push_type_name(component_type.expect_ty(), output, debug); + output.push_str(", "); + } + if !component_types.is_empty() { + output.pop(); + output.pop(); + } + output.push(')'); + } + ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => { + output.push('*'); + match mutbl { + hir::MutImmutable => output.push_str("const "), + hir::MutMutable => output.push_str("mut "), + } + + self.push_type_name(inner_type, output, debug); + } + ty::Ref(_, inner_type, mutbl) => { + output.push('&'); + if mutbl == hir::MutMutable { + output.push_str("mut "); + } + + self.push_type_name(inner_type, output, debug); + } + ty::Array(inner_type, len) => { + output.push('['); + self.push_type_name(inner_type, output, debug); + write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); + output.push(']'); + } + ty::Slice(inner_type) => { + output.push('['); + self.push_type_name(inner_type, output, debug); + output.push(']'); + } + ty::Dynamic(ref trait_data, ..) => { + if let Some(principal) = trait_data.principal() { + self.push_def_path(principal.def_id(), output); + self.push_generic_params( + principal.skip_binder().substs, + trait_data.projection_bounds(), + output, + debug, + ); + } else { + output.push_str("dyn '_"); + } + } + ty::Foreign(did) => self.push_def_path(did, output), + ty::FnDef(..) | ty::FnPtr(_) => { + let sig = t.fn_sig(self.tcx); + if sig.unsafety() == hir::Unsafety::Unsafe { + output.push_str("unsafe "); + } + + let abi = sig.abi(); + if abi != ::rustc_target::spec::abi::Abi::Rust { + output.push_str("extern \""); + output.push_str(abi.name()); + output.push_str("\" "); + } + + output.push_str("fn("); + + let sig = + self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + + if !sig.inputs().is_empty() { + for ¶meter_type in sig.inputs() { + self.push_type_name(parameter_type, output, debug); + output.push_str(", "); + } + output.pop(); + output.pop(); + } + + if sig.c_variadic { + if !sig.inputs().is_empty() { + output.push_str(", ..."); + } else { + output.push_str("..."); + } + } + + output.push(')'); + + if !sig.output().is_unit() { + output.push_str(" -> "); + self.push_type_name(sig.output(), output, debug); + } + } + ty::Generator(def_id, GeneratorSubsts { ref substs }, _) + | ty::Closure(def_id, ClosureSubsts { ref substs }) => { + self.push_def_path(def_id, output); + let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); + let substs = substs.truncate_to(self.tcx, generics); + self.push_generic_params(substs, iter::empty(), output, debug); + } + ty::Error + | ty::Bound(..) + | ty::Infer(_) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::Projection(..) + | ty::Param(_) + | ty::GeneratorWitness(_) + | ty::Opaque(..) => { + if debug { + output.push_str(&format!("`{:?}`", t)); + } else { + bug!( + "DefPathBasedNames: trying to create type name for unexpected type: {:?}", + t, + ); + } + } + } + } + + // Pushes the the name of the specified const to the provided string. + // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed, + // as well as the unprintable types of constants (see `push_type_name` for more details). + pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { + match c.val { + ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => { + // FIXME(const_generics): we could probably do a better job here. + write!(output, "{:?}", c).unwrap() + } + _ => { + if debug { + write!(output, "{:?}", c).unwrap() + } else { + bug!( + "DefPathBasedNames: trying to create const name for unexpected const: {:?}", + c, + ); + } + } + } + output.push_str(": "); + self.push_type_name(c.ty, output, debug); + } + + pub fn push_def_path(&self, def_id: DefId, output: &mut String) { + let def_path = self.tcx.def_path(def_id); + + // some_crate:: + if !(self.omit_local_crate_name && def_id.is_local()) { + output.push_str(&self.tcx.crate_name(def_path.krate).as_str()); + output.push_str("::"); + } + + // foo::bar::ItemName:: + for part in self.tcx.def_path(def_id).data { + if self.omit_disambiguators { + write!(output, "{}::", part.data.as_interned_str()).unwrap(); + } else { + write!(output, "{}[{}]::", part.data.as_interned_str(), part.disambiguator) + .unwrap(); + } + } + + // remove final "::" + output.pop(); + output.pop(); + } + + fn push_generic_params( + &self, + substs: SubstsRef<'tcx>, + projections: I, + output: &mut String, + debug: bool, + ) where + I: Iterator>, + { + let mut projections = projections.peekable(); + if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() { + return; + } + + output.push('<'); + + for type_parameter in substs.types() { + self.push_type_name(type_parameter, output, debug); + output.push_str(", "); + } + + for projection in projections { + let projection = projection.skip_binder(); + let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); + output.push_str(name); + output.push_str("="); + self.push_type_name(projection.ty, output, debug); + output.push_str(", "); + } + + for const_parameter in substs.consts() { + self.push_const_name(const_parameter, output, debug); + output.push_str(", "); + } + + output.pop(); + output.pop(); + + output.push('>'); + } + + pub fn push_instance_as_string( + &self, + instance: Instance<'tcx>, + output: &mut String, + debug: bool, + ) { + self.push_def_path(instance.def_id(), output); + self.push_generic_params(instance.substs, iter::empty(), output, debug); + } +} diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 800bf505125d6..7a82fd731f604 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -4,7 +4,7 @@ use crate::type_::Type; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, Align, LayoutOf, FnTypeExt, PointeeInfo, Size, TyLayout}; use rustc_target::abi::{FloatTy, TyLayoutMethods}; -use rustc_mir::monomorphize::item::DefPathBasedNames; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc_codegen_ssa::traits::*; use std::fmt::Write; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 2f134e6e358b6..fc3d0712fca5a 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -24,6 +24,7 @@ use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index b808f64b0077f..2fc42098669ea 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,6 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; @@ -193,7 +194,7 @@ use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; -use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; +use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index c685283b3dc0a..d60d0fe9114d3 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -1,14 +1,11 @@ -use rustc::hir; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::mir::interpret::ConstValue; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::mono::MonoItem; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, Instance}; -use rustc::ty::subst::{SubstsRef, InternalSubsts}; -use syntax::ast; +use rustc::ty::{self, TyCtxt, Instance}; +use rustc::ty::subst::InternalSubsts; +use rustc::ty::print::obsolete::DefPathBasedNames; use syntax::attr::InlineAttr; -use std::fmt::{self, Write}; -use std::iter; +use std::fmt; use rustc::mir::mono::Linkage; use syntax_pos::symbol::InternedString; use syntax::source_map::Span; @@ -206,290 +203,3 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { self } } - -//=----------------------------------------------------------------------------- -// MonoItem String Keys -//=----------------------------------------------------------------------------- - -// The code below allows for producing a unique string key for a mono item. -// These keys are used by the handwritten auto-tests, so they need to be -// predictable and human-readable. -// -// Note: A lot of this could looks very similar to what's already in `ty::print`. -// FIXME(eddyb) implement a custom `PrettyPrinter` for this. - -/// Same as `unique_type_name()` but with the result pushed onto the given -/// `output` parameter. -pub struct DefPathBasedNames<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - omit_disambiguators: bool, - omit_local_crate_name: bool, -} - -impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, - omit_disambiguators: bool, - omit_local_crate_name: bool) - -> Self { - DefPathBasedNames { - tcx, - omit_disambiguators, - omit_local_crate_name, - } - } - - // Pushes the type name of the specified type to the provided string. - // If `debug` is true, printing normally unprintable types is allowed - // (e.g. `ty::GeneratorWitness`). This parameter should only be set when - // this method is being used for logging purposes (e.g. with `debug!` or `info!`) - // When being used for codegen purposes, `debug` should be set to `false` - // in order to catch unexpected types that should never end up in a type name. - pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { - match t.sty { - ty::Bool => output.push_str("bool"), - ty::Char => output.push_str("char"), - ty::Str => output.push_str("str"), - ty::Never => output.push_str("!"), - ty::Int(ast::IntTy::Isize) => output.push_str("isize"), - ty::Int(ast::IntTy::I8) => output.push_str("i8"), - ty::Int(ast::IntTy::I16) => output.push_str("i16"), - ty::Int(ast::IntTy::I32) => output.push_str("i32"), - ty::Int(ast::IntTy::I64) => output.push_str("i64"), - ty::Int(ast::IntTy::I128) => output.push_str("i128"), - ty::Uint(ast::UintTy::Usize) => output.push_str("usize"), - ty::Uint(ast::UintTy::U8) => output.push_str("u8"), - ty::Uint(ast::UintTy::U16) => output.push_str("u16"), - ty::Uint(ast::UintTy::U32) => output.push_str("u32"), - ty::Uint(ast::UintTy::U64) => output.push_str("u64"), - ty::Uint(ast::UintTy::U128) => output.push_str("u128"), - ty::Float(ast::FloatTy::F32) => output.push_str("f32"), - ty::Float(ast::FloatTy::F64) => output.push_str("f64"), - ty::Adt(adt_def, substs) => { - self.push_def_path(adt_def.did, output); - self.push_generic_params(substs, iter::empty(), output, debug); - }, - ty::Tuple(component_types) => { - output.push('('); - for &component_type in component_types { - self.push_type_name(component_type.expect_ty(), output, debug); - output.push_str(", "); - } - if !component_types.is_empty() { - output.pop(); - output.pop(); - } - output.push(')'); - }, - ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { - output.push('*'); - match mutbl { - hir::MutImmutable => output.push_str("const "), - hir::MutMutable => output.push_str("mut "), - } - - self.push_type_name(inner_type, output, debug); - }, - ty::Ref(_, inner_type, mutbl) => { - output.push('&'); - if mutbl == hir::MutMutable { - output.push_str("mut "); - } - - self.push_type_name(inner_type, output, debug); - }, - ty::Array(inner_type, len) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); - output.push(']'); - }, - ty::Slice(inner_type) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - output.push(']'); - }, - ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_generic_params( - principal.skip_binder().substs, - trait_data.projection_bounds(), - output, - debug - ); - } else { - output.push_str("dyn '_"); - } - }, - ty::Foreign(did) => self.push_def_path(did, output), - ty::FnDef(..) | - ty::FnPtr(_) => { - let sig = t.fn_sig(self.tcx); - if sig.unsafety() == hir::Unsafety::Unsafe { - output.push_str("unsafe "); - } - - let abi = sig.abi(); - if abi != ::rustc_target::spec::abi::Abi::Rust { - output.push_str("extern \""); - output.push_str(abi.name()); - output.push_str("\" "); - } - - output.push_str("fn("); - - let sig = self.tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &sig, - ); - - if !sig.inputs().is_empty() { - for ¶meter_type in sig.inputs() { - self.push_type_name(parameter_type, output, debug); - output.push_str(", "); - } - output.pop(); - output.pop(); - } - - if sig.c_variadic { - if !sig.inputs().is_empty() { - output.push_str(", ..."); - } else { - output.push_str("..."); - } - } - - output.push(')'); - - if !sig.output().is_unit() { - output.push_str(" -> "); - self.push_type_name(sig.output(), output, debug); - } - }, - ty::Generator(def_id, GeneratorSubsts { ref substs }, _) | - ty::Closure(def_id, ClosureSubsts { ref substs }) => { - self.push_def_path(def_id, output); - let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); - let substs = substs.truncate_to(self.tcx, generics); - self.push_generic_params(substs, iter::empty(), output, debug); - } - ty::Error | - ty::Bound(..) | - ty::Infer(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Projection(..) | - ty::Param(_) | - ty::GeneratorWitness(_) | - ty::Opaque(..) => { - if debug { - output.push_str(&format!("`{:?}`", t)); - } else { - bug!( - "DefPathBasedNames: trying to create type name for unexpected type: {:?}", - t, - ); - } - } - } - } - - // Pushes the the name of the specified const to the provided string. - // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed, - // as well as the unprintable types of constants (see `push_type_name` for more details). - pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { - match c.val { - ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => { - // FIXME(const_generics): we could probably do a better job here. - write!(output, "{:?}", c).unwrap() - } - _ => { - if debug { - write!(output, "{:?}", c).unwrap() - } else { - bug!( - "DefPathBasedNames: trying to create const name for unexpected const: {:?}", - c, - ); - } - } - } - output.push_str(": "); - self.push_type_name(c.ty, output, debug); - } - - pub fn push_def_path(&self, - def_id: DefId, - output: &mut String) { - let def_path = self.tcx.def_path(def_id); - - // some_crate:: - if !(self.omit_local_crate_name && def_id.is_local()) { - output.push_str(&self.tcx.crate_name(def_path.krate).as_str()); - output.push_str("::"); - } - - // foo::bar::ItemName:: - for part in self.tcx.def_path(def_id).data { - if self.omit_disambiguators { - write!(output, "{}::", part.data.as_interned_str()).unwrap(); - } else { - write!(output, "{}[{}]::", - part.data.as_interned_str(), - part.disambiguator).unwrap(); - } - } - - // remove final "::" - output.pop(); - output.pop(); - } - - fn push_generic_params( - &self, - substs: SubstsRef<'tcx>, - projections: I, - output: &mut String, - debug: bool, - ) where I: Iterator> { - let mut projections = projections.peekable(); - if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() { - return; - } - - output.push('<'); - - for type_parameter in substs.types() { - self.push_type_name(type_parameter, output, debug); - output.push_str(", "); - } - - for projection in projections { - let projection = projection.skip_binder(); - let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); - output.push_str(name); - output.push_str("="); - self.push_type_name(projection.ty, output, debug); - output.push_str(", "); - } - - for const_parameter in substs.consts() { - self.push_const_name(const_parameter, output, debug); - output.push_str(", "); - } - - output.pop(); - output.pop(); - - output.push('>'); - } - - pub fn push_instance_as_string(&self, - instance: Instance<'tcx>, - output: &mut String, - debug: bool) { - self.push_def_path(instance.def_id(), output); - self.push_generic_params(instance.substs, iter::empty(), output, debug); - } -} From 621bf0da80a9f304906d74657a91ed927f4f9cad Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 10:57:30 -0500 Subject: [PATCH 06/12] move monoitemext to inherent methods --- src/librustc/mir/mono.rs | 191 +++++++++++++++++- src/librustc_codegen_ssa/base.rs | 4 +- src/librustc_codegen_ssa/mono_item.rs | 31 +-- src/librustc_codegen_utils/symbol_names.rs | 3 +- src/librustc_mir/monomorphize/collector.rs | 4 +- src/librustc_mir/monomorphize/mod.rs | 3 - src/librustc_mir/monomorphize/partitioning.rs | 3 +- 7 files changed, 211 insertions(+), 28 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index ca79bc15358c5..9ba0bb3eb2d39 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,15 +1,44 @@ use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use crate::hir::HirId; use syntax::symbol::InternedString; -use crate::ty::{Instance, TyCtxt}; +use syntax::attr::InlineAttr; +use syntax::source_map::Span; +use crate::ty::{Instance, TyCtxt, SymbolName, subst::InternalSubsts}; use crate::util::nodemap::FxHashMap; +use crate::ty::print::obsolete::DefPathBasedNames; use rustc_data_structures::base_n; use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, StableHasher}; use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; +use crate::session::config::OptLevel; use std::fmt; use std::hash::Hash; +/// Describes how a monomorphization will be instantiated in object files. +#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] +pub enum InstantiationMode { + /// There will be exactly one instance of the given MonoItem. It will have + /// external linkage so that it can be linked to from other codegen units. + GloballyShared { + /// In some compilation scenarios we may decide to take functions that + /// are typically `LocalCopy` and instead move them to `GloballyShared` + /// to avoid codegenning them a bunch of times. In this situation, + /// however, our local copy may conflict with other crates also + /// inlining the same function. + /// + /// This flag indicates that this situation is occurring, and informs + /// symbol name calculation that some extra mangling is needed to + /// avoid conflicts. Note that this may eventually go away entirely if + /// ThinLTO enables us to *always* have a globally shared instance of a + /// function within one crate's compilation. + may_conflict: bool, + }, + + /// Each codegen unit containing a reference to the given MonoItem will + /// have its own private copy of the function (with internal linkage). + LocalCopy, +} + #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), @@ -31,6 +60,166 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(_) => 1, } } + + pub fn is_generic_fn(&self) -> bool { + match *self { + MonoItem::Fn(ref instance) => { + instance.substs.non_erasable_generics().next().is_some() + } + MonoItem::Static(..) | + MonoItem::GlobalAsm(..) => false, + } + } + + pub fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> SymbolName { + match *self { + MonoItem::Fn(instance) => tcx.symbol_name(instance), + MonoItem::Static(def_id) => { + tcx.symbol_name(Instance::mono(tcx, def_id)) + } + MonoItem::GlobalAsm(hir_id) => { + let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + SymbolName { + name: InternedString::intern(&format!("global_asm_{:?}", def_id)) + } + } + } + } + + pub fn instantiation_mode(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> InstantiationMode { + let inline_in_all_cgus = + tcx.sess.opts.debugging_opts.inline_in_all_cgus.unwrap_or_else(|| { + tcx.sess.opts.optimize != OptLevel::No + }) && !tcx.sess.opts.cg.link_dead_code; + + match *self { + MonoItem::Fn(ref instance) => { + let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); + // If this function isn't inlined or otherwise has explicit + // linkage, then we'll be creating a globally shared version. + if self.explicit_linkage(tcx).is_some() || + !instance.def.requires_local(tcx) || + Some(instance.def_id()) == entry_def_id + { + return InstantiationMode::GloballyShared { may_conflict: false } + } + + // At this point we don't have explicit linkage and we're an + // inlined function. If we're inlining into all CGUs then we'll + // be creating a local copy per CGU + if inline_in_all_cgus { + return InstantiationMode::LocalCopy + } + + // Finally, if this is `#[inline(always)]` we're sure to respect + // that with an inline copy per CGU, but otherwise we'll be + // creating one copy of this `#[inline]` function which may + // conflict with upstream crates as it could be an exported + // symbol. + match tcx.codegen_fn_attrs(instance.def_id()).inline { + InlineAttr::Always => InstantiationMode::LocalCopy, + _ => { + InstantiationMode::GloballyShared { may_conflict: true } + } + } + } + MonoItem::Static(..) | + MonoItem::GlobalAsm(..) => { + InstantiationMode::GloballyShared { may_conflict: false } + } + } + } + + pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { + let def_id = match *self { + MonoItem::Fn(ref instance) => instance.def_id(), + MonoItem::Static(def_id) => def_id, + MonoItem::GlobalAsm(..) => return None, + }; + + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); + codegen_fn_attrs.linkage + } + + /// Returns `true` if this instance is instantiable - whether it has no unsatisfied + /// predicates. + /// + /// In order to codegen an item, all of its predicates must hold, because + /// otherwise the item does not make sense. Type-checking ensures that + /// the predicates of every item that is *used by* a valid item *do* + /// hold, so we can rely on that. + /// + /// However, we codegen collector roots (reachable items) and functions + /// in vtables when they are seen, even if they are not used, and so they + /// might not be instantiable. For example, a programmer can define this + /// public function: + /// + /// pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone { + /// <&mut () as Clone>::clone(&s); + /// } + /// + /// That function can't be codegened, because the method `<&mut () as Clone>::clone` + /// does not exist. Luckily for us, that function can't ever be used, + /// because that would require for `&'a mut (): Clone` to hold, so we + /// can just not emit any code, or even a linker reference for it. + /// + /// Similarly, if a vtable method has such a signature, and therefore can't + /// be used, we can just not emit it and have a placeholder (a null pointer, + /// which will never be accessed) in its place. + pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { + debug!("is_instantiable({:?})", self); + let (def_id, substs) = match *self { + MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), + MonoItem::Static(def_id) => (def_id, InternalSubsts::empty()), + // global asm never has predicates + MonoItem::GlobalAsm(..) => return true + }; + + tcx.substitute_normalize_and_test_predicates((def_id, &substs)) + } + + pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, debug: bool) -> String { + return match *self { + MonoItem::Fn(instance) => { + to_string_internal(tcx, "fn ", instance, debug) + }, + MonoItem::Static(def_id) => { + let instance = Instance::new(def_id, tcx.intern_substs(&[])); + to_string_internal(tcx, "static ", instance, debug) + }, + MonoItem::GlobalAsm(..) => { + "global_asm".to_string() + } + }; + + fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + prefix: &str, + instance: Instance<'tcx>, + debug: bool) + -> String { + let mut result = String::with_capacity(32); + result.push_str(prefix); + let printer = DefPathBasedNames::new(tcx, false, false); + printer.push_instance_as_string(instance, &mut result, debug); + result + } + } + + pub fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { + match *self { + MonoItem::Fn(Instance { def, .. }) => { + tcx.hir().as_local_hir_id(def.def_id()) + } + MonoItem::Static(def_id) => { + tcx.hir().as_local_hir_id(def_id) + } + MonoItem::GlobalAsm(hir_id) => { + Some(hir_id) + } + }.map(|hir_id| tcx.hir().span_by_hir_id(hir_id)) + } } impl<'a, 'tcx> HashStable> for MonoItem<'tcx> { diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index fc3d0712fca5a..34e5b0681de03 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -20,11 +20,10 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::lang_items::StartFnLangItem; use rustc::middle::weak_lang_items; -use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit}; +use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit, MonoItem}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; -use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; @@ -42,7 +41,6 @@ use crate::callee; use crate::common::{RealPredicate, TypeKind, IntPredicate}; use crate::meth; use crate::mir; -use crate::mono_item::MonoItem; use crate::traits::*; diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 60d75480e61a6..1c9c86a5f5dda 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -1,19 +1,18 @@ use rustc::hir; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::layout::HasTyCtxt; -use std::fmt; use crate::base; use crate::traits::*; -pub use rustc::mir::mono::MonoItem; +use rustc::mir::mono::MonoItem; -pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; +pub trait MonoItemExt<'a, 'tcx: 'a> { + fn as_mono_item(&self) -> &MonoItem<'tcx>; -pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { fn define>(&self, cx: &'a Bx::CodegenCx) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), + self.as_mono_item().to_string(cx.tcx(), true), + self.as_mono_item().to_raw_string(), cx.codegen_unit().name()); match *self.as_mono_item() { @@ -34,8 +33,8 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } debug!("END IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), + self.as_mono_item().to_string(cx.tcx(), true), + self.as_mono_item().to_raw_string(), cx.codegen_unit().name()); } @@ -46,11 +45,11 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { visibility: Visibility ) { debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), + self.as_mono_item().to_string(cx.tcx(), true), + self.as_mono_item().to_raw_string(), cx.codegen_unit().name()); - let symbol_name = self.symbol_name(cx.tcx()).as_str(); + let symbol_name = self.as_mono_item().symbol_name(cx.tcx()).as_str(); debug!("symbol {}", &symbol_name); @@ -65,8 +64,8 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } debug!("END PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), + self.as_mono_item().to_string(cx.tcx(), true), + self.as_mono_item().to_raw_string(), cx.codegen_unit().name()); } @@ -87,4 +86,8 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } } -impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {} +impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { + fn as_mono_item(&self) -> &MonoItem<'tcx> { + self + } +} diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 9f710d7932dcf..47dc4e5b2cafe 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -93,8 +93,7 @@ use rustc::hir::CodegenFnAttrFlags; use rustc::session::config::SymbolManglingVersion; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, Instance}; -use rustc::mir::mono::MonoItem; -use rustc_mir::monomorphize::item::{InstantiationMode, MonoItemExt}; +use rustc::mir::mono::{MonoItem, InstantiationMode}; use syntax_pos::symbol::InternedString; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 2fc42098669ea..eed051449e155 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -187,15 +187,13 @@ use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::mono::MonoItem; +use rustc::mir::mono::{MonoItem, InstantiationMode}; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; -use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; - use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index f7b32dc84bdd5..51bcbff7f3236 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -2,10 +2,7 @@ use rustc::traits; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::ty::{self, Ty, TyCtxt}; -pub use self::item::MonoItemExt; - pub mod collector; -pub mod item; pub mod partitioning; pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index cc90d6c95c915..6a7f67da1bf1a 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -108,11 +108,10 @@ use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; use rustc::util::common::time; use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet}; -use rustc::mir::mono::MonoItem; +use rustc::mir::mono::{MonoItem, InstantiationMode}; use crate::monomorphize::collector::InliningMap; use crate::monomorphize::collector::{self, MonoItemCollectionMode}; -use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; pub enum PartitioningStrategy { /// Generates one codegen unit per source-level module. From e21d002bd2485fb4bd5a783cc3fe3a1cf2ca2c5a Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 11:19:53 -0500 Subject: [PATCH 07/12] move codegenunitext to rustc::mir::mono --- src/librustc/mir/mono.rs | 70 ++++++++++++++- src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_codegen_ssa/base.rs | 1 - src/librustc_mir/monomorphize/partitioning.rs | 90 +------------------ 4 files changed, 70 insertions(+), 92 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 9ba0bb3eb2d39..79228a5c56f2d 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -3,9 +3,10 @@ use crate::hir::HirId; use syntax::symbol::InternedString; use syntax::attr::InlineAttr; use syntax::source_map::Span; -use crate::ty::{Instance, TyCtxt, SymbolName, subst::InternalSubsts}; +use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; use crate::util::nodemap::FxHashMap; use crate::ty::print::obsolete::DefPathBasedNames; +use crate::dep_graph::{WorkProductId, DepNode, WorkProduct, DepConstructor}; use rustc_data_structures::base_n; use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, StableHasher}; @@ -350,6 +351,73 @@ impl<'tcx> CodegenUnit<'tcx> { self.size_estimate = Some(size_estimate + delta); } } + + pub fn contains_item(&self, item: &MonoItem<'tcx>) -> bool { + self.items().contains_key(item) + } + + pub fn work_product_id(&self) -> WorkProductId { + WorkProductId::from_cgu_name(&self.name().as_str()) + } + + pub fn work_product(&self, tcx: TyCtxt<'_, '_, '_>) -> WorkProduct { + let work_product_id = self.work_product_id(); + tcx.dep_graph + .previous_work_product(&work_product_id) + .unwrap_or_else(|| { + panic!("Could not find work-product for CGU `{}`", self.name()) + }) + } + + pub fn items_in_deterministic_order<'a>(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> Vec<(MonoItem<'tcx>, + (Linkage, Visibility))> { + // The codegen tests rely on items being process in the same order as + // they appear in the file, so for local items, we sort by node_id first + #[derive(PartialEq, Eq, PartialOrd, Ord)] + pub struct ItemSortKey(Option, SymbolName); + + fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: MonoItem<'tcx>) -> ItemSortKey { + ItemSortKey(match item { + MonoItem::Fn(ref instance) => { + match instance.def { + // We only want to take HirIds of user-defined + // instances into account. The others don't matter for + // the codegen tests and can even make item order + // unstable. + InstanceDef::Item(def_id) => { + tcx.hir().as_local_hir_id(def_id) + } + InstanceDef::VtableShim(..) | + InstanceDef::Intrinsic(..) | + InstanceDef::FnPtrShim(..) | + InstanceDef::Virtual(..) | + InstanceDef::ClosureOnceShim { .. } | + InstanceDef::DropGlue(..) | + InstanceDef::CloneShim(..) => { + None + } + } + } + MonoItem::Static(def_id) => { + tcx.hir().as_local_hir_id(def_id) + } + MonoItem::GlobalAsm(hir_id) => { + Some(hir_id) + } + }, item.symbol_name(tcx)) + } + + let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect(); + items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i)); + items + } + + pub fn codegen_dep_node(&self, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> DepNode { + DepNode::new(tcx, DepConstructor::CompileCodegenUnit(self.name().clone())) + } } impl<'a, 'tcx> HashStable> for CodegenUnit<'tcx> { diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index b13d8df5525e9..09156c0f9e746 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -32,7 +32,6 @@ extern crate flate2; #[macro_use] extern crate bitflags; extern crate libc; #[macro_use] extern crate rustc; -extern crate rustc_mir; extern crate rustc_allocator; extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 34e5b0681de03..0cd29e0213ee7 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -28,7 +28,6 @@ use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; -use rustc_mir::monomorphize::partitioning::CodegenUnitExt; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr}; diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 6a7f67da1bf1a..1895d4871552e 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -97,8 +97,7 @@ use std::cmp; use std::sync::Arc; use syntax::symbol::InternedString; -use rustc::dep_graph::{WorkProductId, WorkProduct, DepNode, DepConstructor}; -use rustc::hir::{CodegenFnAttrFlags, HirId}; +use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def::DefKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder, CodegenUnit}; @@ -121,93 +120,6 @@ pub enum PartitioningStrategy { FixedUnitCount(usize) } -pub trait CodegenUnitExt<'tcx> { - fn as_codegen_unit(&self) -> &CodegenUnit<'tcx>; - - fn contains_item(&self, item: &MonoItem<'tcx>) -> bool { - self.items().contains_key(item) - } - - fn name<'a>(&'a self) -> &'a InternedString - where 'tcx: 'a, - { - &self.as_codegen_unit().name() - } - - fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { - &self.as_codegen_unit().items() - } - - fn work_product_id(&self) -> WorkProductId { - WorkProductId::from_cgu_name(&self.name().as_str()) - } - - fn work_product(&self, tcx: TyCtxt<'_, '_, '_>) -> WorkProduct { - let work_product_id = self.work_product_id(); - tcx.dep_graph - .previous_work_product(&work_product_id) - .unwrap_or_else(|| { - panic!("Could not find work-product for CGU `{}`", self.name()) - }) - } - - fn items_in_deterministic_order<'a>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Vec<(MonoItem<'tcx>, - (Linkage, Visibility))> { - // The codegen tests rely on items being process in the same order as - // they appear in the file, so for local items, we sort by node_id first - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub struct ItemSortKey(Option, ty::SymbolName); - - fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: MonoItem<'tcx>) -> ItemSortKey { - ItemSortKey(match item { - MonoItem::Fn(ref instance) => { - match instance.def { - // We only want to take HirIds of user-defined - // instances into account. The others don't matter for - // the codegen tests and can even make item order - // unstable. - InstanceDef::Item(def_id) => { - tcx.hir().as_local_hir_id(def_id) - } - InstanceDef::VtableShim(..) | - InstanceDef::Intrinsic(..) | - InstanceDef::FnPtrShim(..) | - InstanceDef::Virtual(..) | - InstanceDef::ClosureOnceShim { .. } | - InstanceDef::DropGlue(..) | - InstanceDef::CloneShim(..) => { - None - } - } - } - MonoItem::Static(def_id) => { - tcx.hir().as_local_hir_id(def_id) - } - MonoItem::GlobalAsm(hir_id) => { - Some(hir_id) - } - }, item.symbol_name(tcx)) - } - - let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect(); - items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i)); - items - } - - fn codegen_dep_node(&self, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> DepNode { - DepNode::new(tcx, DepConstructor::CompileCodegenUnit(self.name().clone())) - } -} - -impl<'tcx> CodegenUnitExt<'tcx> for CodegenUnit<'tcx> { - fn as_codegen_unit(&self) -> &CodegenUnit<'tcx> { - self - } -} - // Anything we can't find a proper codegen unit for goes into this. fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>) -> InternedString { name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu")) From b20d96f97f29019404c45f4ec73903af1b9d3699 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 12:26:30 -0500 Subject: [PATCH 08/12] remove as_mono_item --- src/librustc_codegen_ssa/mono_item.rs | 41 ++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 1c9c86a5f5dda..11e9a48133d9a 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -7,15 +7,24 @@ use crate::traits::*; use rustc::mir::mono::MonoItem; pub trait MonoItemExt<'a, 'tcx: 'a> { - fn as_mono_item(&self) -> &MonoItem<'tcx>; + fn define>(&self, cx: &'a Bx::CodegenCx); + fn predefine>( + &self, + cx: &'a Bx::CodegenCx, + linkage: Linkage, + visibility: Visibility + ); + fn to_raw_string(&self) -> String; +} +impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn define>(&self, cx: &'a Bx::CodegenCx) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.as_mono_item().to_string(cx.tcx(), true), - self.as_mono_item().to_raw_string(), + self.to_string(cx.tcx(), true), + self.to_raw_string(), cx.codegen_unit().name()); - match *self.as_mono_item() { + match *self { MonoItem::Static(def_id) => { cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id)); } @@ -33,8 +42,8 @@ pub trait MonoItemExt<'a, 'tcx: 'a> { } debug!("END IMPLEMENTING '{} ({})' in cgu {}", - self.as_mono_item().to_string(cx.tcx(), true), - self.as_mono_item().to_raw_string(), + self.to_string(cx.tcx(), true), + self.to_raw_string(), cx.codegen_unit().name()); } @@ -45,15 +54,15 @@ pub trait MonoItemExt<'a, 'tcx: 'a> { visibility: Visibility ) { debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", - self.as_mono_item().to_string(cx.tcx(), true), - self.as_mono_item().to_raw_string(), + self.to_string(cx.tcx(), true), + self.to_raw_string(), cx.codegen_unit().name()); - let symbol_name = self.as_mono_item().symbol_name(cx.tcx()).as_str(); + let symbol_name = self.symbol_name(cx.tcx()).as_str(); debug!("symbol {}", &symbol_name); - match *self.as_mono_item() { + match *self { MonoItem::Static(def_id) => { cx.predefine_static(def_id, linkage, visibility, &symbol_name); } @@ -64,13 +73,13 @@ pub trait MonoItemExt<'a, 'tcx: 'a> { } debug!("END PREDEFINING '{} ({})' in cgu {}", - self.as_mono_item().to_string(cx.tcx(), true), - self.as_mono_item().to_raw_string(), + self.to_string(cx.tcx(), true), + self.to_raw_string(), cx.codegen_unit().name()); } fn to_raw_string(&self) -> String { - match *self.as_mono_item() { + match *self { MonoItem::Fn(instance) => { format!("Fn({:?}, {})", instance.def, @@ -85,9 +94,3 @@ pub trait MonoItemExt<'a, 'tcx: 'a> { } } } - -impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { - fn as_mono_item(&self) -> &MonoItem<'tcx> { - self - } -} From c747f31ffce95507471156f77d2e5ea1c4ccf9c9 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 12:32:53 -0500 Subject: [PATCH 09/12] remove unneeded deps --- src/librustc_codegen_llvm/base.rs | 1 - src/librustc_codegen_llvm/consts.rs | 1 - src/librustc_codegen_llvm/debuginfo/namespace.rs | 3 +-- src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_codegen_ssa/meth.rs | 1 - src/librustc_codegen_ssa/mir/block.rs | 1 - src/librustc_codegen_ssa/mir/rvalue.rs | 1 - src/librustc_codegen_utils/Cargo.toml | 1 - 8 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index f8c6087373f1e..62374eb21039a 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -22,7 +22,6 @@ use crate::metadata; use crate::builder::Builder; use crate::common; use crate::context::CodegenCx; -use crate::monomorphize::partitioning::CodegenUnitExt; use rustc::dep_graph; use rustc::mir::mono::{Linkage, Visibility}; use rustc::middle::cstore::{EncodedMetadata}; diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index c05a7a35665d5..eb059ac453c3d 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -1,6 +1,5 @@ use crate::llvm::{self, SetUnnamedAddr, True}; use crate::debuginfo; -use crate::monomorphize::MonoItem; use crate::common::CodegenCx; use crate::base; use crate::type_::Type; diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index c0e8acbbde940..889984749fdf7 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -2,14 +2,13 @@ use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER}; use super::utils::{DIB, debug_context}; -use rustc::ty; +use rustc::ty::{self, Instance}; use crate::llvm; use crate::llvm::debuginfo::DIScope; use crate::common::CodegenCx; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; -use rustc::ty::Instance; use rustc_data_structures::small_c_str::SmallCStr; diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 09156c0f9e746..0fdd326a1882e 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -63,7 +63,6 @@ use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; -use rustc_mir::monomorphize; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_utils::codegen_backend::CodegenBackend; diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 73065be997092..d38e434d98ce8 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -1,5 +1,4 @@ use rustc_target::abi::call::FnType; -use rustc_mir::monomorphize; use crate::callee; use crate::traits::*; diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index f2d4cd33229ce..4c9313a330921 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -5,7 +5,6 @@ use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::InterpError; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; -use rustc_mir::monomorphize; use crate::base; use crate::MemFlags; use crate::common::{self, IntPredicate}; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index b11fe236833c1..7a2bd18df4ec9 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -11,7 +11,6 @@ use crate::base; use crate::MemFlags; use crate::callee; use crate::common::{self, RealPredicate, IntPredicate}; -use rustc_mir::monomorphize; use crate::traits::*; diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index 268be2b109114..b218d18a06ba7 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -22,4 +22,3 @@ rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_metadata = { path = "../librustc_metadata" } -rustc_mir = { path = "../librustc_mir" } From 74919df3a9aa0411f0ff39a3cef250abbadd4a3f Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 14:58:37 -0500 Subject: [PATCH 10/12] query-ify const_field --- Cargo.lock | 1 - src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/query/mod.rs | 10 ++++++++++ src/librustc/ty/print/mod.rs | 3 ++- src/librustc/ty/query/keys.rs | 9 +++++++++ src/librustc_codegen_ssa/mir/constant.rs | 9 ++------- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 6 ++++-- src/librustc_mir/lib.rs | 4 ++++ 9 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea0087de839af..e9c4d6b3bad64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2703,7 +2703,6 @@ dependencies = [ "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", "rustc_metadata 0.0.0", - "rustc_mir 0.0.0", "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index e5bf9a27ab050..a364a6da2e497 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -49,6 +49,7 @@ //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. +use crate::mir; use crate::mir::interpret::GlobalId; use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use crate::hir::map::DefPathHash; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 18308f5444221..00856041edf46 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -4,6 +4,7 @@ use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; use crate::dep_graph::SerializedDepNodeIndex; use crate::hir::def_id::{CrateNum, DefId, DefIndex}; +use crate::mir; use crate::mir::interpret::GlobalId; use crate::traits; use crate::traits::query::{ @@ -431,6 +432,15 @@ rustc_queries! { tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok) } } + + /// Extracts a field of a (variant of a) const. + query const_field( + key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)> + ) -> &'tcx ty::Const<'tcx> { + eval_always + no_force + desc { "extract field of const" } + } } TypeChecking { diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index a3986f7c055e6..a7cb7bd3956f0 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -7,9 +7,10 @@ use rustc_data_structures::fx::FxHashSet; // `pretty` is a separate module only for organization. mod pretty; -pub mod obsolete; pub use self::pretty::*; +pub mod obsolete; + pub trait Print<'gcx, 'tcx, P> { type Output; type Error; diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d353da801778d..27b0e8e881df9 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -127,6 +127,15 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { } } +impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_, '_, '_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for ty::PolyTraitRef<'tcx>{ fn query_crate(&self) -> CrateNum { self.def_id().krate diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index eaa1dd186a536..78c22206ab7a5 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -1,5 +1,4 @@ use rustc::mir::interpret::ErrorHandled; -use rustc_mir::const_eval::const_field; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use rustc::ty::{self, Ty}; @@ -46,12 +45,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("invalid simd shuffle type: {}", c.ty), }; let values: Vec<_> = (0..fields).map(|field| { - let field = const_field( - bx.tcx(), - ty::ParamEnv::reveal_all(), - None, - mir::Field::new(field as usize), - c, + let field = bx.tcx().const_field( + ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))) ); if let Some(prim) = field.val.try_to_scalar() { let layout = bx.layout_of(field_ty); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index dc7aa0f17e88c..d118a61bcc6ce 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -470,7 +470,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> } } -/// Projects to a field of a (variant of a) const. +/// Extracts a field of a (variant of a) const. // this function uses `unwrap` copiously, because an already validated constant must have valid // fields and can thus never fail outside of compiler bugs pub fn const_field<'a, 'tcx>( diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index d5cee871810f5..716838b4fc597 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -5,7 +5,7 @@ mod check_match; pub(crate) use self::check_match::check_match; -use crate::const_eval::{const_field, const_variant_index}; +use crate::const_eval::const_variant_index; use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::constant::*; @@ -949,7 +949,9 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { debug!("const_to_pat: cv={:#?} id={:?}", cv, id); let adt_subpattern = |i, variant_opt| { let field = Field::new(i); - let val = const_field(self.tcx, self.param_env, variant_opt, field, cv); + let val = crate::const_eval::const_field( + self.tcx, self.param_env, variant_opt, field, cv + ); self.const_to_pat(instance, val, id, span) }; let adt_subpatterns = |n, variant_opt| { diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 6dc2b00740706..46bda28c13c5c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -63,6 +63,10 @@ pub fn provide(providers: &mut Providers<'_>) { providers.const_eval = const_eval::const_eval_provider; providers.const_eval_raw = const_eval::const_eval_raw_provider; providers.check_match = hair::pattern::check_match; + providers.const_field = |tcx, param_env_and_value| { + let (param_env, (value, field)) = param_env_and_value.into_parts(); + const_eval::const_field(tcx, param_env, None, field, value) + }; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS } From b7f5eab11c687f084e37a6a5fa5c46326d83a5b4 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 24 May 2019 15:01:11 -0500 Subject: [PATCH 11/12] remove last dependency of codegen on rustc_mir --- src/librustc_codegen_ssa/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 0b34ec8e8bc1c..a4cb517fafed6 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -33,5 +33,4 @@ rustc_data_structures = { path = "../librustc_data_structures"} rustc_errors = { path = "../librustc_errors" } rustc_fs_util = { path = "../librustc_fs_util" } rustc_incremental = { path = "../librustc_incremental" } -rustc_mir = { path = "../librustc_mir" } rustc_target = { path = "../librustc_target" } From 0f822d775f046df87713edf8ffb4e308fc77b3ef Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sun, 2 Jun 2019 23:20:36 -0500 Subject: [PATCH 12/12] query-fy type_name --- Cargo.lock | 1 - src/librustc/query/mod.rs | 9 +++++++++ src/librustc_codegen_llvm/intrinsic.rs | 2 +- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/lib.rs | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9c4d6b3bad64..d7191743c36f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2684,7 +2684,6 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_fs_util 0.0.0", "rustc_incremental 0.0.0", - "rustc_mir 0.0.0", "rustc_target 0.0.0", "serialize 0.0.0", "syntax 0.0.0", diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 00856041edf46..10efef54526a6 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -441,6 +441,15 @@ rustc_queries! { no_force desc { "extract field of const" } } + + /// Produces an absolute path representation of the given type. See also the documentation + /// on `std::any::type_name`. + query type_name(key: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { + eval_always + no_force + desc { "get absolute path of type" } + } + } TypeChecking { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 060c295eb7af1..98a829b2affec 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -212,7 +212,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } "type_name" => { let tp_ty = substs.type_at(0); - let ty_name = rustc_mir::interpret::type_name(self.tcx, tp_ty); + let ty_name = self.tcx.type_name(tp_ty); OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self) } "type_id" => { diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index ed389a8df94ab..d59bee6943a51 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -33,4 +33,4 @@ pub use self::visitor::{ValueVisitor, MutValueVisitor}; pub use self::validity::RefTracking; -pub use self::intrinsics::type_name; +pub(super) use self::intrinsics::type_name; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 46bda28c13c5c..9213a009ea740 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -67,6 +67,7 @@ pub fn provide(providers: &mut Providers<'_>) { let (param_env, (value, field)) = param_env_and_value.into_parts(); const_eval::const_field(tcx, param_env, None, field, value) }; + providers.type_name = interpret::type_name; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS }