diff options
Diffstat (limited to 'compiler/rustc_mir/src/monomorphize')
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/collector.rs | 51 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/partitioning/mod.rs | 8 |
3 files changed, 48 insertions, 15 deletions
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index c5c701082e6..1fda71d74bb 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -59,11 +59,15 @@ //! //! ### Discovering roots //! -//! The roots of the mono item graph correspond to the non-generic +//! The roots of the mono item graph correspond to the public non-generic //! syntactic items in the source code. We find them by walking the HIR of the -//! crate, and whenever we hit upon a function, method, or static item, we -//! create a mono item consisting of the items DefId and, since we only -//! consider non-generic items, an empty type-substitution set. +//! crate, and whenever we hit upon a public function, method, or static item, +//! we create a mono item consisting of the items DefId and, since we only +//! consider non-generic items, an empty type-substitution set. (In eager +//! collection mode, during incremental compilation, all non-generic functions +//! are considered as roots, as well as when the `-Clink-dead-code` option is +//! specified. Functions marked `#[no_mangle]` and functions called by inlinable +//! functions also always act as roots.) //! //! ### Finding neighbor nodes //! Given a mono item node, we can discover neighbors by inspecting its @@ -184,7 +188,6 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; @@ -193,6 +196,7 @@ use rustc_middle::mir::{self, Local, Location}; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP}; use smallvec::SmallVec; @@ -638,6 +642,35 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_rvalue(rvalue, location); } + /// This does not walk the constant, as it has been handled entirely here and trying + /// to walk it would attempt to evaluate the `ty::Const` inside, which doesn't necessarily + /// work, as some constants cannot be represented in the type system. + fn visit_constant(&mut self, constant: &mir::Constant<'tcx>, location: Location) { + let literal = self.monomorphize(constant.literal); + let val = match literal { + mir::ConstantKind::Val(val, _) => val, + mir::ConstantKind::Ty(ct) => match ct.val { + ty::ConstKind::Value(val) => val, + ty::ConstKind::Unevaluated(ct) => { + let param_env = ty::ParamEnv::reveal_all(); + match self.tcx.const_eval_resolve(param_env, ct, None) { + // The `monomorphize` call should have evaluated that constant already. + Ok(val) => val, + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => return, + Err(ErrorHandled::TooGeneric) => span_bug!( + self.body.source_info(location).span, + "collection encountered polymorphic constant: {:?}", + literal + ), + } + } + _ => return, + }, + }; + collect_const_value(self.tcx, val, self.output); + self.visit_ty(literal.ty(), TyContext::Location(location)); + } + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) { debug!("visiting const {:?} @ {:?}", *constant, location); @@ -648,7 +681,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), ty::ConstKind::Unevaluated(unevaluated) => { match self.tcx.const_eval_resolve(param_env, unevaluated, None) { - Ok(val) => collect_const_value(self.tcx, val, self.output), + // The `monomorphize` call should have evaluated that constant already. + Ok(val) => span_bug!( + self.body.source_info(location).span, + "collection encountered the unevaluated constant {} which evaluated to {:?}", + substituted_constant, + val + ), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index d2586f0f84d..9ca4b6687f1 100644 --- a/compiler/rustc_mir/src/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs @@ -8,14 +8,14 @@ pub mod collector; pub mod partitioning; pub mod polymorphize; -pub fn custom_coerce_unsize_info<'tcx>( +fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - let trait_ref = ty::Binder::bind(ty::TraitRef { + let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), }); diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index 04f31ec3a33..dc2379fd92b 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -196,13 +196,7 @@ pub fn partition<'tcx>( // Next we try to make as many symbols "internal" as possible, so LLVM has // more freedom to optimize. - if !tcx.sess.link_dead_code() && !tcx.sess.instrument_coverage() { - // Disabled for `-Z instrument-coverage` because some LLVM optimizations can sometimes - // break coverage results. Tests that failed at certain optimization levels are now - // validated at those optimization levels (via `compile-flags` directive); for example: - // * `src/test/run-make-fulldeps/coverage/async.rs` broke with `-C opt-level=1` - // * `src/test/run-make-fulldeps/coverage/closure.rs` broke with `-C opt-level=2`, and - // also required disabling `generate_gcu_internal_copies` in `rustc_middle/mir/mono.rs` + if !tcx.sess.link_dead_code() { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); partitioner.internalize_symbols(cx, &mut post_inlining); } |
