/src/test/codegen/debuginfo-generic-closure-env-names.rs

https://gitlab.com/rust-lang/rust · Rust · 89 lines · 28 code · 22 blank · 39 comment · 2 complexity · 31a23b591f221f616379375d5ee496f7 MD5 · raw file

  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, so DAG allows any order.
  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. // ignore-tidy-linelength
  11. // Use the v0 symbol mangling scheme to codegen order independent of rustc version.
  12. // Unnamed items like shims are generated in lexicographical order of their symbol name and in the
  13. // legacy mangling scheme rustc version and generic parameters are both hashed into a single part
  14. // of the name, thus randomizing item order with respect to rustc version.
  15. // compile-flags: -Cdebuginfo=2 --edition 2021 -Copt-level=0 -Csymbol-mangling-version=v0
  16. // non_generic_closure()
  17. // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: ![[non_generic_closure_NAMESPACE:[0-9]+]],
  18. // MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: ![[non_generic_closure_NAMESPACE:[0-9]+]],
  19. // CHECK: ![[non_generic_closure_NAMESPACE]] = !DINamespace(name: "non_generic_closure"
  20. // CHECK: ![[function_containing_closure_NAMESPACE:[0-9]+]] = !DINamespace(name: "function_containing_closure"
  21. // CHECK: ![[generic_async_function_NAMESPACE:[0-9]+]] = !DINamespace(name: "generic_async_function"
  22. // CHECK: ![[generic_async_block_NAMESPACE:[0-9]+]] = !DINamespace(name: "generic_async_block"
  23. // function_containing_closure<u32>()
  24. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<u32>", scope: ![[function_containing_closure_NAMESPACE]]
  25. // MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<u32>", scope: ![[function_containing_closure_NAMESPACE]]
  26. // generic_async_function<Foo>()
  27. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_function_NAMESPACE]]
  28. // generic_async_function<u32>()
  29. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<u32>", scope: ![[generic_async_function_NAMESPACE]]
  30. // generic_async_block<Foo>()
  31. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_block_NAMESPACE]]
  32. // generic_async_block<u32>()
  33. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<u32>", scope: ![[generic_async_block_NAMESPACE]]
  34. // function_containing_closure<Foo>()
  35. // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
  36. // MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
  37. #![crate_type = "lib"]
  38. use std::future::Future;
  39. pub struct Foo;
  40. pub fn non_generic_closure(x: Foo) -> Box<dyn FnOnce() -> Foo> {
  41. return Box::new(move || x);
  42. }
  43. fn function_containing_closure<T: 'static>(x: T) -> impl FnOnce() -> T {
  44. // This static only exists to trigger generating the namespace debuginfo for
  45. // `function_containing_closure` at a predictable, early point, which makes
  46. // writing the FileCheck tests above simpler.
  47. static _X: u8 = 0;
  48. return move || x;
  49. }
  50. async fn generic_async_function<T: 'static>(x: T) -> T {
  51. static _X: u8 = 0; // Same as above
  52. x
  53. }
  54. fn generic_async_block<T: 'static>(x: T) -> impl Future<Output=T> {
  55. static _X: u8 = 0; // Same as above
  56. async move {
  57. x
  58. }
  59. }
  60. pub fn instantiate_generics() {
  61. let _closure_u32 = function_containing_closure(7u32);
  62. let _closure_foo = function_containing_closure(Foo);
  63. let _async_fn_u32 = generic_async_function(42u32);
  64. let _async_fn_foo = generic_async_function(Foo);
  65. let _async_block_u32 = generic_async_block(64u32);
  66. let _async_block_foo = generic_async_block(Foo);
  67. }