]> git.lizzy.rs Git - rust.git/commitdiff
Move def_id out add substsref
authorWesley Wiser <wwiser@gmail.com>
Tue, 6 Aug 2019 01:11:55 +0000 (21:11 -0400)
committerWesley Wiser <wwiser@gmail.com>
Thu, 22 Aug 2019 10:36:30 +0000 (06:36 -0400)
19 files changed:
src/librustc/mir/mod.rs
src/librustc/mir/visit.rs
src/librustc_codegen_ssa/mir/block.rs
src/librustc_codegen_ssa/mir/place.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/mutability_errors.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/place_ext.rs
src/librustc_mir/borrow_check/places_conflict.rs
src/librustc_mir/build/expr/as_place.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_min_const_fn.rs

index 66f5eaeeda1c77f559f1f45d583f8714a69e84c3..69e98583b191c160486985fde4f3be6d588dfd2d 100644 (file)
@@ -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)
             }
         }
index 2d16e7bcc83716aae59408ad7eb39434aec7e84b..ac0e784d8bd12df36751c401869f27437cdd01b4 100644 (file)
@@ -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));
                     }
                 }
index dbce5ce4896a718f72e6ac17fd630262b807712a..d2a7571fde1e20336de06e51e2e982f7d3e8a0ba 100644 (file)
@@ -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,
                             }
index a632838ba24424b5714d1cd77b47a89c95d4c1a0..f7b94ea134cfcf7c09e7e4a6f6c6e65bcafb5fb7 100644 (file)
@@ -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,
             } => {
index 99899aa390c4a05c6cc0932d13b0aaf0c24137f0..251d4b727c7544b35427d1b81e5e3e8db6bfd809 100644 (file)
@@ -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,
index 05b396681ac06cee643d41b632758fe9f5357ee9..33cec78f3dfd5f93eaef28f18f42998af19f457f 100644 (file)
@@ -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,
index 937c6383be341e50f3a5429440820650ce969147..091b3eeb05f6cc761ab838841db1142c85047553 100644 (file)
@@ -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,
index 4b4477756bacc9771cfcf24ed0f38dc8372f5281..35dd5b5d7eb194492cebb6c5256cb266b9f42048 100644 (file)
@@ -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,
index 72d5588c34120523522ce5971e14c52f0c7b7f2b..5caba637ccc4abf1b7473d32e478d0da0d69daca 100644 (file)
@@ -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)
                 }
             };
index 4dd2794f11301bb977fd1d00fefdb7a341490c6c..4f469174b392d04df81651befb6a542d0c45d507 100644 (file)
@@ -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) {
index 7005f274e0e7def29f39b88d373595e4b1751c67..98cf4bba1c75fc68713441bd871dd0d88457804b 100644 (file)
@@ -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,
             }),
index 85f9cbd37589ab2260f0d66211e44d5539759128..23c9e7fdf67ce7c692f62723408c1200e68f887f 100644 (file)
@@ -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
index 9d80163f30f9d26276812828dc53ac52a8076769..512ace1a4728cc16dec51151688b2d75bf43ab9d 100644 (file)
 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 {
index d5c5267a119d369d183b361f082f47ea925fbe3d..539922c54d12d9530b49e755f2d6d93bf34266ce 100644 (file)
@@ -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 \
index 9aeef16ba1e38cc1680bcfb7607c8835463d7177..b6146b6b7227df927f66e5b06b1437b33d612fa3 100644 (file)
@@ -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
index 19a8769ce16331ad4783072318ba9c83963e89b9..533e08f5e1fd3cf40c446a4b8e61ae8d6ec16f7a 100644 (file)
@@ -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<Local, Local>,
     scope_map: IndexVec<SourceScope, SourceScope>,
-    promoted_map: IndexVec<Promoted, Promoted>,
-    _callsite: CallSite<'tcx>,
+    callsite: CallSite<'tcx>,
     destination: Place<'tcx>,
     return_block: BasicBlock,
     cleanup_block: Option<BasicBlock>,
     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)
         }
index 7015e2c087faa0670f87ad66409f2140f1dd9eed..cb0ce77d5c01483c8d740e6429feff64b3cd356d 100644 (file)
 //! 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<Body<'tcx>> {
+    fn promote_candidate(mut self, def_id: DefId, candidate: Candidate, next_promoted_id: usize) -> Option<Body<'tcx>> {
         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<Local, TempState>,
@@ -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);
         }
     }
index dd4db479cc00b29bae32b45dc4502cb85d07e3b0..70a394ad983300f02b114f39b57b5cecb2cacc18 100644 (file)
@@ -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() {
index 334d0cee9fbe7412a7e401c9e8afbf963c151f61..56093527aee249c3301af89bcc46922b4d1055ed 100644 (file)
@@ -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(()),
         }
     })
 }