diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 68d8766c90734..2412824efeb75 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -74,7 +74,7 @@ pub(super) fn build_custom_mir<'tcx>( let mut pctxt = ParseCtxt { tcx, thir, - source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, + source_scope: OUTERMOST_SOURCE_SCOPE, body: &mut body, local_map: FxHashMap::default(), block_map: FxHashMap::default(), @@ -128,7 +128,7 @@ fn parse_attribute(attr: &Attribute) -> MirPhase { struct ParseCtxt<'tcx, 'body> { tcx: TyCtxt<'tcx>, thir: &'body Thir<'tcx>, - source_info: SourceInfo, + source_scope: SourceScope, body: &'body mut Body<'tcx>, local_map: FxHashMap, diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs index 52cb0a4826d07..d72770e70c7ec 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -23,6 +23,7 @@ macro_rules! parse_by_kind { ( $self:ident, $expr_id:expr, + $expr_name:pat, $expected:literal, $( @call($name:literal, $args:ident) => $call_expr:expr, @@ -33,6 +34,8 @@ macro_rules! parse_by_kind { ) => {{ let expr_id = $self.preparse($expr_id); let expr = &$self.thir[expr_id]; + debug!("Trying to parse {:?} as {}", expr.kind, $expected); + let $expr_name = expr; match &expr.kind { $( ExprKind::Call { ty, fun: _, args: $args, .. } if { @@ -137,10 +140,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { /// This allows us to easily parse the basic blocks declarations, local declarations, and /// basic block definitions in order. pub fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { - let body = parse_by_kind!(self, expr_id, "whole body", + let body = parse_by_kind!(self, expr_id, _, "whole body", ExprKind::Block { block } => self.thir[*block].expr.unwrap(), ); - let (block_decls, rest) = parse_by_kind!(self, body, "body with block decls", + let (block_decls, rest) = parse_by_kind!(self, body, _, "body with block decls", ExprKind::Block { block } => { let block = &self.thir[*block]; (&block.stmts, block.expr.unwrap()) @@ -148,7 +151,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ); self.parse_block_decls(block_decls.iter().copied())?; - let (local_decls, rest) = parse_by_kind!(self, rest, "body with local decls", + let (local_decls, rest) = parse_by_kind!(self, rest, _, "body with local decls", ExprKind::Block { block } => { let block = &self.thir[*block]; (&block.stmts, block.expr.unwrap()) @@ -156,7 +159,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ); self.parse_local_decls(local_decls.iter().copied())?; - let block_defs = parse_by_kind!(self, rest, "body with block defs", + let block_defs = parse_by_kind!(self, rest, _, "body with block defs", ExprKind::Block { block } => &self.thir[*block].stmts, ); for (i, block_def) in block_defs.iter().enumerate() { @@ -223,22 +226,30 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } fn parse_block_def(&self, expr_id: ExprId) -> PResult> { - let block = parse_by_kind!(self, expr_id, "basic block", + let block = parse_by_kind!(self, expr_id, _, "basic block", ExprKind::Block { block } => &self.thir[*block], ); let mut data = BasicBlockData::new(None); for stmt_id in &*block.stmts { let stmt = self.statement_as_expr(*stmt_id)?; + let span = self.thir[stmt].span; let statement = self.parse_statement(stmt)?; - data.statements.push(Statement { source_info: self.source_info, kind: statement }); + data.statements.push(Statement { + source_info: SourceInfo { span, scope: self.source_scope }, + kind: statement, + }); } let Some(trailing) = block.expr else { return Err(self.expr_error(expr_id, "terminator")) }; + let span = self.thir[trailing].span; let terminator = self.parse_terminator(trailing)?; - data.terminator = Some(Terminator { source_info: self.source_info, kind: terminator }); + data.terminator = Some(Terminator { + source_info: SourceInfo { span, scope: self.source_scope }, + kind: terminator, + }); Ok(data) } 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 6d6176584f5f4..03206af33bfb5 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,10 +1,11 @@ +use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::{mir::*, thir::*, ty}; use super::{parse_by_kind, PResult, ParseCtxt}; impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { pub fn parse_statement(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, "statement", + parse_by_kind!(self, expr_id, _, "statement", @call("mir_retag", args) => { Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?))) }, @@ -20,7 +21,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } pub fn parse_terminator(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, "terminator", + parse_by_kind!(self, expr_id, _, "terminator", @call("mir_return", _args) => { Ok(TerminatorKind::Return) }, @@ -31,7 +32,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } fn parse_rvalue(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, "rvalue", + parse_by_kind!(self, expr_id, _, "rvalue", ExprKind::Borrow { borrow_kind, arg } => Ok( Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) ), @@ -43,14 +44,26 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } fn parse_operand(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, "operand", + 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 { .. } + | ExprKind::ZstLiteral { .. } + | ExprKind::ConstParam { .. } + | ExprKind::ConstBlock { .. } => { + Ok(Operand::Constant(Box::new( + crate::build::expr::as_constant::as_constant_inner(expr, |_| None, self.tcx) + ))) + }, _ => self.parse_place(expr_id).map(Operand::Copy), ) } fn parse_place(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, "place", + parse_by_kind!(self, expr_id, _, "place", ExprKind::Deref { arg } => Ok( self.parse_place(*arg)?.project_deeper(&[PlaceElem::Deref], self.tcx) ), @@ -59,14 +72,34 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } fn parse_local(&self, expr_id: ExprId) -> PResult { - parse_by_kind!(self, expr_id, "local", + parse_by_kind!(self, expr_id, _, "local", ExprKind::VarRef { id } => Ok(self.local_map[id]), ) } fn parse_block(&self, expr_id: ExprId) -> PResult { - parse_by_kind!(self, expr_id, "basic block", + parse_by_kind!(self, expr_id, _, "basic block", ExprKind::VarRef { id } => Ok(self.block_map[id]), ) } + + fn parse_static(&self, expr_id: ExprId) -> PResult> { + 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/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 32c0207cb680c..717c62315745b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -8,7 +8,9 @@ use rustc_middle::mir::interpret::{ }; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt}; +use rustc_middle::ty::{ + self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex, +}; use rustc_span::DUMMY_SP; use rustc_target::abi::Size; @@ -19,84 +21,87 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let this = self; let tcx = this.tcx; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; - match *kind { + match kind { ExprKind::Scope { region_scope: _, lint_level: _, value } => { - this.as_constant(&this.thir[value]) - } - ExprKind::Literal { lit, neg } => { - let literal = - match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) { - Ok(c) => c, - Err(LitToConstError::Reported(guar)) => { - ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar)) - } - Err(LitToConstError::TypeError) => { - bug!("encountered type error in `lit_to_mir_constant") - } - }; - - Constant { span, user_ty: None, literal } + this.as_constant(&this.thir[*value]) } - ExprKind::NonHirLiteral { lit, ref user_ty } => { - let user_ty = user_ty.as_ref().map(|user_ty| { - this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { + _ => as_constant_inner( + expr, + |user_ty| { + Some(this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span, user_ty: user_ty.clone(), inferred_ty: ty, - }) - }); - let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty); + })) + }, + tcx, + ), + } + } +} - Constant { span, user_ty: user_ty, literal } - } - ExprKind::ZstLiteral { ref user_ty } => { - let user_ty = user_ty.as_ref().map(|user_ty| { - this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span, - user_ty: user_ty.clone(), - inferred_ty: ty, - }) - }); - let literal = ConstantKind::Val(ConstValue::ZeroSized, ty); +pub fn as_constant_inner<'tcx>( + expr: &Expr<'tcx>, + push_cuta: impl FnMut(&Box>) -> Option, + tcx: TyCtxt<'tcx>, +) -> Constant<'tcx> { + let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; + match *kind { + ExprKind::Literal { lit, neg } => { + let literal = + match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) { + Ok(c) => c, + Err(LitToConstError::Reported(guar)) => { + ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar)) + } + Err(LitToConstError::TypeError) => { + bug!("encountered type error in `lit_to_mir_constant") + } + }; - Constant { span, user_ty: user_ty, literal } - } - ExprKind::NamedConst { def_id, substs, ref user_ty } => { - let user_ty = user_ty.as_ref().map(|user_ty| { - this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span, - user_ty: user_ty.clone(), - inferred_ty: ty, - }) - }); + Constant { span, user_ty: None, literal } + } + ExprKind::NonHirLiteral { lit, ref user_ty } => { + let user_ty = user_ty.as_ref().map(push_cuta).flatten(); - let uneval = - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); - let literal = ConstantKind::Unevaluated(uneval, ty); + let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty); - Constant { user_ty, span, literal } - } - ExprKind::ConstParam { param, def_id: _ } => { - let const_param = tcx.mk_const(param, expr.ty); - let literal = ConstantKind::Ty(const_param); + Constant { span, user_ty: user_ty, literal } + } + ExprKind::ZstLiteral { ref user_ty } => { + let user_ty = user_ty.as_ref().map(push_cuta).flatten(); - Constant { user_ty: None, span, literal } - } - ExprKind::ConstBlock { did: def_id, substs } => { - let uneval = - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); - let literal = ConstantKind::Unevaluated(uneval, ty); + let literal = ConstantKind::Val(ConstValue::ZeroSized, ty); - Constant { user_ty: None, span, literal } - } - ExprKind::StaticRef { alloc_id, ty, .. } => { - let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); - let literal = ConstantKind::Val(const_val, ty); + Constant { span, user_ty: user_ty, literal } + } + ExprKind::NamedConst { def_id, substs, ref user_ty } => { + let user_ty = user_ty.as_ref().map(push_cuta).flatten(); - Constant { span, user_ty: None, literal } - } - _ => span_bug!(span, "expression is not a valid constant {:?}", kind), + let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); + + Constant { user_ty, span, literal } + } + ExprKind::ConstParam { param, def_id: _ } => { + let const_param = tcx.mk_const(ty::ConstKind::Param(param), expr.ty); + let literal = ConstantKind::Ty(const_param); + + Constant { user_ty: None, span, literal } + } + ExprKind::ConstBlock { did: def_id, substs } => { + let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); + + Constant { user_ty: None, span, literal } + } + ExprKind::StaticRef { alloc_id, ty, .. } => { + let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); + let literal = ConstantKind::Val(const_val, ty); + + Constant { span, user_ty: None, literal } } + _ => span_bug!(span, "expression is not a valid constant {:?}", kind), } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0b76122913ebe..b456e2aa37a27 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -492,7 +492,7 @@ fn construct_fn<'tcx>( arguments, return_ty, return_ty_span, - span, + span_with_body, custom_mir_attr, ); } diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 1bacdc39148a1..8ba1c122884ca 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(place: T)); define!("mir_retag_raw", fn RetagRaw(place: T)); define!("mir_move", fn Move(place: T) -> T); +define!("mir_static", fn Static(s: T) -> &'static T); +define!("mir_static_mut", fn StaticMut(s: T) -> *mut T); /// Convenience macro for generating custom MIR. /// @@ -90,10 +92,14 @@ pub macro mir { ( $(let $local_decl:ident $(: $local_decl_ty:ty)? ;)* - $entry_block:block + { + $($entry:tt)* + } $( - $block_name:ident = $block:block + $block_name:ident = { + $($block:tt)* + } )* ) => {{ // First, we declare all basic blocks. @@ -109,11 +115,22 @@ pub macro mir { let $local_decl $(: $local_decl_ty)? ; )* + ::core::intrinsics::mir::__internal_extract_let!($($entry)*); + $( + ::core::intrinsics::mir::__internal_extract_let!($($block)*); + )* + { // Finally, the contents of the basic blocks - $entry_block; + ::core::intrinsics::mir::__internal_remove_let!({ + {} + { $($entry)* } + }); $( - $block; + ::core::intrinsics::mir::__internal_remove_let!({ + {} + { $($block)* } + }); )* RET @@ -121,3 +138,152 @@ pub macro mir { } }} } + +/// Helper macro that extracts the `let` declarations out of a bunch of statements. +/// +/// This macro is written using the "statement muncher" strategy. Each invocation parses the first +/// statement out of the input, does the appropriate thing with it, and then recursively calls the +/// same macro on the remainder of the input. +#[doc(hidden)] +pub macro __internal_extract_let { + // If it's a `let` like statement, keep the `let` + ( + let $var:ident $(: $ty:ty)? = $expr:expr; $($rest:tt)* + ) => { + let $var $(: $ty)?; + ::core::intrinsics::mir::__internal_extract_let!($($rest)*); + }, + // Due to #86730, we have to handle const blocks separately + ( + let $var:ident $(: $ty:ty)? = const $block:block; $($rest:tt)* + ) => { + let $var $(: $ty)?; + ::core::intrinsics::mir::__internal_extract_let!($($rest)*); + }, + // Otherwise, output nothing + ( + $stmt:stmt; $($rest:tt)* + ) => { + ::core::intrinsics::mir::__internal_extract_let!($($rest)*); + }, + ( + $expr:expr + ) => {} +} + +/// Helper macro that removes the `let` declarations from a bunch of statements. +/// +/// Because expression position macros cannot expand to statements + expressions, we need to be +/// slightly creative here. The general strategy is also statement munching as above, but the output +/// of the macro is "stored" in the subsequent macro invocation. Easiest understood via example: +/// ```text +/// invoke!( +/// { +/// { +/// x = 5; +/// } +/// { +/// let d = e; +/// Call() +/// } +/// } +/// ) +/// ``` +/// becomes +/// ```text +/// invoke!( +/// { +/// { +/// x = 5; +/// d = e; +/// } +/// { +/// Call() +/// } +/// } +/// ) +/// ``` +#[doc(hidden)] +pub macro __internal_remove_let { + // If it's a `let` like statement, remove the `let` + ( + { + { + $($already_parsed:tt)* + } + { + let $var:ident $(: $ty:ty)? = $expr:expr; + $($rest:tt)* + } + } + ) => { ::core::intrinsics::mir::__internal_remove_let!( + { + { + $($already_parsed)* + $var = $expr; + } + { + $($rest)* + } + } + )}, + // Due to #86730 , we have to handle const blocks separately + ( + { + { + $($already_parsed:tt)* + } + { + let $var:ident $(: $ty:ty)? = const $block:block; + $($rest:tt)* + } + } + ) => { ::core::intrinsics::mir::__internal_remove_let!( + { + { + $($already_parsed)* + $var = const $block; + } + { + $($rest)* + } + } + )}, + // Otherwise, keep going + ( + { + { + $($already_parsed:tt)* + } + { + $stmt:stmt; + $($rest:tt)* + } + } + ) => { ::core::intrinsics::mir::__internal_remove_let!( + { + { + $($already_parsed)* + $stmt; + } + { + $($rest)* + } + } + )}, + ( + { + { + $($already_parsed:tt)* + } + { + $expr:expr + } + } + ) => { + { + $($already_parsed)* + $expr + } + }, +} diff --git a/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir b/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir new file mode 100644 index 0000000000000..20dd251e7e308 --- /dev/null +++ b/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir @@ -0,0 +1,22 @@ +// MIR for `arbitrary_let` after built + +fn arbitrary_let(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/arbitrary_let.rs:+0:29: +0:32 + let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + goto -> bb2; // scope 0 at $DIR/arbitrary_let.rs:+4:13: +4:25 + } + + bb1: { + _0 = _3; // scope 0 at $DIR/arbitrary_let.rs:+7:13: +7:20 + return; // scope 0 at $DIR/arbitrary_let.rs:+8:13: +8:21 + } + + bb2: { + _3 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + goto -> bb1; // scope 0 at $DIR/arbitrary_let.rs:+12:13: +12:24 + } +} diff --git a/src/test/mir-opt/building/custom/arbitrary_let.rs b/src/test/mir-opt/building/custom/arbitrary_let.rs new file mode 100644 index 0000000000000..776df3151ffd7 --- /dev/null +++ b/src/test/mir-opt/building/custom/arbitrary_let.rs @@ -0,0 +1,28 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; +use core::ptr::{addr_of, addr_of_mut}; + +// EMIT_MIR arbitrary_let.arbitrary_let.built.after.mir +#[custom_mir(dialect = "built")] +fn arbitrary_let(x: i32) -> i32 { + mir!( + { + let y = x; + Goto(second) + } + third = { + RET = z; + Return() + } + second = { + let z = y; + Goto(third) + } + ) +} + +fn main() { + assert_eq!(arbitrary_let(5), 5); +} diff --git a/src/test/mir-opt/building/custom/consts.consts.built.after.mir b/src/test/mir-opt/building/custom/consts.consts.built.after.mir new file mode 100644 index 0000000000000..ba753cfc20ca2 --- /dev/null +++ b/src/test/mir-opt/building/custom/consts.consts.built.after.mir @@ -0,0 +1,22 @@ +// MIR for `consts` after built + +fn consts() -> () { + let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:27: +0:27 + let mut _1: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: i8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: fn() {consts::<10>}; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _1 = const 5_u8; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _2 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _3 = const C; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _4 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _5 = consts::<10>; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // mir::Constant + // + span: $DIR/consts.rs:16:18: 16:30 + // + literal: Const { ty: fn() {consts::<10>}, val: Value() } + return; // scope 0 at $DIR/consts.rs:+7:9: +7:17 + } +} diff --git a/src/test/mir-opt/building/custom/consts.rs b/src/test/mir-opt/building/custom/consts.rs new file mode 100644 index 0000000000000..ff4fe1a93246e --- /dev/null +++ b/src/test/mir-opt/building/custom/consts.rs @@ -0,0 +1,36 @@ +#![feature(custom_mir, core_intrinsics, inline_const)] + +extern crate core; +use core::intrinsics::mir::*; + +const D: i32 = 5; + +// EMIT_MIR consts.consts.built.after.mir +#[custom_mir(dialect = "built")] +fn consts() { + mir!({ + let _a = 5_u8; + let _b = const { 5_i8 }; + let _c = C; + let _d = D; + let _e = consts::<10>; + Return() + }) +} + +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 0000000000000..ee768e263ecdf --- /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:+0:14: +0: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 $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // 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 $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // 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:+4:9: +4:17 + } +} + +alloc2 (static: T, size: 4, align: 4) { + 0a 00 00 00 │ .... +} + +alloc1 (static: S, size: 4, align: 4) { + 05 00 00 00 │ .... +} diff --git a/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir index 4a5ddde4081e2..4d38d45c0f479 100644 --- a/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir +++ b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir @@ -5,10 +5,10 @@ fn immut_ref(_1: &i32) -> &i32 { let mut _2: *const i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL bb0: { - _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+0:1: +0:34 - Retag([raw] _2); // scope 0 at $DIR/references.rs:+0:1: +0:34 - _0 = &(*_2); // scope 0 at $DIR/references.rs:+0:1: +0:34 - Retag(_0); // scope 0 at $DIR/references.rs:+0:1: +0:34 - return; // scope 0 at $DIR/references.rs:+0:1: +0:34 + _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:29 + Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24 + _0 = &(*_2); // scope 0 at $DIR/references.rs:+7:13: +7:23 + Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23 + return; // scope 0 at $DIR/references.rs:+9:13: +9:21 } } diff --git a/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir index ec8509f69d14e..01bc8a9cd3580 100644 --- a/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir +++ b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir @@ -5,10 +5,10 @@ fn mut_ref(_1: &mut i32) -> &mut i32 { let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL bb0: { - _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+0:1: +0:40 - Retag([raw] _2); // scope 0 at $DIR/references.rs:+0:1: +0:40 - _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+0:1: +0:40 - Retag(_0); // scope 0 at $DIR/references.rs:+0:1: +0:40 - return; // scope 0 at $DIR/references.rs:+0:1: +0:40 + _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:33 + Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24 + _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+7:13: +7:26 + Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23 + return; // scope 0 at $DIR/references.rs:+9:13: +9:21 } } diff --git a/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir index a5a2834c2e1bf..d7560fde69c95 100644 --- a/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir +++ b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir @@ -6,13 +6,13 @@ fn simple(_1: i32) -> i32 { let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL bb0: { - _2 = _1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 - goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + _2 = _1; // scope 0 at $DIR/simple_assign.rs:+6:13: +6:22 + goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+7:13: +7:23 } bb1: { - _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 - _0 = _3; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 - return; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+11:13: +11:32 + _0 = _3; // scope 0 at $DIR/simple_assign.rs:+12:13: +12:24 + return; // scope 0 at $DIR/simple_assign.rs:+13:13: +13:21 } } diff --git a/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir index 6c90f0130a2e6..2b0e8f1047b53 100644 --- a/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir +++ b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir @@ -4,7 +4,7 @@ fn simple_ref(_1: &mut i32) -> &mut i32 { let mut _0: &mut i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:35: +0:43 bb0: { - _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:43 - return; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:43 + _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+2:9: +2:22 + return; // scope 0 at $DIR/simple_assign.rs:+3:9: +3:17 } }