From: Wesley Wiser Date: Tue, 6 Aug 2019 01:11:55 +0000 (-0400) Subject: Move def_id out add substsref X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=4d62545687d0c10577eb75c058c0662e6b261395;p=rust.git Move def_id out add substsref --- diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 66f5eaeeda1..69e98583b19 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1732,20 +1732,22 @@ pub enum PlaceBase<'tcx> { #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct Static<'tcx> { pub ty: Ty<'tcx>, - pub kind: StaticKind, + pub kind: StaticKind<'tcx>, + pub def_id: DefId, } #[derive( Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable, )] -pub enum StaticKind { - Promoted(Promoted), - Static(DefId), +pub enum StaticKind<'tcx> { + Promoted(Promoted, SubstsRef<'tcx>), + Static, } impl_stable_hash_for!(struct Static<'tcx> { ty, - kind + kind, + def_id }); /// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`. @@ -2106,10 +2108,12 @@ impl Debug for PlaceBase<'_> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { match *self { PlaceBase::Local(id) => write!(fmt, "{:?}", id), - PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) }) => { + PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static, def_id }) => { write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) } - PlaceBase::Static(box self::Static { ty, kind: StaticKind::Promoted(promoted) }) => { + PlaceBase::Static(box self::Static { + ty, kind: StaticKind::Promoted(promoted, _), def_id: _ + }) => { write!(fmt, "({:?}: {:?})", promoted, ty) } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 2d16e7bcc83..ac0e784d8bd 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -708,7 +708,7 @@ fn super_place_base(&mut self, PlaceBase::Local(local) => { self.visit_local(local, context, location); } - PlaceBase::Static(box Static { kind: _, ty }) => { + PlaceBase::Static(box Static { kind: _, ty, def_id: _ }) => { self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); } } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index dbce5ce4896..d2a7571fde1 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -609,8 +609,9 @@ fn codegen_call_terminator<'b>( mir::Operand::Copy( Place { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted), + kind: StaticKind::Promoted(promoted, _), ty, + def_id: _, }), projection: None, } @@ -618,8 +619,9 @@ fn codegen_call_terminator<'b>( mir::Operand::Move( Place { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted), + kind: StaticKind::Promoted(promoted, _), ty, + def_id: _, }), projection: None, } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index a632838ba24..f7b94ea134c 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -1,4 +1,5 @@ -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Instance, Ty}; +use rustc::ty::subst::Subst; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::mir; use rustc::mir::tcx::PlaceTy; @@ -454,16 +455,25 @@ pub fn codegen_place( mir::PlaceRef { base: mir::PlaceBase::Static(box mir::Static { ty, - kind: mir::StaticKind::Promoted(promoted), + kind: mir::StaticKind::Promoted(promoted, substs), + def_id, }), projection: None, } => { + debug!("promoted={:?}, def_id={:?}, substs={:?}, self_substs={:?}", promoted, def_id, substs, self.instance.substs); let param_env = ty::ParamEnv::reveal_all(); + let instance = Instance::new(*def_id, substs.subst(bx.tcx(), self.instance.substs)); + debug!("instance: {:?}", instance); let cid = mir::interpret::GlobalId { - instance: self.instance, + instance: instance, promoted: Some(*promoted), }; - let layout = cx.layout_of(self.monomorphize(&ty)); + let mono_ty = tcx.subst_and_normalize_erasing_regions( + instance.substs, + param_env, + ty, + ); + let layout = cx.layout_of(mono_ty); match bx.tcx().const_eval(param_env.and(cid)) { Ok(val) => match val.val { mir::interpret::ConstValue::ByRef { alloc, offset } => { @@ -487,7 +497,8 @@ pub fn codegen_place( mir::PlaceRef { base: mir::PlaceBase::Static(box mir::Static { ty, - kind: mir::StaticKind::Static(def_id), + kind: mir::StaticKind::Static, + def_id, }), projection: None, } => { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 99899aa390c..251d4b727c7 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -159,7 +159,7 @@ fn append_place_to_string( PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), projection: None, @@ -169,7 +169,8 @@ fn append_place_to_string( PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Static(def_id), + kind: StaticKind::Static, + def_id, .. }), projection: None, @@ -440,7 +441,8 @@ fn describe_field_from_ty( pub fn is_place_thread_local(&self, place_ref: PlaceRef<'cx, 'tcx>) -> bool { if let PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Static(def_id), + kind: StaticKind::Static, + def_id, .. }), projection: None, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 05b396681ac..33cec78f3df 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1467,13 +1467,13 @@ fn check_for_invalidation_at_exit( assert!(root_place.projection.is_none()); let (might_be_alive, will_be_dropped) = match root_place.base { PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }) => { (true, false) } PlaceBase::Static(box Static { - kind: StaticKind::Static(_), + kind: StaticKind::Static, .. }) => { // Thread-locals might be dropped after the function exits, but @@ -2155,7 +2155,7 @@ fn is_mutable<'d>( // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), projection: None, @@ -2167,7 +2167,8 @@ fn is_mutable<'d>( }), PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Static(def_id), + kind: StaticKind::Static, + def_id, .. }), projection: None, diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 937c6383be3..091b3eeb05f 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -149,7 +149,7 @@ pub(super) fn report_mutability_error( PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), projection: None, @@ -158,7 +158,8 @@ pub(super) fn report_mutability_error( PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Static(def_id), + kind: StaticKind::Static, + def_id, .. }), projection: None, diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 4b4477756ba..35dd5b5d7eb 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -421,7 +421,7 @@ fn sanitize_place( let mut place_ty = match place_base { PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), - PlaceBase::Static(box Static { kind, ty: sty }) => { + PlaceBase::Static(box Static { kind, ty: sty, def_id }) => { let sty = self.sanitize_type(place, sty); let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, @@ -445,7 +445,7 @@ fn sanitize_place( }; }; match kind { - StaticKind::Promoted(promoted) => { + StaticKind::Promoted(promoted, _) => { if !self.errors_reported { let promoted_body = &self.promoted[*promoted]; self.sanitize_promoted(promoted_body, location); @@ -454,7 +454,7 @@ fn sanitize_place( check_err(self, place, promoted_ty, sty); } } - StaticKind::Static(def_id) => { + StaticKind::Static => { let ty = self.tcx().type_of(*def_id); let ty = self.cx.normalize(ty, location); @@ -471,7 +471,7 @@ fn sanitize_place( let is_promoted = match place { Place { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), projection: None, diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 72d5588c341..5caba637ccc 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -46,9 +46,9 @@ fn ignore_borrow( } } } - PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) => + PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) => false, - PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => { + PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => { tcx.is_mutable_static(*def_id) } }; diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 4dd2794f113..4f469174b39 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -329,11 +329,11 @@ fn place_base_conflict<'tcx>( } (PlaceBase::Static(s1), PlaceBase::Static(s2)) => { match (&s1.kind, &s2.kind) { - (StaticKind::Static(def_id_1), StaticKind::Static(def_id_2)) => { - if def_id_1 != def_id_2 { + (StaticKind::Static, StaticKind::Static) => { + if s1.def_id != s2.def_id { debug!("place_element_conflict: DISJOINT-STATIC"); Overlap::Disjoint - } else if tcx.is_mutable_static(*def_id_1) { + } else if tcx.is_mutable_static(s1.def_id) { // We ignore mutable statics - they can only be unsafe code. debug!("place_element_conflict: IGNORE-STATIC-MUT"); Overlap::Disjoint @@ -342,7 +342,7 @@ fn place_base_conflict<'tcx>( Overlap::EqualOrDisjoint } }, - (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => { + (StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => { if promoted_1 == promoted_2 { if let ty::Array(_, len) = s1.ty.sty { if let Some(0) = len.try_eval_usize(tcx, param_env) { diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 7005f274e0e..98cf4bba1c7 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -126,7 +126,8 @@ fn expr_as_place( ExprKind::StaticRef { id } => block.and(Place { base: PlaceBase::Static(Box::new(Static { ty: expr.ty, - kind: StaticKind::Static(id), + kind: StaticKind::Static, + def_id: id, })), projection: None, }), diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 85f9cbd3758..23c9e7fdf67 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -585,7 +585,7 @@ pub(super) fn eval_static_to_mplace( use rustc::mir::StaticKind; Ok(match place_static.kind { - StaticKind::Promoted(promoted) => { + StaticKind::Promoted(promoted, _) => { let instance = self.frame().instance; self.const_eval_raw(GlobalId { instance, @@ -593,11 +593,11 @@ pub(super) fn eval_static_to_mplace( })? } - StaticKind::Static(def_id) => { + StaticKind::Static => { let ty = place_static.ty; assert!(!ty.needs_subst()); let layout = self.layout_of(ty)?; - let instance = ty::Instance::mono(*self.tcx, def_id); + let instance = ty::Instance::mono(*self.tcx, place_static.def_id); let cid = GlobalId { instance, promoted: None diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 9d80163f30f..512ace1a472 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -180,7 +180,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::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; @@ -661,7 +661,7 @@ fn visit_place_base(&mut self, _context: mir::visit::PlaceContext, location: Location) { match place_base { - PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => { + PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => { debug!("visiting static {:?} @ {:?}", def_id, location); let tcx = self.tcx; @@ -670,8 +670,23 @@ fn visit_place_base(&mut self, self.output.push(MonoItem::Static(*def_id)); } } - PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => { - // FIXME: should we handle promoteds here instead of eagerly in collect_neighbours? + PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted, substs), def_id, .. }) => { + debug!("collecting promoted(def_id: {:?}, promoted: {:?}, substs: {:?})", def_id, promoted, substs); + debug!("param_substs: {:?}", self.param_substs); + let param_env = ty::ParamEnv::reveal_all(); + let cid = GlobalId { + instance: Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)), + promoted: Some(*promoted), + }; + debug!("cid: {:?}", cid); + match self.tcx.const_eval(param_env.and(cid)) { + Ok(val) => collect_const(self.tcx, val, substs, self.output), + Err(ErrorHandled::Reported) => {}, + Err(ErrorHandled::TooGeneric) => { + let span = self.tcx.promoted_mir(*def_id)[*promoted].span; + span_bug!(span, "collection encountered polymorphic constant") + }, + } } PlaceBase::Local(_) => { // Locals have no relevance for collector @@ -1231,24 +1246,6 @@ fn collect_neighbours<'tcx>( output, param_substs: instance.substs, }.visit_body(&body); - - if let ty::InstanceDef::Item(def_id) = instance.def { - let param_env = ty::ParamEnv::reveal_all(); - let promoted = tcx.promoted_mir(def_id); - for (promoted, promoted_body) in promoted.iter_enumerated() { - let cid = GlobalId { - instance, - promoted: Some(promoted), - }; - match tcx.const_eval(param_env.and(cid)) { - Ok(val) => collect_const(tcx, val, instance.substs, output), - Err(ErrorHandled::Reported) => {}, - Err(ErrorHandled::TooGeneric) => span_bug!( - promoted_body.span, "collection encountered polymorphic constant", - ), - } - } - } } fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String { diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index d5c5267a119..539922c54d1 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -205,10 +205,10 @@ fn visit_place(&mut self, PlaceBase::Local(..) => { // Locals are safe. } - PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => { + PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => { bug!("unsafety checking should happen before promotion") } - PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => { + PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => { if self.tcx.is_mutable_static(*def_id) { self.require_unsafe("use of mutable static", "mutable statics can be mutated by multiple threads: aliasing \ diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 9aeef16ba1e..b6146b6b722 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -285,7 +285,7 @@ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option place.iterate(|place_base, place_projection| { let mut eval = match place_base { PlaceBase::Local(loc) => self.get_const(*loc).clone()?, - PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..}) => { + PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted, _), ..}) => { let generics = self.tcx.generics_of(self.source.def_id()); if generics.requires_monomorphization(self.tcx) { // FIXME: can't handle code with generics diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 19a8769ce16..533e08f5e1f 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -394,7 +394,6 @@ fn inline_call(&self, let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len()); - let promoted_map = IndexVec::with_capacity(self.tcx.promoted_mir(callsite.callee).len()); for mut scope in callee_body.source_scopes.iter().cloned() { if scope.parent_scope.is_none() { @@ -420,11 +419,6 @@ fn inline_call(&self, local_map.push(idx); } - //TODO fixme - //promoted_map.extend( - // self.tcx.promoted_mir(callsite.callee).iter().cloned().map(|p| caller_body.promoted.push(p)) - //); - // If the call is something like `a[*i] = f(i)`, where // `i : &mut usize`, then just duplicating the `a[*i]` // Place could result in two different locations if `f` @@ -485,12 +479,12 @@ fn dest_needs_borrow(place: &Place<'_>) -> bool { args: &args, local_map, scope_map, - promoted_map, - _callsite: callsite, + callsite, destination: dest, return_block, cleanup_block: cleanup, - in_cleanup_block: false + in_cleanup_block: false, + tcx: self.tcx, }; @@ -645,12 +639,12 @@ struct Integrator<'a, 'tcx> { args: &'a [Local], local_map: IndexVec, scope_map: IndexVec, - promoted_map: IndexVec, - _callsite: CallSite<'tcx>, + callsite: CallSite<'tcx>, destination: Place<'tcx>, return_block: BasicBlock, cleanup_block: Option, in_cleanup_block: bool, + tcx: TyCtxt<'tcx>, } impl<'a, 'tcx> Integrator<'a, 'tcx> { @@ -701,14 +695,14 @@ fn visit_place(&mut self, }, Place { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted), + kind: StaticKind::Promoted(_, substs), .. }), projection: None, } => { - if let Some(p) = self.promoted_map.get(*promoted).cloned() { - *promoted = p; - } + let adjusted_substs = substs.subst(self.tcx, self.callsite.substs); + debug!("replacing substs {:?} with {:?}", substs, adjusted_substs); + *substs = adjusted_substs; }, _ => self.super_place(place, _ctxt, _location) } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 7015e2c087f..cb0ce77d5c0 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -12,9 +12,11 @@ //! initialization and can otherwise silence errors, if //! move analysis runs after promotion on broken MIR. +use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; +use rustc::ty::subst::InternalSubsts; use rustc::ty::TyCtxt; use syntax_pos::Span; @@ -293,17 +295,18 @@ fn promote_temp(&mut self, temp: Local) -> Local { new_temp } - fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Option> { + fn promote_candidate(mut self, def_id: DefId, candidate: Candidate, next_promoted_id: usize) -> Option> { let mut operand = { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); - let mut promoted_place = |ty, span| { + let mut promoted_place = |ty, substs, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); Place { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted_id), - ty + kind: StaticKind::Promoted(promoted_id, substs), + ty, + def_id, }), projection: None, } @@ -319,7 +322,14 @@ fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> let span = statement.source_info.span; Operand::Move(Place { - base: mem::replace(&mut place.base, promoted_place(ty, span).base), + base: mem::replace( + &mut place.base, + promoted_place( + ty, + InternalSubsts::identity_for_item(self.tcx, def_id), + span, + ).base + ), projection: None, }) } @@ -332,7 +342,16 @@ fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => { let ty = operand.ty(local_decls, self.tcx); let span = statement.source_info.span; - mem::replace(operand, Operand::Copy(promoted_place(ty, span))) + mem::replace( + operand, + Operand::Copy( + promoted_place( + ty, + InternalSubsts::identity_for_item(self.tcx, def_id), + span, + ) + ) + ) } _ => bug!() } @@ -343,7 +362,12 @@ fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> TerminatorKind::Call { ref mut args, .. } => { let ty = args[index].ty(local_decls, self.tcx); let span = terminator.source_info.span; - let operand = Operand::Copy(promoted_place(ty, span)); + let operand = + Operand::Copy( + promoted_place( + ty, + InternalSubsts::identity_for_item(self.tcx, def_id), + span)); mem::replace(&mut args[index], operand) } // We expected a `TerminatorKind::Call` for which we'd like to promote an @@ -385,6 +409,7 @@ fn visit_local(&mut self, } pub fn promote_candidates<'tcx>( + def_id: DefId, body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>, mut temps: IndexVec, @@ -442,7 +467,7 @@ pub fn promote_candidates<'tcx>( keep_original: false }; - if let Some(promoted) = promoter.promote_candidate(candidate, promotions.len()) { + if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) { promotions.push(promoted); } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index dd4db479cc0..70a394ad983 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -223,7 +223,7 @@ fn in_place(cx: &ConstCx<'_, 'tcx>, place: PlaceRef<'_, 'tcx>) -> bool { } => Self::in_local(cx, *local), PlaceRef { base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), projection: None, @@ -434,13 +434,13 @@ impl Qualif for IsNotPromotable { fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool { match static_.kind { - StaticKind::Promoted(_) => unreachable!(), - StaticKind::Static(def_id) => { + StaticKind::Promoted(_, _) => unreachable!(), + StaticKind::Static => { // Only allow statics (not consts) to refer to other statics. let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut; !allowed || - cx.tcx.get_attrs(def_id).iter().any( + cx.tcx.get_attrs(static_.def_id).iter().any( |attr| attr.check_name(sym::thread_local) ) } @@ -873,7 +873,7 @@ fn assign(&mut self, dest: &Place<'tcx>, source: ValueSource<'_, 'tcx>, location dest_projection = &proj.base; }, (&PlaceBase::Static(box Static { - kind: StaticKind::Promoted(_), + kind: StaticKind::Promoted(..), .. }), None) => bug!("promoteds don't exist yet during promotion"), (&PlaceBase::Static(box Static{ kind: _, .. }), None) => { @@ -1028,10 +1028,10 @@ fn visit_place_base( self.super_place_base(place_base, context, location); match place_base { PlaceBase::Local(_) => {} - PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) => { + PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) => { unreachable!() } - PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => { + PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => { if self.tcx .get_attrs(*def_id) .iter() @@ -1661,7 +1661,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx // Do the actual promotion, now that we know what's viable. self.promoted.set( - Some(promote_consts::promote_candidates(body, tcx, temps, candidates)) + Some(promote_consts::promote_candidates(def_id, body, tcx, temps, candidates)) ); } else { if !body.control_flow_destroyed.is_empty() { diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 334d0cee9fb..56093527aee 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -264,11 +264,11 @@ fn check_place( } match place_base { - PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. }) => { + PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => { Err((span, "cannot access `static` items in const fn".into())) } PlaceBase::Local(_) - | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => Ok(()), + | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()), } }) }