Detect unused files in src/test/mir-opt
and error on them in tidy.
This commit is contained in:
parent
024207ab43
commit
17395b45b1
@ -816,6 +816,7 @@ dependencies = [
|
||||
"lazycell",
|
||||
"libc",
|
||||
"miow",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
"rustfix",
|
||||
"serde",
|
||||
@ -2268,6 +2269,13 @@ dependencies = [
|
||||
"ui_test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miropt-test-tools"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
@ -4920,6 +4928,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.14.0",
|
||||
"lazy_static",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
"walkdir",
|
||||
]
|
||||
|
@ -11,6 +11,7 @@ members = [
|
||||
"src/tools/error_index_generator",
|
||||
"src/tools/linkchecker",
|
||||
"src/tools/lint-docs",
|
||||
"src/tools/miropt-test-tools",
|
||||
"src/tools/rustbook",
|
||||
"src/tools/unstable-book-gen",
|
||||
"src/tools/tidy",
|
||||
|
@ -622,6 +622,7 @@ macro_rules! describe {
|
||||
check::Clippy,
|
||||
check::Miri,
|
||||
check::CargoMiri,
|
||||
check::MiroptTestTools,
|
||||
check::Rls,
|
||||
check::RustAnalyzer,
|
||||
check::Rustfmt,
|
||||
|
@ -460,6 +460,7 @@ fn stamp(
|
||||
tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
|
||||
tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
|
||||
tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
|
||||
tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree);
|
||||
|
||||
tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
- // MIR for `try_identity` before DestinationPropagation
|
||||
+ // MIR for `try_identity` after DestinationPropagation
|
||||
|
||||
fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
|
||||
debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18
|
||||
let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57
|
||||
let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10
|
||||
let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
|
||||
let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14
|
||||
let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
|
||||
let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9
|
||||
scope 1 {
|
||||
debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10
|
||||
}
|
||||
scope 2 {
|
||||
debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
scope 3 {
|
||||
scope 7 {
|
||||
debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
}
|
||||
scope 8 {
|
||||
debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
|
||||
let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 4 {
|
||||
debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15
|
||||
scope 5 {
|
||||
}
|
||||
}
|
||||
scope 6 {
|
||||
- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
|
||||
+ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10
|
||||
- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
|
||||
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
|
||||
- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
|
||||
- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
|
||||
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
|
||||
+ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
|
||||
+ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
+ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
|
||||
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
|
||||
+ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
|
||||
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2
|
||||
goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
- // MIR for `try_identity` before DestinationPropagation
|
||||
+ // MIR for `try_identity` after DestinationPropagation
|
||||
|
||||
fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
|
||||
debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
|
||||
let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
|
||||
let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
|
||||
let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
|
||||
let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
scope 1 {
|
||||
- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
+ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
}
|
||||
scope 2 {
|
||||
debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
|
||||
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
}
|
||||
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
|
||||
debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
+ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
}
|
||||
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
|
||||
- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
|
||||
+ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
|
||||
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
+ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
+ nop; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
|
||||
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
+ ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
+ nop; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
+ nop; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
|
||||
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
+ nop; // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
|
||||
nop; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
|
||||
Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
- // MIR for `try_identity` before SimplifyArmIdentity
|
||||
+ // MIR for `try_identity` after SimplifyArmIdentity
|
||||
|
||||
fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
|
||||
debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
|
||||
let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
|
||||
let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
|
||||
let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
|
||||
let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
scope 1 {
|
||||
debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
}
|
||||
scope 2 {
|
||||
debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
|
||||
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
}
|
||||
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
|
||||
debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
}
|
||||
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
|
||||
debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
_4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
_3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
|
||||
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
|
||||
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
_10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
_2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
_11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
|
||||
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
_9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
|
||||
((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
|
||||
Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
// MIR for `try_identity` after SimplifyBranchSame
|
||||
|
||||
fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
|
||||
debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
|
||||
let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
|
||||
let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
|
||||
let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
|
||||
let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
scope 1 {
|
||||
debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
}
|
||||
scope 2 {
|
||||
debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
|
||||
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
}
|
||||
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
|
||||
debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
}
|
||||
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
|
||||
debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
_4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
_3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
|
||||
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
|
||||
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
_10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
_2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
|
||||
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
_11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
|
||||
Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
|
||||
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
_9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
|
||||
((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
|
||||
Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
|
||||
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// MIR for `try_identity` after SimplifyLocals
|
||||
|
||||
fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
|
||||
debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
|
||||
let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
|
||||
let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
let mut _3: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
|
||||
let _4: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
let mut _5: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
let mut _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
scope 1 {
|
||||
debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
|
||||
}
|
||||
scope 2 {
|
||||
debug e => _4; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
|
||||
debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||
}
|
||||
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
|
||||
debug e => _5; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
}
|
||||
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
|
||||
debug r => _2; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
|
||||
_3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
|
||||
}
|
||||
|
||||
bb1: {
|
||||
((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
|
||||
Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
|
||||
StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
|
||||
StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
|
||||
StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
|
||||
Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
|
||||
StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
|
||||
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ colored = "2"
|
||||
diff = "0.1.10"
|
||||
unified-diff = "0.2.1"
|
||||
getopts = "0.2"
|
||||
miropt-test-tools = { path = "../miropt-test-tools" }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
|
||||
regex = "1.0"
|
||||
|
@ -3399,103 +3399,49 @@ fn check_mir_dump(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
for l in test_file_contents.lines() {
|
||||
if l.starts_with("// EMIT_MIR ") {
|
||||
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
|
||||
let mut test_names = test_name.split(' ');
|
||||
// sometimes we specify two files so that we get a diff between the two files
|
||||
let test_name = test_names.next().unwrap();
|
||||
let mut expected_file;
|
||||
let from_file;
|
||||
let to_file;
|
||||
let files = miropt_test_tools::files_for_miropt_test(
|
||||
&self.testpaths.file,
|
||||
self.config.get_pointer_width(),
|
||||
);
|
||||
|
||||
if test_name.ends_with(".diff") {
|
||||
let trimmed = test_name.trim_end_matches(".diff");
|
||||
let test_against = format!("{}.after.mir", trimmed);
|
||||
from_file = format!("{}.before.mir", trimmed);
|
||||
expected_file = format!("{}{}.diff", trimmed, bit_width);
|
||||
assert!(
|
||||
test_names.next().is_none(),
|
||||
"two mir pass names specified for MIR diff"
|
||||
);
|
||||
to_file = Some(test_against);
|
||||
} else if let Some(first_pass) = test_names.next() {
|
||||
let second_pass = test_names.next().unwrap();
|
||||
assert!(
|
||||
test_names.next().is_none(),
|
||||
"three mir pass names specified for MIR diff"
|
||||
);
|
||||
expected_file =
|
||||
format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
|
||||
let second_file = format!("{}.{}.mir", test_name, second_pass);
|
||||
from_file = format!("{}.{}.mir", test_name, first_pass);
|
||||
to_file = Some(second_file);
|
||||
} else {
|
||||
let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
|
||||
let cap = ext_re
|
||||
.captures_iter(test_name)
|
||||
.next()
|
||||
.expect("test_name has an invalid extension");
|
||||
let extension = cap.get(1).unwrap().as_str();
|
||||
expected_file = format!(
|
||||
"{}{}{}",
|
||||
test_name.trim_end_matches(extension),
|
||||
bit_width,
|
||||
extension,
|
||||
);
|
||||
from_file = test_name.to_string();
|
||||
assert!(
|
||||
test_names.next().is_none(),
|
||||
"two mir pass names specified for MIR dump"
|
||||
);
|
||||
to_file = None;
|
||||
};
|
||||
if !expected_file.starts_with(&test_crate) {
|
||||
expected_file = format!("{}.{}", test_crate, expected_file);
|
||||
}
|
||||
let expected_file = test_dir.join(expected_file);
|
||||
|
||||
let dumped_string = if let Some(after) = to_file {
|
||||
self.diff_mir_files(from_file.into(), after.into())
|
||||
} else {
|
||||
let mut output_file = PathBuf::new();
|
||||
output_file.push(self.get_mir_dump_dir());
|
||||
output_file.push(&from_file);
|
||||
debug!(
|
||||
"comparing the contents of: {} with {}",
|
||||
for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files {
|
||||
let dumped_string = if let Some(after) = to_file {
|
||||
self.diff_mir_files(from_file.into(), after.into())
|
||||
} else {
|
||||
let mut output_file = PathBuf::new();
|
||||
output_file.push(self.get_mir_dump_dir());
|
||||
output_file.push(&from_file);
|
||||
debug!(
|
||||
"comparing the contents of: {} with {}",
|
||||
output_file.display(),
|
||||
expected_file.display()
|
||||
);
|
||||
if !output_file.exists() {
|
||||
panic!(
|
||||
"Output file `{}` from test does not exist, available files are in `{}`",
|
||||
output_file.display(),
|
||||
output_file.parent().unwrap().display()
|
||||
);
|
||||
}
|
||||
self.check_mir_test_timestamp(&from_file, &output_file);
|
||||
let dumped_string = fs::read_to_string(&output_file).unwrap();
|
||||
self.normalize_output(&dumped_string, &[])
|
||||
};
|
||||
|
||||
if self.config.bless {
|
||||
let _ = std::fs::remove_file(&expected_file);
|
||||
std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
|
||||
} else {
|
||||
if !expected_file.exists() {
|
||||
panic!("Output file `{}` from test does not exist", expected_file.display());
|
||||
}
|
||||
let expected_string = fs::read_to_string(&expected_file).unwrap();
|
||||
if dumped_string != expected_string {
|
||||
print!("{}", write_diff(&expected_string, &dumped_string, 3));
|
||||
panic!(
|
||||
"Actual MIR output differs from expected MIR output {}",
|
||||
expected_file.display()
|
||||
);
|
||||
if !output_file.exists() {
|
||||
panic!(
|
||||
"Output file `{}` from test does not exist, available files are in `{}`",
|
||||
output_file.display(),
|
||||
output_file.parent().unwrap().display()
|
||||
);
|
||||
}
|
||||
self.check_mir_test_timestamp(&from_file, &output_file);
|
||||
let dumped_string = fs::read_to_string(&output_file).unwrap();
|
||||
self.normalize_output(&dumped_string, &[])
|
||||
};
|
||||
|
||||
if self.config.bless {
|
||||
let _ = std::fs::remove_file(&expected_file);
|
||||
std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
|
||||
} else {
|
||||
if !expected_file.exists() {
|
||||
panic!(
|
||||
"Output file `{}` from test does not exist",
|
||||
expected_file.display()
|
||||
);
|
||||
}
|
||||
let expected_string = fs::read_to_string(&expected_file).unwrap();
|
||||
if dumped_string != expected_string {
|
||||
print!("{}", write_diff(&expected_string, &dumped_string, 3));
|
||||
panic!(
|
||||
"Actual MIR output differs from expected MIR output {}",
|
||||
expected_file.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
src/tools/miropt-test-tools/Cargo.toml
Normal file
7
src/tools/miropt-test-tools/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "miropt-test-tools"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
regex = "1.0"
|
70
src/tools/miropt-test-tools/src/lib.rs
Normal file
70
src/tools/miropt-test-tools/src/lib.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::fs;
|
||||
|
||||
pub struct MiroptTestFiles {
|
||||
pub expected_file: std::path::PathBuf,
|
||||
pub from_file: String,
|
||||
pub to_file: Option<String>,
|
||||
}
|
||||
|
||||
pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<MiroptTestFiles> {
|
||||
let mut out = Vec::new();
|
||||
let test_file_contents = fs::read_to_string(&testfile).unwrap();
|
||||
|
||||
let test_dir = testfile.parent().unwrap();
|
||||
let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_");
|
||||
|
||||
let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
|
||||
format!(".{}bit", bit_width)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
for l in test_file_contents.lines() {
|
||||
if l.starts_with("// EMIT_MIR ") {
|
||||
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
|
||||
let mut test_names = test_name.split(' ');
|
||||
// sometimes we specify two files so that we get a diff between the two files
|
||||
let test_name = test_names.next().unwrap();
|
||||
let mut expected_file;
|
||||
let from_file;
|
||||
let to_file;
|
||||
|
||||
if test_name.ends_with(".diff") {
|
||||
let trimmed = test_name.trim_end_matches(".diff");
|
||||
let test_against = format!("{}.after.mir", trimmed);
|
||||
from_file = format!("{}.before.mir", trimmed);
|
||||
expected_file = format!("{}{}.diff", trimmed, bit_width);
|
||||
assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff");
|
||||
to_file = Some(test_against);
|
||||
} else if let Some(first_pass) = test_names.next() {
|
||||
let second_pass = test_names.next().unwrap();
|
||||
assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff");
|
||||
expected_file =
|
||||
format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
|
||||
let second_file = format!("{}.{}.mir", test_name, second_pass);
|
||||
from_file = format!("{}.{}.mir", test_name, first_pass);
|
||||
to_file = Some(second_file);
|
||||
} else {
|
||||
let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
|
||||
let cap = ext_re
|
||||
.captures_iter(test_name)
|
||||
.next()
|
||||
.expect("test_name has an invalid extension");
|
||||
let extension = cap.get(1).unwrap().as_str();
|
||||
expected_file =
|
||||
format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,);
|
||||
from_file = test_name.to_string();
|
||||
assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump");
|
||||
to_file = None;
|
||||
};
|
||||
if !expected_file.starts_with(&test_crate) {
|
||||
expected_file = format!("{}.{}", test_crate, expected_file);
|
||||
}
|
||||
let expected_file = test_dir.join(expected_file);
|
||||
|
||||
out.push(MiroptTestFiles { expected_file, from_file, to_file });
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
@ -7,6 +7,7 @@ autobins = false
|
||||
[dependencies]
|
||||
cargo_metadata = "0.14"
|
||||
regex = "1"
|
||||
miropt-test-tools = { path = "../miropt-test-tools" }
|
||||
lazy_static = "1"
|
||||
walkdir = "2"
|
||||
|
||||
|
@ -47,6 +47,7 @@ macro_rules! tidy_error {
|
||||
pub mod errors;
|
||||
pub mod extdeps;
|
||||
pub mod features;
|
||||
pub mod mir_opt_tests;
|
||||
pub mod pal;
|
||||
pub mod primitive_docs;
|
||||
pub mod style;
|
||||
|
@ -64,6 +64,7 @@ macro_rules! check {
|
||||
// Checks over tests.
|
||||
check!(debug_artifacts, &src_path);
|
||||
check!(ui_tests, &src_path);
|
||||
check!(mir_opt_tests, &src_path);
|
||||
|
||||
// Checks that only make sense for the compiler.
|
||||
check!(errors, &compiler_path);
|
||||
|
37
src/tools/tidy/src/mir_opt_tests.rs
Normal file
37
src/tools/tidy/src/mir_opt_tests.rs
Normal file
@ -0,0 +1,37 @@
|
||||
//! Tidy check to ensure that mir opt directories do not have stale files.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
let mut rs_files = Vec::<PathBuf>::new();
|
||||
let mut output_files = HashSet::<PathBuf>::new();
|
||||
let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter();
|
||||
|
||||
for file in files.filter_map(Result::ok).filter(|e| e.file_type().is_file()) {
|
||||
let filepath = file.path();
|
||||
if filepath.extension() == Some("rs".as_ref()) {
|
||||
rs_files.push(filepath.to_owned());
|
||||
} else {
|
||||
output_files.insert(filepath.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
for file in rs_files {
|
||||
for bw in [32, 64] {
|
||||
for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) {
|
||||
output_files.remove(&output_file.expected_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for extra in output_files {
|
||||
if extra.file_name() != Some("README.md".as_ref()) {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"the following output file is not associated with any mir-opt test, you can remove it: {}",
|
||||
extra.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user