Skip to content

Treat constant values as mir::ConstantKind::Val #94059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ pub enum StackPopCleanup {
}

/// State of a local variable including a memoized layout
#[derive(Clone, PartialEq, Eq, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, HashStable)]
pub struct LocalState<'tcx, Tag: Provenance = AllocId> {
pub value: LocalValue<Tag>,
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
Expand Down Expand Up @@ -714,13 +714,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.size_and_align_of(&mplace.meta, &mplace.layout)
}

#[instrument(skip(self, body, return_place, return_to_block), level = "debug")]
pub fn push_stack_frame(
&mut self,
instance: ty::Instance<'tcx>,
body: &'mir mir::Body<'tcx>,
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> {
debug!("body: {:#?}", body);
// first push a stack frame so we have access to the local substs
let pre_frame = Frame {
body,
Expand Down Expand Up @@ -824,6 +826,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// `Drop` impls for any locals that have been initialized at this point.
/// The cleanup block ends with a special `Resume` terminator, which will
/// cause us to continue unwinding.
#[instrument(skip(self), level = "debug")]
pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> {
info!(
"popping stack frame ({})",
Expand Down Expand Up @@ -876,6 +879,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(());
}

debug!("locals: {:#?}", frame.locals);

// Cleanup: deallocate all locals that are backed by an allocation.
for local in &frame.locals {
self.deallocate_local(local.value)?;
Expand Down Expand Up @@ -935,6 +940,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(())
}

#[instrument(skip(self), level = "debug")]
fn deallocate_local(&mut self, local: LocalValue<M::PointerTag>) -> InterpResult<'tcx> {
if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local {
// All locals have a backing allocation, even if the allocation is empty
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ pub fn intern_const_alloc_recursive<
// pointers, ... So we can't intern them according to their type rules

let mut todo: Vec<_> = leftover_allocations.iter().cloned().collect();
debug!(?todo);
debug!("dead_alloc_map: {:#?}", ecx.memory.dead_alloc_map);
while let Some(alloc_id) = todo.pop() {
if let Some((_, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) {
// We can't call the `intern_shallow` method here, as its logic is tailored to safe
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Ok(new_ptr)
}

#[instrument(skip(self), level = "debug")]
pub fn deallocate(
&mut self,
ptr: Pointer<Option<M::PointerTag>>,
Expand Down Expand Up @@ -305,6 +306,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
.into());
};

debug!(?alloc);

if alloc.mutability == Mutability::Not {
throw_ub_format!("deallocating immutable allocation {}", alloc_id);
}
Expand Down
30 changes: 29 additions & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2554,7 +2554,14 @@ impl<'tcx> Constant<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for ConstantKind<'tcx> {
#[inline]
fn from(ct: ty::Const<'tcx>) -> Self {
Self::Ty(ct)
match ct.val() {
ty::ConstKind::Value(cv) => {
// FIXME Once valtrees are introduced we need to convert those
// into `ConstValue` instances here
Self::Val(cv, ct.ty())
}
_ => Self::Ty(ct),
}
}
}

Expand Down Expand Up @@ -2635,6 +2642,27 @@ impl<'tcx> ConstantKind<'tcx> {
Self::Val(val, _) => val.try_to_machine_usize(tcx),
}
}

pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
let cv = ConstValue::from_bool(v);
Self::Val(cv, tcx.types.bool)
}

pub fn from_zero_sized(ty: Ty<'tcx>) -> Self {
let cv = ConstValue::Scalar(Scalar::ZST);
Self::Val(cv, ty)
}

pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
let ty = tcx.types.usize;
let size = tcx
.layout_of(ty::ParamEnv::empty().and(ty))
.unwrap_or_else(|e| bug!("could not compute layout for {:?}: {:?}", ty, e))
.size;
let cv = ConstValue::Scalar(Scalar::from_uint(n as u128, size));

Self::Val(cv, ty)
}
}

/// A collection of projections into user types.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/build/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::build::CFG;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::TyCtxt;

impl<'tcx> CFG<'tcx> {
crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<'tcx> CFG<'tcx> {
Rvalue::Use(Operand::Constant(Box::new(Constant {
span: source_info.span,
user_ty: None,
literal: ty::Const::zero_sized(tcx, tcx.types.unit).into(),
literal: ConstantKind::from_zero_sized(tcx.types.unit),
}))),
);
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_hir as hir;
use rustc_index::vec::Idx;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use std::iter;

impl<'a, 'tcx> Builder<'a, 'tcx> {
Expand Down Expand Up @@ -107,7 +107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant {
span: expr_span,
user_ty: None,
literal: ty::Const::from_bool(this.tcx, true).into(),
literal: ConstantKind::from_bool(this.tcx, true),
},
);

Expand All @@ -118,7 +118,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant {
span: expr_span,
user_ty: None,
literal: ty::Const::from_bool(this.tcx, false).into(),
literal: ConstantKind::from_bool(this.tcx, false),
},
);

Expand Down Expand Up @@ -183,8 +183,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span: expr_span,
user_ty: None,
literal: match op {
LogicalOp::And => ty::Const::from_bool(this.tcx, false).into(),
LogicalOp::Or => ty::Const::from_bool(this.tcx, true).into(),
LogicalOp::And => ConstantKind::from_bool(this.tcx, false),
LogicalOp::Or => ConstantKind::from_bool(this.tcx, true),
},
},
);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant {
span: source_info.span,
user_ty: None,
literal: ty::Const::from_usize(self.tcx, value).into(),
literal: ConstantKind::from_usize(self.tcx, value),
},
);
temp
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ impl<'tcx> Cx<'tcx> {

hir::ExprKind::ConstBlock(ref anon_const) => {
let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);

// FIXME Do we want to use `from_inline_const` once valtrees
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that function is only used from here? . If so, we can move it onto constantkind and turn inline consts always into mir constants

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is only used from here. But changing from_inline_const would require some changes in how we process patterns during thir construction. The next PR will be about changing thir to use mir::Constant instead of ty::Const, so would also include the change to from_inline_const. I would prefer to leave this as is in this PR, unless you want this change right now.

// are introduced? This would create `ValTree`s that will never be used...
let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);

ExprKind::ConstBlock { value }
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,21 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
&mut self,
constant: mir::ConstantKind<'tcx>,
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
constant.try_super_fold_with(self)
let constant_kind = match constant {
mir::ConstantKind::Ty(c) => {
let const_folded = c.try_fold_with(self)?;
match const_folded.val() {
ty::ConstKind::Value(cv) => {
// FIXME With Valtrees we need to convert `cv: ValTree`
// to a `ConstValue` here.
mir::ConstantKind::Val(cv, const_folded.ty())
}
_ => mir::ConstantKind::Ty(const_folded),
}
}
mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?,
};

Ok(constant_kind)
}
}
8 changes: 4 additions & 4 deletions src/test/mir-opt/inline/inline_generator.main.Inline.diff
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@
- bb1: {
+ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:15:5: 15:41
_3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:9:23: 9:31
- _2 = Pin::<&mut impl Generator<bool>>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:9:14: 9:32
- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:41]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:9:14: 9:32
- // mir::Constant
- // + span: $DIR/inline-generator.rs:9:14: 9:22
- // + user_ty: UserType(0)
- // + literal: Const { ty: fn(&mut impl Generator<bool>) -> Pin<&mut impl Generator<bool>> {Pin::<&mut impl Generator<bool>>::new}, val: Value(Scalar(<ZST>)) }
- // + literal: Const { ty: fn(&mut [generator@$DIR/inline-generator.rs:15:5: 15:41]) -> Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:41]> {Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:41]>::new}, val: Value(Scalar(<ZST>)) }
- }
-
- bb2: {
Expand All @@ -62,10 +62,10 @@
+ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:9:31: 9:32
- _1 = <impl Generator<bool> as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:41] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
- // mir::Constant
- // + span: $DIR/inline-generator.rs:9:33: 9:39
- // + literal: Const { ty: for<'r> fn(Pin<&'r mut impl Generator<bool>>, bool) -> GeneratorState<<impl Generator<bool> as Generator<bool>>::Yield, <impl Generator<bool> as Generator<bool>>::Return> {<impl Generator<bool> as Generator<bool>>::resume}, val: Value(Scalar(<ZST>)) }
- // + literal: Const { ty: for<'r> fn(Pin<&'r mut [generator@$DIR/inline-generator.rs:15:5: 15:41]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:41] as Generator<bool>>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:41] as Generator<bool>>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:41] as Generator<bool>>::resume}, val: Value(Scalar(<ZST>)) }
+ StorageLive(_7); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
+ _7 = const false; // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
+ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
Expand Down
4 changes: 2 additions & 2 deletions src/test/mir-opt/inline/issue_78442.bar.Inline.diff
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
bb1: {
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- // mir::Constant
- // + span: $DIR/issue-78442.rs:11:5: 11:15
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL
}

Expand Down
6 changes: 4 additions & 2 deletions src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
_2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
+ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit surprised that this changed with your pr 🤔 but as its definitely a positive change, i don't necessarily care about why this changed 🤷

// mir::Constant
// + span: $DIR/issue-78442.rs:11:5: 11:15
// + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
+ // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
}

bb2: {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) ->
let mut _0: bool; // return place in scope 0 at $DIR/named-lifetimes-basic.rs:12:81: 12:85

bb0: {
_0 = const Const(Value(Scalar(0x01)): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:12:88: 12:92
_0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:12:88: 12:92
return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:12:94: 12:94
}
}
14 changes: 7 additions & 7 deletions src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ fn main() -> () {

bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
_1 = [const Const(Value(Scalar(0x00000001)): usize), const Const(Value(Scalar(0x00000002)): usize), const Const(Value(Scalar(0x00000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
_1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
_3 = const Const(Value(Scalar(0x00000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
_3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
_4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
_5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
Expand All @@ -62,15 +62,15 @@ fn main() -> () {
_6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14
FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
_7 = const Const(Value(Scalar(0x01)): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
_7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
switchInt(move _7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
}

bb2: {
StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
_9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
_8 = Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
_8 = ConstValue(Scalar(<ZST>): fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
// mir::Constant
// + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
Expand All @@ -79,21 +79,21 @@ fn main() -> () {
bb3: {
StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:17: 21:18
StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
_0 = const Const(Value(Scalar(<ZST>)): ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:13: 22:6
_0 = const ConstValue(Scalar(<ZST>): ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:13: 22:6
goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
}

bb4: {
StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
_10 = Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x00000016)): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
_10 = ConstValue(Scalar(<ZST>): fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
// mir::Constant
// + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
}

bb5: {
StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:18: 23:19
_0 = const Const(Value(Scalar(<ZST>)): ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:22:12: 24:6
_0 = const ConstValue(Scalar(<ZST>): ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:22:12: 24:6
goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
}

Expand Down
Loading