Skip to content

Commit e9d68a5

Browse files
Add UI test for DefId::parent()
1 parent 99049b3 commit e9d68a5

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
//@ run-pass
2+
//! Test that users are able to use public MIR APIs to retrieve information about parent
3+
//! definitions.
4+
5+
//@ ignore-stage1
6+
//@ ignore-cross-compile
7+
//@ ignore-remote
8+
//@ edition: 2024
9+
// ignore-tidy-linelength
10+
11+
#![feature(rustc_private)]
12+
13+
extern crate rustc_middle;
14+
15+
extern crate rustc_driver;
16+
extern crate rustc_interface;
17+
extern crate rustc_public;
18+
19+
use rustc_public::ty::{RigidTy, TyKind};
20+
use rustc_public::*;
21+
use std::fmt::Debug;
22+
use std::io::Write;
23+
use std::ops::ControlFlow;
24+
25+
const CRATE_NAME: &str = "input";
26+
27+
/// Verify that each def has the correct parent
28+
fn test_stable_mir() -> ControlFlow<()> {
29+
fn set_once<T: Debug + PartialEq>(slot: &mut Option<T>, val: T) {
30+
assert_eq!(slot.replace(val), None);
31+
}
32+
33+
let mut const_item = None;
34+
let mut static_item = None;
35+
let mut trait_method = None;
36+
let mut trait_method_helper = None;
37+
let mut inherent_method = None;
38+
let mut inherent_method_helper = None;
39+
let mut main = None;
40+
let mut mystruct_ctor = None;
41+
let mut trait_decl = None;
42+
let mut trait_impl = None;
43+
44+
let mut mystruct_ctor_ty = None;
45+
46+
// Extract def-ids of various items
47+
let krate = rustc_public::local_crate();
48+
for it in rustc_public::all_local_items() {
49+
match &*it.0.name() {
50+
"wrapper_mod::CONST_ITEM" => {
51+
set_once(&mut const_item, it.0);
52+
}
53+
"wrapper_mod::STATIC_ITEM" => {
54+
set_once(&mut static_item, it.0);
55+
}
56+
"<wrapper_mod::MyStruct as wrapper_mod::MyTrait>::trait_method" => {
57+
set_once(&mut trait_method, it.0);
58+
}
59+
"<wrapper_mod::MyStruct as wrapper_mod::MyTrait>::trait_method::trait_method_helper" => {
60+
set_once(&mut trait_method_helper, it.0);
61+
}
62+
"wrapper_mod::MyStruct::inherent_method" => {
63+
set_once(&mut inherent_method, it.0);
64+
}
65+
"wrapper_mod::MyStruct::inherent_method::inherent_method_helper" => {
66+
set_once(&mut inherent_method_helper, it.0);
67+
}
68+
"main" => {
69+
set_once(&mut main, it.0);
70+
}
71+
"wrapper_mod::MyStruct" => {
72+
set_once(&mut mystruct_ctor, it.0);
73+
mystruct_ctor_ty = Some(it.ty());
74+
}
75+
_ => (),
76+
}
77+
}
78+
for it in krate.trait_decls() {
79+
match &*it.0.name() {
80+
"wrapper_mod::MyTrait" => set_once(&mut trait_decl, it.0),
81+
_ => (),
82+
}
83+
}
84+
for it in krate.trait_impls() {
85+
match &*it.0.name() {
86+
"<wrapper_mod::MyStruct as wrapper_mod::MyTrait>" => set_once(&mut trait_impl, it.0),
87+
_ => (),
88+
}
89+
}
90+
91+
let const_item = const_item.unwrap();
92+
let static_item = static_item.unwrap();
93+
let trait_method = trait_method.unwrap();
94+
let trait_method_helper = trait_method_helper.unwrap();
95+
let inherent_method = inherent_method.unwrap();
96+
let inherent_method_helper = inherent_method_helper.unwrap();
97+
let main = main.unwrap();
98+
let mystruct_ctor = mystruct_ctor.unwrap();
99+
let trait_decl = trait_decl.unwrap();
100+
let trait_impl = trait_impl.unwrap();
101+
102+
let mystruct_ctor_ty = mystruct_ctor_ty.unwrap();
103+
let mystruct_ty = mystruct_ctor_ty.kind().fn_def().unwrap().0.fn_sig().skip_binder().output();
104+
let TyKind::RigidTy(RigidTy::Adt(mystruct_adt_def, _)) = mystruct_ty.kind() else { panic!() };
105+
106+
let inherent_impl = inherent_method.parent().unwrap();
107+
let wrapper_mod = const_item.parent().unwrap();
108+
let crate_root = wrapper_mod.parent().unwrap();
109+
assert_eq!(&*wrapper_mod.name(), "wrapper_mod");
110+
111+
// Check that each def-id has the correct parent
112+
assert_eq!(crate_root.parent(), None);
113+
assert_eq!(inherent_impl.parent(), Some(wrapper_mod));
114+
assert_eq!(const_item.parent(), Some(wrapper_mod));
115+
assert_eq!(static_item.parent(), Some(wrapper_mod));
116+
assert_eq!(trait_method.parent(), Some(trait_impl));
117+
assert_eq!(trait_method_helper.parent(), Some(trait_method));
118+
assert_eq!(inherent_method_helper.parent(), Some(inherent_method));
119+
assert_eq!(main.parent(), Some(crate_root));
120+
assert_eq!(trait_decl.parent(), Some(wrapper_mod));
121+
assert_eq!(trait_impl.parent(), Some(wrapper_mod));
122+
assert_eq!(mystruct_ctor.parent(), Some(mystruct_adt_def.0));
123+
assert_eq!(mystruct_adt_def.0.parent(), Some(wrapper_mod));
124+
125+
ControlFlow::Continue(())
126+
}
127+
128+
/// This test will generate and analyze a dummy crate using the stable mir.
129+
/// For that, it will first write the dummy crate into a file.
130+
/// Then it will create a `RustcPublic` using custom arguments and then
131+
/// it will run the compiler.
132+
fn main() {
133+
let path = "def_parent_input.rs";
134+
generate_input(&path).unwrap();
135+
let args = &[
136+
"rustc".to_string(),
137+
"-Cpanic=abort".to_string(),
138+
"--crate-name".to_string(),
139+
CRATE_NAME.to_string(),
140+
path.to_string(),
141+
];
142+
run!(args, test_stable_mir).unwrap();
143+
}
144+
145+
fn generate_input(path: &str) -> std::io::Result<()> {
146+
let mut file = std::fs::File::create(path)?;
147+
write!(
148+
file,
149+
r#"
150+
mod wrapper_mod {{
151+
pub const CONST_ITEM: u32 = 100;
152+
pub static STATIC_ITEM: u32 = 150;
153+
154+
pub struct MyStruct(pub u32);
155+
156+
pub trait MyTrait {{
157+
fn trait_method(&self);
158+
}}
159+
160+
impl MyTrait for MyStruct {{
161+
fn trait_method(&self) {{
162+
fn trait_method_helper() {{}}
163+
164+
trait_method_helper()
165+
}}
166+
}}
167+
168+
impl MyStruct {{
169+
pub fn inherent_method(&self) {{
170+
println!("{{}}", self.0);
171+
172+
fn inherent_method_helper() {{}}
173+
174+
inherent_method_helper()
175+
}}
176+
}}
177+
}}
178+
use wrapper_mod::{{MyStruct, MyTrait, CONST_ITEM, STATIC_ITEM}};
179+
180+
fn main() {{
181+
let mystruct = MyStruct(200);
182+
mystruct.trait_method();
183+
mystruct.inherent_method();
184+
let _const = CONST_ITEM;
185+
let _static = STATIC_ITEM;
186+
}}
187+
"#
188+
)?;
189+
Ok(())
190+
}

0 commit comments

Comments
 (0)