]> git.lizzy.rs Git - rust.git/blob - src/test/codegen/debuginfo-generic-closure-env-names.rs
Rollup merge of #88313 - jyn514:pre-push, r=Mark-Simulacrum
[rust.git] / src / test / codegen / debuginfo-generic-closure-env-names.rs
1 // This test checks that we get proper type names for closure environments and
2 // async-fn environments in debuginfo, especially making sure that generic arguments
3 // of the enclosing functions don't get lost.
4 //
5 // Unfortunately, the order that debuginfo gets emitted into LLVM IR becomes a bit hard
6 // to predict once async fns are involved.
7 //
8 // Note that the test does not check async-fns when targeting MSVC because debuginfo for
9 // those does not follow the enum-fallback encoding yet and thus is incomplete.
10
11 // ignore-tidy-linelength
12
13 // Use the v0 symbol mangling scheme to codegen order independent of rustc version.
14 // Unnamed items like shims are generated in lexicographical order of their symbol name and in the
15 // legacy mangling scheme rustc version and generic parameters are both hashed into a single part
16 // of the name, thus randomizing item order with respect to rustc version.
17
18 // compile-flags: -Cdebuginfo=2 --edition 2021 -Copt-level=0 -Csymbol-mangling-version=v0
19
20
21 // CHECK: [[non_generic_closure_NAMESPACE:!.*]] = !DINamespace(name: "non_generic_closure"
22 // CHECK: [[function_containing_closure_NAMESPACE:!.*]] = !DINamespace(name: "function_containing_closure"
23 // CHECK: [[generic_async_function_NAMESPACE:!.*]] = !DINamespace(name: "generic_async_function"
24 // CHECK: [[generic_async_block_NAMESPACE:!.*]] = !DINamespace(name: "generic_async_block"
25
26 // non_generic_closure()
27 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[non_generic_closure_NAMESPACE]]
28 // MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: [[non_generic_closure_NAMESPACE]]
29
30 // function_containing_closure<u32>()
31 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<u32>", scope: [[function_containing_closure_NAMESPACE]]
32 // MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<u32>", scope: [[function_containing_closure_NAMESPACE]]
33
34 // generic_async_function<Foo>()
35 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: [[generic_async_function_NAMESPACE]]
36
37 // generic_async_function<u32>()
38 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<u32>", scope: [[generic_async_function_NAMESPACE]]
39
40 // generic_async_block<Foo>()
41 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: [[generic_async_block_NAMESPACE]]
42
43 // generic_async_block<u32>()
44 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<u32>", scope: [[generic_async_block_NAMESPACE]]
45
46 // function_containing_closure<Foo>()
47 // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: [[function_containing_closure_NAMESPACE]]
48 // MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<debuginfo_generic_closure_env_names::Foo>", scope: [[function_containing_closure_NAMESPACE]]
49
50
51 #![crate_type = "lib"]
52 use std::future::Future;
53
54 pub struct Foo;
55
56 pub fn non_generic_closure(x: Foo) -> Box<dyn FnOnce() -> Foo> {
57     // This static only exists to trigger generating the namespace debuginfo for
58     // `function_containing_closure` at a predictable, early point, which makes
59     // writing the FileCheck tests above simpler.
60     static _X: u8 = 0;
61     return Box::new(move || x);
62 }
63
64 fn function_containing_closure<T: 'static>(x: T) -> impl FnOnce() -> T {
65     static _X: u8 = 0; // Same as above
66
67     return move || x;
68 }
69
70 async fn generic_async_function<T: 'static>(x: T) -> T {
71     static _X: u8 = 0; // Same as above
72     x
73 }
74
75 fn generic_async_block<T: 'static>(x: T) -> impl Future<Output=T> {
76     static _X: u8 = 0; // Same as above
77     async move {
78         x
79     }
80 }
81
82 pub fn instantiate_generics() {
83     let _closure_u32 = function_containing_closure(7u32);
84     let _closure_foo = function_containing_closure(Foo);
85
86     let _async_fn_u32 = generic_async_function(42u32);
87     let _async_fn_foo = generic_async_function(Foo);
88
89     let _async_block_u32 = generic_async_block(64u32);
90     let _async_block_foo = generic_async_block(Foo);
91 }