diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index cd809807a12..03206af33bf 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,3 +1,4 @@ +use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::{mir::*, thir::*, ty}; use super::{parse_by_kind, PResult, ParseCtxt}; @@ -45,6 +46,8 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> { parse_by_kind!(self, expr_id, expr, "operand", @call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move), + @call("mir_static", args) => self.parse_static(args[0]), + @call("mir_static_mut", args) => self.parse_static(args[0]), ExprKind::Literal { .. } | ExprKind::NamedConst { .. } | ExprKind::NonHirLiteral { .. } @@ -79,4 +82,24 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ExprKind::VarRef { id } => Ok(self.block_map[id]), ) } + + fn parse_static(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> { + let expr_id = parse_by_kind!(self, expr_id, _, "static", + ExprKind::Deref { arg } => *arg, + ); + + parse_by_kind!(self, expr_id, expr, "static", + ExprKind::StaticRef { alloc_id, ty, .. } => { + let const_val = + ConstValue::Scalar(Scalar::from_pointer((*alloc_id).into(), &self.tcx)); + let literal = ConstantKind::Val(const_val, *ty); + + Ok(Operand::Constant(Box::new(Constant { + span: expr.span, + user_ty: None, + literal + }))) + }, + ) + } } diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 18011aa5e98..8ba1c122884 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -80,6 +80,8 @@ define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock); define!("mir_retag", fn Retag<T>(place: T)); define!("mir_retag_raw", fn RetagRaw<T>(place: T)); define!("mir_move", fn Move<T>(place: T) -> T); +define!("mir_static", fn Static<T>(s: T) -> &'static T); +define!("mir_static_mut", fn StaticMut<T>(s: T) -> *mut T); /// Convenience macro for generating custom MIR. /// diff --git a/src/test/mir-opt/building/custom/consts.rs b/src/test/mir-opt/building/custom/consts.rs index 98b087f1e58..ff4fe1a9324 100644 --- a/src/test/mir-opt/building/custom/consts.rs +++ b/src/test/mir-opt/building/custom/consts.rs @@ -18,6 +18,19 @@ fn consts<const C: u32>() { }) } +static S: i32 = 5; +static mut T: i32 = 10; +// EMIT_MIR consts.statics.built.after.mir +#[custom_mir(dialect = "built")] +fn statics() { + mir!({ + let _a: &i32 = Static(S); + let _b: *mut i32 = StaticMut(T); + Return() + }) +} + fn main() { consts::<5>(); + statics(); } diff --git a/src/test/mir-opt/building/custom/consts.statics.built.after.mir b/src/test/mir-opt/building/custom/consts.statics.built.after.mir new file mode 100644 index 00000000000..a193af729d5 --- /dev/null +++ b/src/test/mir-opt/building/custom/consts.statics.built.after.mir @@ -0,0 +1,27 @@ +// MIR for `statics` after built + +fn statics() -> () { + let mut _0: (); // return place in scope 0 at $DIR/consts.rs:25:14: 25:14 + let mut _1: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _1 = const {alloc1: &i32}; // scope 0 at $DIR/consts.rs:+0:1: +0:13 + // mir::Constant + // + span: $DIR/consts.rs:27:31: 27:32 + // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } + _2 = const {alloc2: *mut i32}; // scope 0 at $DIR/consts.rs:+0:1: +0:13 + // mir::Constant + // + span: $DIR/consts.rs:28:38: 28:39 + // + literal: Const { ty: *mut i32, val: Value(Scalar(alloc2)) } + return; // scope 0 at $DIR/consts.rs:+0:1: +0:13 + } +} + +alloc2 (static: T, size: 4, align: 4) { + 0a 00 00 00 │ .... +} + +alloc1 (static: S, size: 4, align: 4) { + 05 00 00 00 │ .... +}