diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 5642d01de5d83..2126487da02fd 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2533,7 +2533,7 @@ pub enum ConstantKind<'tcx> { impl<'tcx> Constant<'tcx> { pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option { - match self.literal.try_to_scalar() { + match self.literal.const_for_ty()?.val().try_to_scalar() { Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) { GlobalAlloc::Static(def_id) => { assert!(!tcx.is_thread_local_static(def_id)); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index d1c27c84dd5de..6320b055ab7dc 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -17,8 +17,9 @@ use rustc_middle::mir::interpret::{ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::MirSource; use rustc_middle::mir::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_target::abi::Size; +use std::ops::ControlFlow; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements @@ -663,7 +664,6 @@ pub fn write_allocations<'tcx>( fn alloc_ids_from_alloc(alloc: &Allocation) -> impl DoubleEndedIterator + '_ { alloc.relocations().values().map(|id| *id) } - fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator + '_ { match val { ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _size)) => { @@ -677,29 +677,17 @@ pub fn write_allocations<'tcx>( } } } - struct CollectAllocIds(BTreeSet); - - impl<'tcx> Visitor<'tcx> for CollectAllocIds { - fn visit_const(&mut self, c: ty::Const<'tcx>, _loc: Location) { + impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds { + fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { if let ty::ConstKind::Value(val) = c.val() { self.0.extend(alloc_ids_from_const(val)); } - } - - fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) { - match c.literal { - ConstantKind::Ty(c) => self.visit_const(c, loc), - ConstantKind::Val(val, _) => { - self.0.extend(alloc_ids_from_const(val)); - } - } + c.super_visit_with(self) } } - let mut visitor = CollectAllocIds(Default::default()); - visitor.visit_body(body); - + body.visit_with(&mut visitor); // `seen` contains all seen allocations, including the ones we have *not* printed yet. // The protocol is to first `insert` into `seen`, and only if that returns `true` // then push to `todo`. diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 04bc0c8b52114..40dce281c82bf 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -17,7 +17,6 @@ use rustc_index::newtype_index; use rustc_index::vec::IndexVec; use rustc_middle::infer::canonical::Canonical; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{ BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection, }; @@ -420,8 +419,7 @@ pub enum ExprKind<'tcx> { /// This is only distinguished from `Literal` so that we can register some /// info for diagnostics. StaticRef { - alloc_id: AllocId, - ty: Ty<'tcx>, + literal: Const<'tcx>, def_id: DefId, }, /// Inline assembly, i.e. `asm!()`. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index b3e2cb132a273..95489ac3ab2c6 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -123,7 +123,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {} Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal), - StaticRef { .. } => {} + StaticRef { literal, def_id: _ } => visitor.visit_const(literal), InlineAsm { ref operands, template: _, options: _, line_spans: _ } => { for op in &**operands { use InlineAsmOperand::*; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 0c0b0f2bd05af..79ac09d523d07 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -1,7 +1,6 @@ //! See docs in build/expr/mod.rs use crate::build::Builder; -use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; @@ -27,12 +26,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(literal.ty(), ty); Constant { span, user_ty, literal: literal.into() } } - ExprKind::StaticRef { alloc_id, ty, .. } => { - let const_val = - ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &this.tcx)); - let literal = ConstantKind::Val(const_val, ty); - - Constant { span, user_ty: None, literal } + ExprKind::StaticRef { literal, .. } => { + Constant { span, user_ty: None, literal: literal.into() } } ExprKind::ConstBlock { value } => { Constant { span: span, user_ty: None, literal: value.into() } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 5a7e1d88dd03f..651edc827c320 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -8,6 +8,7 @@ use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; +use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp}; use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ @@ -940,8 +941,15 @@ impl<'tcx> Cx<'tcx> { let kind = if self.tcx.is_thread_local_static(id) { ExprKind::ThreadLocalRef(id) } else { - let alloc_id = self.tcx.create_static_alloc(id); - ExprKind::StaticRef { alloc_id, ty, def_id: id } + let ptr = self.tcx.create_static_alloc(id); + ExprKind::StaticRef { + literal: ty::Const::from_scalar( + self.tcx, + Scalar::from_pointer(ptr.into(), &self.tcx), + ty, + ), + def_id: id, + } }; ExprKind::Deref { arg: self.thir.exprs.push(Expr { ty, temp_lifetime, span: expr.span, kind }), diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir index f8a8afa92e0e6..8e02dca4fb8b6 100644 --- a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir @@ -9,9 +9,12 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 _2 = const {alloc1: &&[(Option, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 + // ty::Const + // + ty: &&[(std::option::Option, &[&str])] + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation.rs:8:5: 8:8 - // + literal: Const { ty: &&[(Option, &[&str])], val: Value(Scalar(alloc1)) } + // + literal: Const { ty: &&[(std::option::Option, &[&str])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9 StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9 diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir index 1f1d857425e5b..88cdbda2fae36 100644 --- a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir @@ -9,9 +9,12 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 _2 = const {alloc1: &&[(Option, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 + // ty::Const + // + ty: &&[(std::option::Option, &[&str])] + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation.rs:8:5: 8:8 - // + literal: Const { ty: &&[(Option, &[&str])], val: Value(Scalar(alloc1)) } + // + literal: Const { ty: &&[(std::option::Option, &[&str])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9 StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:8:8: 8:9 diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir index 8b5ad40c9f92c..059b721f5bb63 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir @@ -9,9 +9,12 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 _2 = const {alloc1: &&[(Option, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 + // ty::Const + // + ty: &&[(std::option::Option, &[&u8])] + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation2.rs:5:5: 5:8 - // + literal: Const { ty: &&[(Option, &[&u8])], val: Value(Scalar(alloc1)) } + // + literal: Const { ty: &&[(std::option::Option, &[&u8])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir index ef651f01c9b98..d6a97917d6226 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -9,9 +9,12 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 _2 = const {alloc1: &&[(Option, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 + // ty::Const + // + ty: &&[(std::option::Option, &[&u8])] + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation2.rs:5:5: 5:8 - // + literal: Const { ty: &&[(Option, &[&u8])], val: Value(Scalar(alloc1)) } + // + literal: Const { ty: &&[(std::option::Option, &[&u8])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir index 991cf40d1b7ce..32000340dcebf 100644 --- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir @@ -9,6 +9,9 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 + // ty::Const + // + ty: &&Packed + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation3.rs:5:5: 5:8 // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir index fb481697aa811..cac882333aeb9 100644 --- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir @@ -9,6 +9,9 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 + // ty::Const + // + ty: &&Packed + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const_allocation3.rs:5:5: 5:8 // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 666b805e822c1..bec0fa9c04957 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -8,6 +8,9 @@ promoted[0] in BAR: &[&i32; 1] = { bb0: { _3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 + // ty::Const + // + ty: &i32 + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index ad83e9c276e66..b480b25782564 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -18,7 +18,9 @@ - StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 - _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 + _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44 -+ // ty::Const + // ty::Const +- // + ty: &i32 +- // + val: Value(Scalar(alloc1)) + // + ty: &[&i32; 1] + // + val: Unevaluated(BAR, [], Some(promoted[0])) // mir::Constant diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 785c8386e88b5..c01b31525b6a6 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -8,6 +8,9 @@ promoted[0] in FOO: &[&i32; 1] = { bb0: { _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + // ty::Const + // + ty: *const i32 + // + val: Value(Scalar(alloc3)) // mir::Constant // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index a9cf3ca976797..ed48f5dc9dcbc 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -20,7 +20,9 @@ - StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 - _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55 -+ // ty::Const + // ty::Const +- // + ty: *const i32 +- // + val: Value(Scalar(alloc3)) + // + ty: &[&i32; 1] + // + val: Unevaluated(FOO, [], Some(promoted[0])) // mir::Constant diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff index 1fd92ddd46190..afc621784633e 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff @@ -24,6 +24,9 @@ StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 _4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 + // ty::Const + // + ty: *mut u32 + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19 // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) } diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff index 15b3e07664258..13ef30d89a076 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff @@ -17,6 +17,9 @@ StorageLive(_2); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16 StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16 _3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16 + // ty::Const + // + ty: &u8 + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/read_immutable_static.rs:7:13: 7:16 // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) } @@ -25,6 +28,9 @@ StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22 StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22 _5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22 + // ty::Const + // + ty: &u8 + // + val: Value(Scalar(alloc1)) // mir::Constant // + span: $DIR/read_immutable_static.rs:7:19: 7:22 // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }