mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			91 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // ignore-tidy-linelength
 | |
| //! This test checks that we get proper type names for closure environments and
 | |
| //! async-fn environments in debuginfo, especially making sure that generic arguments
 | |
| //! of the enclosing functions don't get lost.
 | |
| //!
 | |
| //! Unfortunately, the order that debuginfo gets emitted into LLVM IR becomes a bit hard
 | |
| //! to predict once async fns are involved, so DAG allows any order.
 | |
| //!
 | |
| //! Note that the test does not check async-fns when targeting MSVC because debuginfo for
 | |
| //! those does not follow the enum-fallback encoding yet and thus is incomplete.
 | |
| 
 | |
| //@ revisions: MSVC NONMSVC
 | |
| //@[MSVC] only-msvc
 | |
| //@[NONMSVC] ignore-msvc
 | |
| 
 | |
| // Use the v0 symbol mangling scheme to codegen order independent of rustc version.
 | |
| // Unnamed items like shims are generated in lexicographical order of their symbol name and in the
 | |
| // legacy mangling scheme rustc version and generic parameters are both hashed into a single part
 | |
| // of the name, thus randomizing item order with respect to rustc version.
 | |
| 
 | |
| //@ compile-flags: -Cdebuginfo=2 -Copt-level=0 -Csymbol-mangling-version=v0
 | |
| //@ edition: 2021
 | |
| 
 | |
| // non_generic_closure()
 | |
| // NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: ![[non_generic_closure_NAMESPACE:[0-9]+]],
 | |
| // MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: ![[non_generic_closure_NAMESPACE:[0-9]+]],
 | |
| // CHECK: ![[non_generic_closure_NAMESPACE]] = !DINamespace(name: "non_generic_closure"
 | |
| 
 | |
| // CHECK: ![[function_containing_closure_NAMESPACE:[0-9]+]] = !DINamespace(name: "function_containing_closure"
 | |
| // CHECK: ![[generic_async_function_NAMESPACE:[0-9]+]] = !DINamespace(name: "generic_async_function"
 | |
| // CHECK: ![[generic_async_block_NAMESPACE:[0-9]+]] = !DINamespace(name: "generic_async_block"
 | |
| 
 | |
| // function_containing_closure<u32>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<u32>", scope: ![[function_containing_closure_NAMESPACE]]
 | |
| // MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<u32>", scope: ![[function_containing_closure_NAMESPACE]]
 | |
| 
 | |
| // generic_async_function<Foo>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_function_NAMESPACE]]
 | |
| 
 | |
| // generic_async_function<u32>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<u32>", scope: ![[generic_async_function_NAMESPACE]]
 | |
| 
 | |
| // generic_async_block<Foo>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_block_NAMESPACE]]
 | |
| 
 | |
| // generic_async_block<u32>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<u32>", scope: ![[generic_async_block_NAMESPACE]]
 | |
| 
 | |
| // function_containing_closure<Foo>()
 | |
| // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
 | |
| // MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
 | |
| 
 | |
| #![crate_type = "lib"]
 | |
| use std::future::Future;
 | |
| 
 | |
| pub struct Foo;
 | |
| 
 | |
| pub fn non_generic_closure(x: Foo) -> Box<dyn FnOnce() -> Foo> {
 | |
|     return Box::new(move || x);
 | |
| }
 | |
| 
 | |
| fn function_containing_closure<T: 'static>(x: T) -> impl FnOnce() -> T {
 | |
|     // This static only exists to trigger generating the namespace debuginfo for
 | |
|     // `function_containing_closure` at a predictable, early point, which makes
 | |
|     // writing the FileCheck tests above simpler.
 | |
|     static _X: u8 = 0;
 | |
| 
 | |
|     return move || x;
 | |
| }
 | |
| 
 | |
| async fn generic_async_function<T: 'static>(x: T) -> T {
 | |
|     static _X: u8 = 0; // Same as above
 | |
|     x
 | |
| }
 | |
| 
 | |
| fn generic_async_block<T: 'static>(x: T) -> impl Future<Output = T> {
 | |
|     static _X: u8 = 0; // Same as above
 | |
|     async move { x }
 | |
| }
 | |
| 
 | |
| pub fn instantiate_generics() {
 | |
|     let _closure_u32 = function_containing_closure(7u32);
 | |
|     let _closure_foo = function_containing_closure(Foo);
 | |
| 
 | |
|     let _async_fn_u32 = generic_async_function(42u32);
 | |
|     let _async_fn_foo = generic_async_function(Foo);
 | |
| 
 | |
|     let _async_block_u32 = generic_async_block(64u32);
 | |
|     let _async_block_foo = generic_async_block(Foo);
 | |
| }
 | 
