Skip to content

Commit becdd21

Browse files
committed
Add test for AdtDef::discriminant_for_variant
1 parent 7d13f8d commit becdd21

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//@ run-pass
2+
//! Test that users are able to use stable mir APIs to retrieve type information from a crate item
3+
//! definition.
4+
5+
//@ ignore-stage1
6+
//@ ignore-cross-compile
7+
//@ ignore-remote
8+
//@ edition: 2024
9+
10+
#![feature(rustc_private)]
11+
#![feature(assert_matches)]
12+
13+
extern crate rustc_middle;
14+
#[macro_use]
15+
extern crate rustc_smir;
16+
extern crate rustc_driver;
17+
extern crate rustc_interface;
18+
extern crate stable_mir;
19+
20+
use std::io::Write;
21+
use std::ops::ControlFlow;
22+
23+
use stable_mir::CrateItem;
24+
use stable_mir::crate_def::CrateDef;
25+
use stable_mir::mir::{AggregateKind, Rvalue, Statement, StatementKind};
26+
use stable_mir::ty::{IntTy, RigidTy, Ty};
27+
28+
const CRATE_NAME: &str = "crate_variant_ty";
29+
30+
/// Test if we can retrieve discriminant info for different types.
31+
fn test_def_tys() -> ControlFlow<()> {
32+
check_adt_mono();
33+
check_adt_poly();
34+
35+
ControlFlow::Continue(())
36+
}
37+
38+
fn check_adt_mono() {
39+
let mono = get_fn("mono").expect_body();
40+
41+
check_statement_is_aggregate_assign(
42+
&mono.blocks[0].statements[0],
43+
0,
44+
RigidTy::Int(IntTy::Isize),
45+
);
46+
check_statement_is_aggregate_assign(
47+
&mono.blocks[1].statements[0],
48+
1,
49+
RigidTy::Int(IntTy::Isize),
50+
);
51+
check_statement_is_aggregate_assign(
52+
&mono.blocks[2].statements[0],
53+
2,
54+
RigidTy::Int(IntTy::Isize),
55+
);
56+
}
57+
58+
fn check_adt_poly() {
59+
let poly = get_fn("poly").expect_body();
60+
61+
check_statement_is_aggregate_assign(
62+
&poly.blocks[0].statements[0],
63+
0,
64+
RigidTy::Int(IntTy::Isize),
65+
);
66+
check_statement_is_aggregate_assign(
67+
&poly.blocks[1].statements[0],
68+
1,
69+
RigidTy::Int(IntTy::Isize),
70+
);
71+
check_statement_is_aggregate_assign(
72+
&poly.blocks[2].statements[0],
73+
2,
74+
RigidTy::Int(IntTy::Isize),
75+
);
76+
}
77+
78+
fn get_fn(name: &str) -> CrateItem {
79+
stable_mir::all_local_items().into_iter().find(|it| it.name().eq(name)).unwrap()
80+
}
81+
82+
fn check_statement_is_aggregate_assign(
83+
statement: &Statement,
84+
expected_discr_val: u128,
85+
expected_discr_ty: RigidTy,
86+
) {
87+
if let Statement { kind: StatementKind::Assign(_, rvalue), .. } = statement
88+
&& let Rvalue::Aggregate(aggregate, _) = rvalue
89+
&& let AggregateKind::Adt(adt_def, variant_idx, ..) = aggregate
90+
{
91+
let discr = adt_def.discriminant_for_variant(*variant_idx);
92+
93+
assert_eq!(discr.val, expected_discr_val);
94+
assert_eq!(discr.ty, Ty::from_rigid_kind(expected_discr_ty));
95+
} else {
96+
unreachable!("Unexpected statement");
97+
}
98+
}
99+
100+
/// This test will generate and analyze a dummy crate using the stable mir.
101+
/// For that, it will first write the dummy crate into a file.
102+
/// Then it will create a `StableMir` using custom arguments and then
103+
/// it will run the compiler.
104+
fn main() {
105+
let path = "defs_ty_input.rs";
106+
generate_input(&path).unwrap();
107+
let args = &[
108+
"rustc".to_string(),
109+
"-Cpanic=abort".to_string(),
110+
"--crate-name".to_string(),
111+
CRATE_NAME.to_string(),
112+
path.to_string(),
113+
];
114+
run!(args, test_def_tys).unwrap();
115+
}
116+
117+
fn generate_input(path: &str) -> std::io::Result<()> {
118+
let mut file = std::fs::File::create(path)?;
119+
write!(
120+
file,
121+
r#"
122+
use std::hint::black_box;
123+
124+
enum Mono {{
125+
A,
126+
B(i32),
127+
C {{ a: i32, b: u32 }},
128+
}}
129+
130+
enum Poly<T> {{
131+
A,
132+
B(T),
133+
C {{ t: T }},
134+
}}
135+
136+
pub fn main() {{
137+
mono();
138+
}}
139+
140+
fn mono() {{
141+
black_box(Mono::A);
142+
black_box(Mono::B(6));
143+
black_box(Mono::C {{a: 1, b: 10 }});
144+
}}
145+
146+
fn poly() {{
147+
black_box(Poly::<i32>::A);
148+
black_box(Poly::B(1i32));
149+
black_box(Poly::C {{ t: 1i32 }});
150+
}}
151+
"#
152+
)?;
153+
Ok(())
154+
}

0 commit comments

Comments
 (0)