pretty/mir: const value enums with no variants
This commit modifies the pretty printer and const eval in the MIR so that `destructure_const` (used in `pretty_print_const_value`) can handle enums with no variants (or types containing enums with no variants). Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
63b441aafb
commit
6fa7dc6527
@ -244,6 +244,6 @@ pub enum ClosureOutlivesSubject<'tcx> {
|
||||
/// The constituent parts of an ADT or array.
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct DestructuredConst<'tcx> {
|
||||
pub variant: VariantIdx,
|
||||
pub variant: Option<VariantIdx>,
|
||||
pub fields: &'tcx [&'tcx ty::Const<'tcx>],
|
||||
}
|
||||
|
@ -2001,6 +2001,8 @@ where
|
||||
}
|
||||
|
||||
let fields = match this.ty.kind {
|
||||
ty::Adt(def, _) if def.variants.is_empty() =>
|
||||
bug!("for_variant called on zero-variant enum"),
|
||||
ty::Adt(def, _) => def.variants[variant_index].fields.len(),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -2339,6 +2339,7 @@ impl<'tcx> AdtDef {
|
||||
/// Alternatively, if there is no explicit discriminant, returns the
|
||||
/// inferred discriminant directly.
|
||||
pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
|
||||
assert!(!self.variants.is_empty());
|
||||
let mut explicit_index = variant_index.as_u32();
|
||||
let expr_did;
|
||||
loop {
|
||||
|
@ -1177,8 +1177,13 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
p!(write(")"));
|
||||
}
|
||||
ty::Adt(def, substs) if def.variants.is_empty() => {
|
||||
p!(print_value_path(def.did, substs));
|
||||
}
|
||||
ty::Adt(def, substs) => {
|
||||
let variant_def = &def.variants[contents.variant];
|
||||
let variant_id =
|
||||
contents.variant.expect("destructed const of adt without variant id");
|
||||
let variant_def = &def.variants[variant_id];
|
||||
p!(print_value_path(variant_def.def_id, substs));
|
||||
|
||||
match variant_def.ctor_kind {
|
||||
|
@ -2099,6 +2099,9 @@ impl<'tcx> TyS<'tcx> {
|
||||
variant_index: VariantIdx,
|
||||
) -> Option<Discr<'tcx>> {
|
||||
match self.kind {
|
||||
TyKind::Adt(adt, _) if adt.variants.is_empty() => {
|
||||
bug!("discriminant_for_variant called on zero variant enum");
|
||||
}
|
||||
TyKind::Adt(adt, _) if adt.is_enum() => {
|
||||
Some(adt.discriminant_for_variant(tcx, variant_index))
|
||||
}
|
||||
|
@ -30,8 +30,10 @@ pub(crate) fn const_caller_location(
|
||||
ConstValue::Scalar(loc_place.ptr)
|
||||
}
|
||||
|
||||
// this function uses `unwrap` copiously, because an already validated constant
|
||||
// must have valid fields and can thus never fail outside of compiler bugs
|
||||
/// This function uses `unwrap` copiously, because an already validated constant
|
||||
/// must have valid fields and can thus never fail outside of compiler bugs. However, it is
|
||||
/// invoked from the pretty printer, where it can receive enums with no variants and e.g.
|
||||
/// `read_discriminant` needs to be able to handle that.
|
||||
pub(crate) fn destructure_const<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -41,17 +43,21 @@ pub(crate) fn destructure_const<'tcx>(
|
||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
|
||||
let op = ecx.eval_const_to_op(val, None).unwrap();
|
||||
|
||||
let variant = ecx.read_discriminant(op).unwrap().1;
|
||||
|
||||
// We go to `usize` as we cannot allocate anything bigger anyway.
|
||||
let field_count = match val.ty.kind {
|
||||
ty::Array(_, len) => usize::try_from(len.eval_usize(tcx, param_env)).unwrap(),
|
||||
ty::Adt(def, _) => def.variants[variant].fields.len(),
|
||||
ty::Tuple(substs) => substs.len(),
|
||||
let (field_count, variant, down) = match val.ty.kind {
|
||||
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
|
||||
ty::Adt(def, _) if def.variants.is_empty() => {
|
||||
return mir::DestructuredConst { variant: None, fields: tcx.arena.alloc_slice(&[]) };
|
||||
}
|
||||
ty::Adt(def, _) => {
|
||||
let variant = ecx.read_discriminant(op).unwrap().1;
|
||||
let down = ecx.operand_downcast(op, variant).unwrap();
|
||||
(def.variants[variant].fields.len(), Some(variant), down)
|
||||
}
|
||||
ty::Tuple(substs) => (substs.len(), None, op),
|
||||
_ => bug!("cannot destructure constant {:?}", val),
|
||||
};
|
||||
|
||||
let down = ecx.operand_downcast(op, variant).unwrap();
|
||||
let fields_iter = (0..field_count).map(|i| {
|
||||
let field_op = ecx.operand_field(down, i).unwrap();
|
||||
let val = op_to_const(&ecx, field_op);
|
||||
|
@ -800,7 +800,11 @@ impl<'tcx> Constructor<'tcx> {
|
||||
assert!(!adt.is_enum());
|
||||
VariantIdx::new(0)
|
||||
}
|
||||
ConstantValue(c) => cx.tcx.destructure_const(cx.param_env.and(c)).variant,
|
||||
ConstantValue(c) => cx
|
||||
.tcx
|
||||
.destructure_const(cx.param_env.and(c))
|
||||
.variant
|
||||
.expect("destructed const of adt without variant id"),
|
||||
_ => bug!("bad constructor {:?} for adt {:?}", self, adt),
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +275,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
PatKind::Variant {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index: destructured.variant,
|
||||
variant_index: destructured
|
||||
.variant
|
||||
.expect("destructed const of adt without variant id"),
|
||||
subpatterns: field_pats(destructured.fields),
|
||||
}
|
||||
}
|
||||
|
21
src/test/mir-opt/issue-72181-1.rs
Normal file
21
src/test/mir-opt/issue-72181-1.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// compile-flags: -Z mir-opt-level=1
|
||||
// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags.
|
||||
|
||||
#![feature(never_type)]
|
||||
#![allow(unused, invalid_value)]
|
||||
|
||||
enum Void {}
|
||||
|
||||
// EMIT_MIR rustc.f.mir_map.0.mir
|
||||
fn f(v: Void) -> ! {
|
||||
match v {}
|
||||
}
|
||||
|
||||
// EMIT_MIR rustc.main.mir_map.0.mir
|
||||
fn main() {
|
||||
let v: Void = unsafe {
|
||||
std::mem::transmute::<(), Void>(())
|
||||
};
|
||||
|
||||
f(v);
|
||||
}
|
37
src/test/mir-opt/issue-72181-1/rustc.f.mir_map.0.mir
Normal file
37
src/test/mir-opt/issue-72181-1/rustc.f.mir_map.0.mir
Normal file
@ -0,0 +1,37 @@
|
||||
// MIR for `f` 0 mir_map
|
||||
|
||||
fn f(_1: Void) -> ! {
|
||||
debug v => _1; // in scope 0 at $DIR/issue-72181-1.rs:10:6: 10:7
|
||||
let mut _0: !; // return place in scope 0 at $DIR/issue-72181-1.rs:10:18: 10:19
|
||||
let mut _2: !; // in scope 0 at $DIR/issue-72181-1.rs:10:20: 12:2
|
||||
let mut _3: !; // in scope 0 at $DIR/issue-72181-1.rs:11:5: 11:15
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:10:20: 12:2
|
||||
StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:11:5: 11:15
|
||||
FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/issue-72181-1.rs:11:11: 11:12
|
||||
unreachable; // scope 0 at $DIR/issue-72181-1.rs:11:11: 11:12
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181-1.rs:10:1: 12:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable; // scope 0 at $DIR/issue-72181-1.rs:11:5: 11:15
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3); // scope 0 at $DIR/issue-72181-1.rs:11:14: 11:15
|
||||
unreachable; // scope 0 at $DIR/issue-72181-1.rs:10:20: 12:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:12:1: 12:2
|
||||
goto -> bb5; // scope 0 at $DIR/issue-72181-1.rs:12:2: 12:2
|
||||
}
|
||||
|
||||
bb5: {
|
||||
return; // scope 0 at $DIR/issue-72181-1.rs:12:2: 12:2
|
||||
}
|
||||
}
|
67
src/test/mir-opt/issue-72181-1/rustc.main.mir_map.0.mir
Normal file
67
src/test/mir-opt/issue-72181-1/rustc.main.mir_map.0.mir
Normal file
@ -0,0 +1,67 @@
|
||||
// MIR for `main` 0 mir_map
|
||||
|
||||
| User Type Annotations
|
||||
| 0: Canonical { max_universe: U0, variables: [], value: Ty(Void) } at $DIR/issue-72181-1.rs:16:12: 16:16
|
||||
| 1: Canonical { max_universe: U0, variables: [], value: Ty(Void) } at $DIR/issue-72181-1.rs:16:12: 16:16
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:15:11: 15:11
|
||||
let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:15:11: 21:2
|
||||
let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10
|
||||
let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:17:41: 17:43
|
||||
let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:20:5: 20:9
|
||||
let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:20:7: 20:8
|
||||
scope 1 {
|
||||
debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:16:9: 16:10
|
||||
}
|
||||
scope 2 {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10
|
||||
StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43
|
||||
_3 = (); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43
|
||||
_2 = const std::intrinsics::transmute::<(), Void>(move _3) -> [return: bb2, unwind: bb1]; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44
|
||||
// ty::Const
|
||||
// + ty: unsafe extern "rust-intrinsic" fn(()) -> Void {std::intrinsics::transmute::<(), Void>}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181-1.rs:17:9: 17:40
|
||||
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {std::intrinsics::transmute::<(), Void>}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181-1.rs:15:1: 21:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:17:43: 17:44
|
||||
FakeRead(ForLet, _2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10
|
||||
AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:16:12: 16:16
|
||||
StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9
|
||||
StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8
|
||||
_5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8
|
||||
const f(move _5) -> bb1; // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9
|
||||
// ty::Const
|
||||
// + ty: fn(Void) -> ! {f}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181-1.rs:20:5: 20:6
|
||||
// + literal: Const { ty: fn(Void) -> ! {f}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:20:8: 20:9
|
||||
StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:20:9: 20:10
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:21:1: 21:2
|
||||
unreachable; // scope 0 at $DIR/issue-72181-1.rs:15:11: 21:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
goto -> bb5; // scope 0 at $DIR/issue-72181-1.rs:21:2: 21:2
|
||||
}
|
||||
|
||||
bb5: {
|
||||
return; // scope 0 at $DIR/issue-72181-1.rs:21:2: 21:2
|
||||
}
|
||||
}
|
28
src/test/mir-opt/issue-72181.rs
Normal file
28
src/test/mir-opt/issue-72181.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// compile-flags: -Z mir-opt-level=1
|
||||
// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags.
|
||||
|
||||
use std::mem;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Never {}
|
||||
|
||||
union Foo {
|
||||
a: u64,
|
||||
b: Never
|
||||
}
|
||||
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
// EMIT_MIR rustc.foo.mir_map.0.mir
|
||||
fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
|
||||
|
||||
// EMIT_MIR rustc.bar.mir_map.0.mir
|
||||
fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
|
||||
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
// EMIT_MIR rustc.main.mir_map.0.mir
|
||||
fn main() {
|
||||
let _ = mem::size_of::<Foo>();
|
||||
|
||||
let f = [Foo { a: 42 }, Foo { a: 10 }];
|
||||
let _ = unsafe { f[0].a };
|
||||
}
|
25
src/test/mir-opt/issue-72181/32bit/rustc.bar.mir_map.0.mir
Normal file
25
src/test/mir-opt/issue-72181/32bit/rustc.bar.mir_map.0.mir
Normal file
@ -0,0 +1,25 @@
|
||||
// MIR for `bar` 0 mir_map
|
||||
|
||||
fn bar(_1: [(Never, u32); 1]) -> u32 {
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:19:40: 19:43
|
||||
let _2: u32; // in scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
scope 1 {
|
||||
debug x => _2; // in scope 1 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
_2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
_0 = _2; // scope 1 at $DIR/issue-72181.rs:19:46: 19:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:19:48: 19:49
|
||||
goto -> bb2; // scope 0 at $DIR/issue-72181.rs:19:49: 19:49
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:19:1: 19:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:19:49: 19:49
|
||||
}
|
||||
}
|
37
src/test/mir-opt/issue-72181/32bit/rustc.foo.mir_map.0.mir
Normal file
37
src/test/mir-opt/issue-72181/32bit/rustc.foo.mir_map.0.mir
Normal file
@ -0,0 +1,37 @@
|
||||
// MIR for `foo` 0 mir_map
|
||||
|
||||
fn foo(_1: [(Never, u32); 1]) -> u32 {
|
||||
debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:16:8: 16:10
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:16:34: 16:37
|
||||
let _2: usize; // in scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
_2 = const 0usize; // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x00000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:16:43: 16:44
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
|
||||
_3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
_4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:16:1: 16:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:16:40: 16:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:16:48: 16:49
|
||||
goto -> bb3; // scope 0 at $DIR/issue-72181.rs:16:49: 16:49
|
||||
}
|
||||
|
||||
bb3: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:16:49: 16:49
|
||||
}
|
||||
}
|
93
src/test/mir-opt/issue-72181/32bit/rustc.main.mir_map.0.mir
Normal file
93
src/test/mir-opt/issue-72181/32bit/rustc.main.mir_map.0.mir
Normal file
@ -0,0 +1,93 @@
|
||||
// MIR for `main` 0 mir_map
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:23:11: 23:11
|
||||
let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:27:13: 27:30
|
||||
let _6: usize; // in scope 0 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
scope 1 {
|
||||
let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
scope 2 {
|
||||
debug f => _2; // in scope 2 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
_1 = const std::mem::size_of::<Foo>() -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
// ty::Const
|
||||
// + ty: fn() -> usize {std::mem::size_of::<Foo>}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:24:13: 24:32
|
||||
// + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:23:1: 28:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:24:34: 24:35
|
||||
StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
_3 = Foo { a: const 42u64 }; // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000002a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:26:23: 26:25
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) }
|
||||
StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
_4 = Foo { a: const 10u64 }; // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000000a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:26:38: 26:40
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) }
|
||||
_2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43
|
||||
StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
|
||||
StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
|
||||
FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30
|
||||
StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
_6 = const 0usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x00000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:27:24: 27:25
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
|
||||
_7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
_8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:27:22: 27:28
|
||||
StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:27:30: 27:31
|
||||
StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:27:30: 27:31
|
||||
_0 = const (); // scope 0 at $DIR/issue-72181.rs:23:11: 28:2
|
||||
// ty::Const
|
||||
// + ty: ()
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:23:11: 28:2
|
||||
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
|
||||
StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:28:1: 28:2
|
||||
goto -> bb4; // scope 0 at $DIR/issue-72181.rs:28:2: 28:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:28:2: 28:2
|
||||
}
|
||||
}
|
25
src/test/mir-opt/issue-72181/64bit/rustc.bar.mir_map.0.mir
Normal file
25
src/test/mir-opt/issue-72181/64bit/rustc.bar.mir_map.0.mir
Normal file
@ -0,0 +1,25 @@
|
||||
// MIR for `bar` 0 mir_map
|
||||
|
||||
fn bar(_1: [(Never, u32); 1]) -> u32 {
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:19:40: 19:43
|
||||
let _2: u32; // in scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
scope 1 {
|
||||
debug x => _2; // in scope 1 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
_2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:19:13: 19:14
|
||||
_0 = _2; // scope 1 at $DIR/issue-72181.rs:19:46: 19:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:19:48: 19:49
|
||||
goto -> bb2; // scope 0 at $DIR/issue-72181.rs:19:49: 19:49
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:19:1: 19:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:19:49: 19:49
|
||||
}
|
||||
}
|
37
src/test/mir-opt/issue-72181/64bit/rustc.foo.mir_map.0.mir
Normal file
37
src/test/mir-opt/issue-72181/64bit/rustc.foo.mir_map.0.mir
Normal file
@ -0,0 +1,37 @@
|
||||
// MIR for `foo` 0 mir_map
|
||||
|
||||
fn foo(_1: [(Never, u32); 1]) -> u32 {
|
||||
debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:16:8: 16:10
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:16:34: 16:37
|
||||
let _2: usize; // in scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
_2 = const 0usize; // scope 0 at $DIR/issue-72181.rs:16:43: 16:44
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x0000000000000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:16:43: 16:44
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
|
||||
_3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
_4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:16:40: 16:45
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:16:1: 16:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:16:40: 16:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:16:48: 16:49
|
||||
goto -> bb3; // scope 0 at $DIR/issue-72181.rs:16:49: 16:49
|
||||
}
|
||||
|
||||
bb3: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:16:49: 16:49
|
||||
}
|
||||
}
|
93
src/test/mir-opt/issue-72181/64bit/rustc.main.mir_map.0.mir
Normal file
93
src/test/mir-opt/issue-72181/64bit/rustc.main.mir_map.0.mir
Normal file
@ -0,0 +1,93 @@
|
||||
// MIR for `main` 0 mir_map
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:23:11: 23:11
|
||||
let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:27:13: 27:30
|
||||
let _6: usize; // in scope 0 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
scope 1 {
|
||||
let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
scope 2 {
|
||||
debug f => _2; // in scope 2 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
_1 = const std::mem::size_of::<Foo>() -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:24:13: 24:34
|
||||
// ty::Const
|
||||
// + ty: fn() -> usize {std::mem::size_of::<Foo>}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:24:13: 24:32
|
||||
// + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:23:1: 28:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:24:34: 24:35
|
||||
StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
_3 = Foo { a: const 42u64 }; // scope 1 at $DIR/issue-72181.rs:26:14: 26:27
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000002a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:26:23: 26:25
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) }
|
||||
StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
_4 = Foo { a: const 10u64 }; // scope 1 at $DIR/issue-72181.rs:26:29: 26:42
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000000a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:26:38: 26:40
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) }
|
||||
_2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43
|
||||
StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
|
||||
StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43
|
||||
FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10
|
||||
StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30
|
||||
StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
_6 = const 0usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x0000000000000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:27:24: 27:25
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
|
||||
_7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
_8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:27:22: 27:26
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:27:22: 27:28
|
||||
StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:27:30: 27:31
|
||||
StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:27:30: 27:31
|
||||
_0 = const (); // scope 0 at $DIR/issue-72181.rs:23:11: 28:2
|
||||
// ty::Const
|
||||
// + ty: ()
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:23:11: 28:2
|
||||
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
|
||||
StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:28:1: 28:2
|
||||
goto -> bb4; // scope 0 at $DIR/issue-72181.rs:28:2: 28:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:28:2: 28:2
|
||||
}
|
||||
}
|
25
src/test/mir-opt/issue-72181/rustc.bar.mir_map.0.mir
Normal file
25
src/test/mir-opt/issue-72181/rustc.bar.mir_map.0.mir
Normal file
@ -0,0 +1,25 @@
|
||||
// MIR for `bar` 0 mir_map
|
||||
|
||||
fn bar(_1: [(Never, u32); 1]) -> u32 {
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:18:40: 18:43
|
||||
let _2: u32; // in scope 0 at $DIR/issue-72181.rs:18:13: 18:14
|
||||
scope 1 {
|
||||
debug x => _2; // in scope 1 at $DIR/issue-72181.rs:18:13: 18:14
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:18:13: 18:14
|
||||
_2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:18:13: 18:14
|
||||
_0 = _2; // scope 1 at $DIR/issue-72181.rs:18:46: 18:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:18:48: 18:49
|
||||
goto -> bb2; // scope 0 at $DIR/issue-72181.rs:18:49: 18:49
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:18:1: 18:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:18:49: 18:49
|
||||
}
|
||||
}
|
37
src/test/mir-opt/issue-72181/rustc.foo.mir_map.0.mir
Normal file
37
src/test/mir-opt/issue-72181/rustc.foo.mir_map.0.mir
Normal file
@ -0,0 +1,37 @@
|
||||
// MIR for `foo` 0 mir_map
|
||||
|
||||
fn foo(_1: [(Never, u32); 1]) -> u32 {
|
||||
debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:15:8: 15:10
|
||||
let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:15:34: 15:37
|
||||
let _2: usize; // in scope 0 at $DIR/issue-72181.rs:15:43: 15:44
|
||||
let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:15:40: 15:45
|
||||
let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:15:40: 15:45
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:15:43: 15:44
|
||||
_2 = const 0usize; // scope 0 at $DIR/issue-72181.rs:15:43: 15:44
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x0000000000000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:15:43: 15:44
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
|
||||
_3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:15:40: 15:45
|
||||
_4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:15:40: 15:45
|
||||
assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:15:40: 15:45
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:15:1: 15:49
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:15:40: 15:47
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:15:48: 15:49
|
||||
goto -> bb3; // scope 0 at $DIR/issue-72181.rs:15:49: 15:49
|
||||
}
|
||||
|
||||
bb3: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:15:49: 15:49
|
||||
}
|
||||
}
|
93
src/test/mir-opt/issue-72181/rustc.main.mir_map.0.mir
Normal file
93
src/test/mir-opt/issue-72181/rustc.main.mir_map.0.mir
Normal file
@ -0,0 +1,93 @@
|
||||
// MIR for `main` 0 mir_map
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:21:11: 21:11
|
||||
let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:22:13: 22:34
|
||||
let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:24:14: 24:27
|
||||
let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:24:29: 24:42
|
||||
let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:25:13: 25:30
|
||||
let _6: usize; // in scope 0 at $DIR/issue-72181.rs:25:24: 25:25
|
||||
let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:25:22: 25:26
|
||||
let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:25:22: 25:26
|
||||
scope 1 {
|
||||
let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:24:9: 24:10
|
||||
scope 2 {
|
||||
debug f => _2; // in scope 2 at $DIR/issue-72181.rs:24:9: 24:10
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:22:13: 22:34
|
||||
_1 = const std::mem::size_of::<Foo>() -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:22:13: 22:34
|
||||
// ty::Const
|
||||
// + ty: fn() -> usize {std::mem::size_of::<Foo>}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:22:13: 22:32
|
||||
// + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-72181.rs:21:1: 26:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:22:34: 22:35
|
||||
StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:24:9: 24:10
|
||||
StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:24:14: 24:27
|
||||
_3 = Foo { a: const 42u64 }; // scope 1 at $DIR/issue-72181.rs:24:14: 24:27
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000002a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:24:23: 24:25
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) }
|
||||
StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:24:29: 24:42
|
||||
_4 = Foo { a: const 10u64 }; // scope 1 at $DIR/issue-72181.rs:24:29: 24:42
|
||||
// ty::Const
|
||||
// + ty: u64
|
||||
// + val: Value(Scalar(0x000000000000000a))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:24:38: 24:40
|
||||
// + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) }
|
||||
_2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:24:13: 24:43
|
||||
StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:24:42: 24:43
|
||||
StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:24:42: 24:43
|
||||
FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:24:9: 24:10
|
||||
StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:25:13: 25:30
|
||||
StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:25:24: 25:25
|
||||
_6 = const 0usize; // scope 4 at $DIR/issue-72181.rs:25:24: 25:25
|
||||
// ty::Const
|
||||
// + ty: usize
|
||||
// + val: Value(Scalar(0x0000000000000000))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:25:24: 25:25
|
||||
// + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
|
||||
_7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:25:22: 25:26
|
||||
_8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:25:22: 25:26
|
||||
assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:25:22: 25:26
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:25:22: 25:28
|
||||
StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:25:30: 25:31
|
||||
StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:25:30: 25:31
|
||||
_0 = const (); // scope 0 at $DIR/issue-72181.rs:21:11: 26:2
|
||||
// ty::Const
|
||||
// + ty: ()
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-72181.rs:21:11: 26:2
|
||||
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
|
||||
StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:26:1: 26:2
|
||||
goto -> bb4; // scope 0 at $DIR/issue-72181.rs:26:2: 26:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
return; // scope 0 at $DIR/issue-72181.rs:26:2: 26:2
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user