]> git.lizzy.rs Git - rust.git/blob - src/test/debuginfo/type-names.rs
debuginfo: Fix bug in type name generation for dyn types with associated types but...
[rust.git] / src / test / debuginfo / type-names.rs
1 // ignore-lldb
2
3 // GDB changed the way that it formatted Foreign types
4 // min-gdb-version: 9.2
5
6 // compile-flags:-g
7
8 // === GDB TESTS ===================================================================================
9
10 // gdb-command:run
11
12 // STRUCTS
13 // gdb-command:whatis simple_struct
14 // gdb-check:type = type_names::Struct1
15
16 // gdb-command:whatis generic_struct1
17 // gdb-check:type = type_names::GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
18
19 // gdb-command:whatis generic_struct2
20 // gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
21
22 // gdb-command:whatis mod_struct
23 // gdb-check:type = type_names::mod1::Struct2
24
25 // ENUMS
26 // gdb-command:whatis simple_enum_1
27 // gdb-check:type = type_names::Enum1
28
29 // gdb-command:whatis simple_enum_2
30 // gdb-check:type = type_names::Enum1
31
32 // gdb-command:whatis simple_enum_3
33 // gdb-check:type = type_names::mod1::Enum2
34
35 // gdb-command:whatis generic_enum_1
36 // gdb-check:type = type_names::mod1::mod2::Enum3
37
38 // gdb-command:whatis generic_enum_2
39 // gdb-check:type = type_names::mod1::mod2::Enum3
40
41 // TUPLES
42 // gdb-command:whatis tuple1
43 // gdb-check:type = (u32, type_names::Struct1, type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>)
44
45 // gdb-command:whatis tuple2
46 // gdb-check:type = ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
47
48 // BOX
49 // gdb-command:whatis box1
50 // gdb-check:type = (alloc::boxed::Box<f32, alloc::alloc::Global>, i32)
51
52 // gdb-command:whatis box2
53 // gdb-check:type = (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>, alloc::alloc::Global>, i32)
54
55 // REFERENCES
56 // gdb-command:whatis ref1
57 // gdb-check:type = (&type_names::Struct1, i32)
58
59 // gdb-command:whatis ref2
60 // gdb-check:type = (&type_names::GenericStruct<char, type_names::Struct1>, i32)
61
62 // gdb-command:whatis mut_ref1
63 // gdb-check:type = (&mut type_names::Struct1, i32)
64
65 // gdb-command:whatis mut_ref2
66 // gdb-check:type = (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
67
68 // RAW POINTERS
69 // gdb-command:whatis mut_ptr1
70 // gdb-check:type = (*mut type_names::Struct1, isize)
71
72 // gdb-command:whatis mut_ptr2
73 // gdb-check:type = (*mut isize, isize)
74
75 // gdb-command:whatis mut_ptr3
76 // gdb-check:type = (*mut type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
77
78 // gdb-command:whatis const_ptr1
79 // gdb-check:type = (*const type_names::Struct1, isize)
80
81 // gdb-command:whatis const_ptr2
82 // gdb-check:type = (*const isize, isize)
83
84 // gdb-command:whatis const_ptr3
85 // gdb-check:type = (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
86
87 // VECTORS
88 // gdb-command:whatis fixed_size_vec1
89 // gdb-check:type = ([type_names::Struct1; 3], i16)
90
91 // gdb-command:whatis fixed_size_vec2
92 // gdb-check:type = ([usize; 3], i16)
93
94 // gdb-command:whatis slice1
95 // gdb-check:type = &[usize]
96
97 // gdb-command:whatis slice2
98 // gdb-check:type = &[type_names::mod1::Enum2]
99
100 // TRAITS
101 // gdb-command:whatis box_trait
102 // gdb-check:type = alloc::boxed::Box<dyn type_names::Trait1, alloc::alloc::Global>
103
104 // gdb-command:whatis ref_trait
105 // gdb-check:type = &dyn type_names::Trait1
106
107 // gdb-command:whatis mut_ref_trait
108 // gdb-check:type = &mut dyn type_names::Trait1
109
110 // gdb-command:whatis generic_box_trait
111 // gdb-check:type = alloc::boxed::Box<dyn type_names::Trait2<i32, type_names::mod1::Struct2>, alloc::alloc::Global>
112
113 // gdb-command:whatis generic_ref_trait
114 // gdb-check:type = &dyn type_names::Trait2<type_names::Struct1, type_names::Struct1>
115
116 // gdb-command:whatis generic_mut_ref_trait
117 // gdb-check:type = &mut dyn type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
118
119 // gdb-command:whatis no_principal_trait
120 // gdb-check:type = alloc::boxed::Box<(dyn core::marker::Send + core::marker::Sync), alloc::alloc::Global>
121
122 // gdb-command:whatis has_associated_type_trait
123 // gdb-check:type = &(dyn type_names::Trait3<u32, AssocType=isize> + core::marker::Send)
124
125 // gdb-command:whatis has_associated_type_but_no_generics_trait
126 // gdb-check:type = &dyn type_names::TraitNoGenericsButWithAssocType<Output=isize>
127
128 // BARE FUNCTIONS
129 // gdb-command:whatis rust_fn
130 // gdb-check:type = (fn(core::option::Option<isize>, core::option::Option<&type_names::mod1::Struct2>), usize)
131
132 // gdb-command:whatis extern_c_fn
133 // gdb-check:type = (extern "C" fn(isize), usize)
134
135 // gdb-command:whatis unsafe_fn
136 // gdb-check:type = (unsafe fn(core::result::Result<char, f64>), usize)
137
138 // gdb-command:whatis rust_fn_with_return_value
139 // gdb-check:type = (fn(f64) -> usize, usize)
140
141 // gdb-command:whatis extern_c_fn_with_return_value
142 // gdb-check:type = (extern "C" fn() -> type_names::Struct1, usize)
143
144 // gdb-command:whatis unsafe_fn_with_return_value
145 // gdb-check:type = (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::mod1::Struct2, usize)
146
147 // gdb-command:whatis generic_function_int
148 // gdb-check:type = (fn(isize) -> isize, usize)
149
150 // gdb-command:whatis generic_function_struct3
151 // gdb-check:type = (fn(type_names::mod1::mod2::Struct3) -> type_names::mod1::mod2::Struct3, usize)
152
153 // gdb-command:whatis variadic_function
154 // gdb-check:type = (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
155
156 // CLOSURES
157 // gdb-command:whatis closure1
158 // gdb-check:type = (type_names::main::{closure_env#0}, usize)
159
160 // gdb-command:whatis closure2
161 // gdb-check:type = (type_names::main::{closure_env#1}, usize)
162
163 // FOREIGN TYPES
164 // gdb-command:whatis foreign1
165 // gdb-check:type = *mut ForeignType1
166
167 // gdb-command:whatis foreign2
168 // gdb-check:type = *mut ForeignType2
169
170 // === CDB TESTS ==================================================================================
171
172 // cdb-command: g
173
174 // STRUCTS
175 // 0-sized structs appear to be optimized away in some cases, so only check the structs that do
176 // actually appear.
177 // cdb-command:dv /t *_struct
178 // cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
179
180 // ENUMS
181 // cdb-command:dv /t *_enum_*
182 // cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
183 // cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
184 // cdb-check:type_names::mod1::Enum2 simple_enum_3 = [...]
185 // cdb-check:type_names::mod1::mod2::Enum3 generic_enum_1 = [...]
186 // cdb-check:type_names::mod1::mod2::Enum3 generic_enum_2 = [...]
187
188 // TUPLES
189 // cdb-command:dv /t tuple*
190 // cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
191 // cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
192
193 // BOX
194 // cdb-command:dv /t box*
195 // cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
196 // cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
197
198 // REFERENCES
199 // cdb-command:dv /t *ref*
200 // cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
201 // cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
202 // cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
203 // cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
204
205 // RAW POINTERS
206 // cdb-command:dv /t *_ptr*
207 // cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
208 // cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
209 // cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
210 // cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
211 // cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
212 // cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
213
214 // VECTORS
215 // cdb-command:dv /t *vec*
216 // cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
217 // cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
218 // cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
219 // cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
220 // cdb-command:dv /t slice*
221 // cdb-check:struct slice$<usize> slice1 = [...]
222 // cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
223
224 // TRAITS
225 // cdb-command:dv /t *_trait
226 // cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3,type_names::GenericStruct<usize,isize> > > > generic_mut_ref_trait = [...]
227 // cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1,type_names::Struct1> > > generic_ref_trait = [...]
228 // cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
229 // cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
230 // cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
231 // cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
232 // cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send,core::marker::Sync>,alloc::alloc::Global> no_principal_trait = [...]
233 // cdb-check:struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> >
234 // cdb-check:struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > > has_associated_type_but_no_generics_trait = struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > >
235
236 // BARE FUNCTIONS
237 // cdb-command:dv /t *_fn*
238 // cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
239 // cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
240 // cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
241 // cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
242 // cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
243 // cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
244 // cdb-command:dv /t *_function*
245 // cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
246 // cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
247 // cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
248 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
249 // cdb-check:Return Type: void
250 // cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
251 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
252 // cdb-check:Return Type: usize
253 // cdb-check:Parameter Types: f64
254 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("extern_c_fn_with_return_value")
255 // cdb-check:Return Type: type_names::Struct1
256 // cdb-check:Parameter Types:
257
258 // CLOSURES
259 // cdb-command:dv /t closure*
260 // cdb-check:struct tuple$<type_names::main::closure_env$1,usize> closure2 = [...]
261 // cdb-check:struct tuple$<type_names::main::closure_env$0,usize> closure1 = [...]
262
263 // FOREIGN TYPES
264 // cdb-command:dv /t foreign*
265 // cdb-check:struct ForeignType2 * foreign2 = [...]
266 // cdb-check:struct ForeignType1 * foreign1 = [...]
267
268 #![allow(unused_variables)]
269 #![feature(omit_gdb_pretty_printer_section)]
270 #![omit_gdb_pretty_printer_section]
271 #![feature(extern_types)]
272
273 use self::Enum1::{Variant1, Variant2};
274 use std::marker::PhantomData;
275 use std::ptr;
276
277 pub struct Struct1;
278 struct GenericStruct<T1, T2>(PhantomData<(T1, T2)>);
279
280 enum Enum1 {
281     Variant1,
282     Variant2(isize),
283 }
284
285 extern "C" {
286     type ForeignType1;
287 }
288
289 mod mod1 {
290     pub use self::Enum2::{Variant1, Variant2};
291     pub struct Struct2;
292
293     pub enum Enum2 {
294         Variant1,
295         Variant2(super::Struct1),
296     }
297
298     pub mod mod2 {
299         pub use self::Enum3::{Variant1, Variant2};
300         pub struct Struct3;
301
302         pub enum Enum3<T> {
303             Variant1,
304             Variant2(T),
305         }
306     }
307
308     extern "C" {
309         pub type ForeignType2;
310     }
311 }
312
313 trait Trait1 {
314     fn dummy(&self) {}
315 }
316 trait Trait2<T1, T2> {
317     fn dummy(&self, _: T1, _: T2) {}
318 }
319 trait Trait3<T> {
320     type AssocType;
321     fn dummy(&self) -> T {
322         panic!()
323     }
324 }
325 trait TraitNoGenericsButWithAssocType {
326     type Output;
327     fn foo(&self) -> Self::Output;
328 }
329
330 impl Trait1 for isize {}
331 impl<T1, T2> Trait2<T1, T2> for isize {}
332 impl<T> Trait3<T> for isize {
333     type AssocType = isize;
334 }
335 impl TraitNoGenericsButWithAssocType for isize {
336     type Output = isize;
337     fn foo(&self) -> Self::Output {
338         *self
339     }
340 }
341
342 fn rust_fn(_: Option<isize>, _: Option<&mod1::Struct2>) {}
343 extern "C" fn extern_c_fn(_: isize) {}
344 unsafe fn unsafe_fn(_: Result<char, f64>) {}
345
346 fn rust_fn_with_return_value(_: f64) -> usize {
347     4
348 }
349 extern "C" fn extern_c_fn_with_return_value() -> Struct1 {
350     Struct1
351 }
352 unsafe fn unsafe_fn_with_return_value(_: GenericStruct<u16, u8>) -> mod1::Struct2 {
353     mod1::Struct2
354 }
355
356 fn generic_function<T>(x: T) -> T {
357     x
358 }
359
360 #[allow(improper_ctypes)]
361 extern "C" {
362     fn printf(_: *const u8, ...) -> isize;
363 }
364
365 // In many of the cases below, the type that is actually under test is wrapped
366 // in a tuple, e.g., Box<T>, references, raw pointers, fixed-size vectors, ...
367 // This is because GDB will not print the type name from DWARF debuginfo for
368 // some kinds of types (pointers, arrays, functions, ...)
369 // Since tuples are structs as far as GDB is concerned, their name will be
370 // printed correctly, so the tests below just construct a tuple type that will
371 // then *contain* the type name that we want to see.
372 fn main() {
373     // Structs
374     let simple_struct = Struct1;
375     let generic_struct1: GenericStruct<mod1::Struct2, mod1::mod2::Struct3> =
376         GenericStruct(PhantomData);
377     let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
378         GenericStruct(PhantomData);
379     let mod_struct = mod1::Struct2;
380
381     // Enums
382     let simple_enum_1 = Variant1;
383     let simple_enum_2 = Variant2(0);
384     let simple_enum_3 = mod1::Variant2(Struct1);
385
386     let generic_enum_1: mod1::mod2::Enum3<mod1::Struct2> = mod1::mod2::Variant1;
387     let generic_enum_2 = mod1::mod2::Variant2(Struct1);
388
389     // Tuples
390     let tuple1 = (8u32, Struct1, mod1::mod2::Variant2(mod1::Struct2));
391     let tuple2 = ((Struct1, mod1::mod2::Struct3), mod1::Variant1, 'x');
392
393     // Box
394     let box1 = (Box::new(1f32), 0i32);
395     let box2 = (Box::new(mod1::mod2::Variant2(1f32)), 0i32);
396
397     // References
398     let ref1 = (&Struct1, 0i32);
399     let ref2 = (&GenericStruct::<char, Struct1>(PhantomData), 0i32);
400
401     let mut mut_struct1 = Struct1;
402     let mut mut_generic_struct = GenericStruct::<mod1::Enum2, f64>(PhantomData);
403     let mut_ref1 = (&mut mut_struct1, 0i32);
404     let mut_ref2 = (&mut mut_generic_struct, 0i32);
405
406     // Raw Pointers
407     let mut_ptr1: (*mut Struct1, isize) = (ptr::null_mut(), 0);
408     let mut_ptr2: (*mut isize, isize) = (ptr::null_mut(), 0);
409     let mut_ptr3: (*mut mod1::mod2::Enum3<Struct1>, isize) = (ptr::null_mut(), 0);
410
411     let const_ptr1: (*const Struct1, isize) = (ptr::null(), 0);
412     let const_ptr2: (*const isize, isize) = (ptr::null(), 0);
413     let const_ptr3: (*const mod1::mod2::Enum3<Struct1>, isize) = (ptr::null(), 0);
414
415     // Vectors
416     let fixed_size_vec1 = ([Struct1, Struct1, Struct1], 0i16);
417     let fixed_size_vec2 = ([0_usize, 1, 2], 0i16);
418
419     let vec1 = vec![0_usize, 2, 3];
420     let slice1 = &*vec1;
421     let vec2 = vec![mod1::Variant2(Struct1)];
422     let slice2 = &*vec2;
423
424     // Trait Objects
425     let box_trait = Box::new(0_isize) as Box<dyn Trait1>;
426     let ref_trait = &0_isize as &dyn Trait1;
427     let mut mut_int1 = 0_isize;
428     let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1;
429     let no_principal_trait = Box::new(0_isize) as Box<(dyn Send + Sync)>;
430     let has_associated_type_trait = &0_isize as &(dyn Trait3<u32, AssocType = isize> + Send);
431     let has_associated_type_but_no_generics_trait =
432         &0_isize as &dyn TraitNoGenericsButWithAssocType<Output = isize>;
433
434     let generic_box_trait = Box::new(0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
435     let generic_ref_trait = (&0_isize) as &dyn Trait2<Struct1, Struct1>;
436
437     let mut generic_mut_ref_trait_impl = 0_isize;
438     let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl)
439         as &mut dyn Trait2<mod1::mod2::Struct3, GenericStruct<usize, isize>>;
440
441     // Bare Functions
442     let rust_fn = (rust_fn, 0_usize);
443     let extern_c_fn = (extern_c_fn, 0_usize);
444     let unsafe_fn = (unsafe_fn, 0_usize);
445
446     let rust_fn_with_return_value = (rust_fn_with_return_value, 0_usize);
447     let extern_c_fn_with_return_value = (extern_c_fn_with_return_value, 0_usize);
448     let unsafe_fn_with_return_value = (unsafe_fn_with_return_value, 0_usize);
449
450     let generic_function_int = (generic_function::<isize>, 0_usize);
451     let generic_function_struct3 = (generic_function::<mod1::mod2::Struct3>, 0_usize);
452
453     let variadic_function = (printf, 0_usize);
454
455     // Closures
456     // I (mw) am a bit unclear about the current state of closures, their
457     // various forms (boxed, unboxed, proc, capture-by-ref, by-val, once) and
458     // how that maps to rustc's internal representation of these forms.
459     // Once closures have reached their 1.0 form, the tests below should
460     // probably be expanded.
461     let closure1 = (|x: isize| {}, 0_usize);
462     let closure2 = (|x: i8, y: f32| (x as f32) + y, 0_usize);
463
464     // Foreign Types
465     let foreign1 = unsafe { 0 as *const ForeignType1 };
466     let foreign2 = unsafe { 0 as *const mod1::ForeignType2 };
467
468     zzz(); // #break
469 }
470
471 #[inline(never)]
472 fn zzz() {
473     ()
474 }