diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 61e49fab6ff88..833604c533cf1 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -25,7 +25,7 @@ use rustc_data_structures::sync::Lrc; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::vec::IndexVec; use rustc_middle::mir; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeFoldable}; use rustc_session::config::{self, DebugInfo}; @@ -307,9 +307,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn_abi: &FnAbi<'tcx, Ty<'tcx>>, maybe_definition_llfn: Option<&'ll Value>, ) -> &'ll DIScope { + let tcx = self.tcx; + let def_id = instance.def_id(); let containing_scope = get_containing_scope(self, instance); - let span = self.tcx.def_span(def_id); + let span = tcx.def_span(def_id); let loc = self.lookup_debug_loc(span.lo()); let file_metadata = file_metadata(self, &loc.file); @@ -319,16 +321,24 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { }; let mut name = String::new(); - type_names::push_item_name(self.tcx(), def_id, false, &mut name); + type_names::push_item_name(tcx, def_id, false, &mut name); // Find the enclosing function, in case this is a closure. - let enclosing_fn_def_id = self.tcx().typeck_root_def_id(def_id); + let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id); + + // We look up the generics of the enclosing function and truncate the substs + // to their length in order to cut off extra stuff that might be in there for + // closures or generators. + let generics = tcx.generics_of(enclosing_fn_def_id); + let substs = instance.substs.truncate_to(tcx, generics); + + type_names::push_generic_params( + tcx, + tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs), + &mut name, + ); - // Get_template_parameters() will append a `<...>` clause to the function - // name if necessary. - let generics = self.tcx().generics_of(enclosing_fn_def_id); - let substs = instance.substs.truncate_to(self.tcx(), generics); - let template_parameters = get_template_parameters(self, generics, substs, &mut name); + let template_parameters = get_template_parameters(self, generics, substs); let linkage_name = &mangled_name_of_instance(self, instance).name; // Omit the linkage_name if it is the same as subprogram name. @@ -350,7 +360,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { if self.sess().opts.optimize != config::OptLevel::No { spflags |= DISPFlags::SPFlagOptimized; } - if let Some((id, _)) = self.tcx.entry_fn(()) { + if let Some((id, _)) = tcx.entry_fn(()) { if id == def_id { spflags |= DISPFlags::SPFlagMainSubprogram; } @@ -429,14 +439,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { cx: &CodegenCx<'ll, 'tcx>, generics: &ty::Generics, substs: SubstsRef<'tcx>, - name_to_append_suffix_to: &mut String, ) -> &'ll DIArray { - type_names::push_generic_params( - cx.tcx, - cx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs), - name_to_append_suffix_to, - ); - if substs.types().next().is_none() { return create_DIArray(DIB(cx), &[]); } diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 9687fd09a53bc..831c34d8f1f60 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -13,9 +13,9 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; +use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, AdtDef, ExistentialProjection, Ty, TyCtxt}; @@ -102,14 +102,14 @@ fn push_debuginfo_type_name<'tcx>( ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => { if cpp_like_debuginfo { match mutbl { - hir::Mutability::Not => output.push_str("ptr_const$<"), - hir::Mutability::Mut => output.push_str("ptr_mut$<"), + Mutability::Not => output.push_str("ptr_const$<"), + Mutability::Mut => output.push_str("ptr_mut$<"), } } else { output.push('*'); match mutbl { - hir::Mutability::Not => output.push_str("const "), - hir::Mutability::Mut => output.push_str("mut "), + Mutability::Not => output.push_str("const "), + Mutability::Mut => output.push_str("mut "), } } @@ -131,8 +131,8 @@ fn push_debuginfo_type_name<'tcx>( output.push_str(mutbl.prefix_str()); } else if !is_slice_or_str { match mutbl { - hir::Mutability::Not => output.push_str("ref$<"), - hir::Mutability::Mut => output.push_str("ref_mut$<"), + Mutability::Not => output.push_str("ref$<"), + Mutability::Mut => output.push_str("ref_mut$<"), } } @@ -345,14 +345,39 @@ fn push_debuginfo_type_name<'tcx>( // processing visited.remove(t); } - ty::Closure(def_id, ..) | ty::Generator(def_id, ..) => { - let key = tcx.def_key(def_id); + ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => { + // Name will be "{closure_env#0}", "{generator_env#0}", or + // "{async_fn_env#0}", etc. + let def_key = tcx.def_key(def_id); + if qualified { - let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let parent_def_id = DefId { index: def_key.parent.unwrap(), ..def_id }; push_item_name(tcx, parent_def_id, true, output); output.push_str("::"); } - push_unqualified_item_name(tcx, def_id, key.disambiguated_data, output); + + let mut label = String::with_capacity(20); + write!(&mut label, "{}_env", generator_kind_label(tcx.generator_kind(def_id))).unwrap(); + + push_disambiguated_special_name( + &label, + def_key.disambiguated_data.disambiguator, + cpp_like_debuginfo, + output, + ); + + // We also need to add the generic arguments of the async fn/generator or + // the enclosing function (for closures or async blocks), so that we end + // up with a unique name for every instantiation. + + // Find the generics of the enclosing function, as defined in the source code. + let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id); + let generics = tcx.generics_of(enclosing_fn_def_id); + + // Truncate the substs to the length of the above generics. This will cut off + // anything closure- or generator-specific. + let substs = substs.truncate_to(tcx, generics); + push_generic_params_internal(tcx, substs, output, visited); } // Type parameters from polymorphized functions. ty::Param(_) => { @@ -509,6 +534,29 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: & push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output); } +fn generator_kind_label(generator_kind: Option) -> &'static str { + match generator_kind { + Some(GeneratorKind::Async(AsyncGeneratorKind::Block)) => "async_block", + Some(GeneratorKind::Async(AsyncGeneratorKind::Closure)) => "async_closure", + Some(GeneratorKind::Async(AsyncGeneratorKind::Fn)) => "async_fn", + Some(GeneratorKind::Gen) => "generator", + None => "closure", + } +} + +fn push_disambiguated_special_name( + label: &str, + disambiguator: u32, + cpp_like_debuginfo: bool, + output: &mut String, +) { + if cpp_like_debuginfo { + write!(output, "{}${}", label, disambiguator).unwrap(); + } else { + write!(output, "{{{}#{}}}", label, disambiguator).unwrap(); + } +} + fn push_unqualified_item_name( tcx: TyCtxt<'_>, def_id: DefId, @@ -519,42 +567,32 @@ fn push_unqualified_item_name( DefPathData::CrateRoot => { output.push_str(tcx.crate_name(def_id.krate).as_str()); } - DefPathData::ClosureExpr if tcx.generator_kind(def_id).is_some() => { - let key = match tcx.generator_kind(def_id).unwrap() { - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn", - hir::GeneratorKind::Gen => "generator", - }; - // Generators look like closures, but we want to treat them differently - // in the debug info. - if cpp_like_debuginfo(tcx) { - write!(output, "{}${}", key, disambiguated_data.disambiguator).unwrap(); - } else { - write!(output, "{{{}#{}}}", key, disambiguated_data.disambiguator).unwrap(); - } + DefPathData::ClosureExpr => { + let label = generator_kind_label(tcx.generator_kind(def_id)); + + push_disambiguated_special_name( + label, + disambiguated_data.disambiguator, + cpp_like_debuginfo(tcx), + output, + ); } _ => match disambiguated_data.data.name() { DefPathDataName::Named(name) => { output.push_str(name.as_str()); } DefPathDataName::Anon { namespace } => { - if cpp_like_debuginfo(tcx) { - write!(output, "{}${}", namespace, disambiguated_data.disambiguator).unwrap(); - } else { - write!(output, "{{{}#{}}}", namespace, disambiguated_data.disambiguator) - .unwrap(); - } + push_disambiguated_special_name( + namespace.as_str(), + disambiguated_data.disambiguator, + cpp_like_debuginfo(tcx), + output, + ); } }, }; } -// Pushes the generic parameters in the given `InternalSubsts` to the output string. -// This ignores region parameters, since they can't reliably be -// reconstructed for items from non-local crates. For local crates, this -// would be possible but with inlining and LTO we have to use the least -// common denominator - otherwise we would run into conflicts. fn push_generic_params_internal<'tcx>( tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs index bb0db9d3d8514..a90c85a54491d 100644 --- a/src/test/codegen/async-fn-debug-msvc.rs +++ b/src/test/codegen/async-fn-debug-msvc.rs @@ -17,7 +17,7 @@ async fn async_fn_test() { // FIXME: No way to reliably check the filename. // CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "async_fn$0" +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "async_fn_env$0" // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]], // For brevity, we only check the struct name and members of the last variant. // CHECK-SAME: file: [[FILE:![0-9]*]], line: 11, diff --git a/src/test/codegen/async-fn-debug.rs b/src/test/codegen/async-fn-debug.rs index f456f7ffc0fba..8fbd2765fd771 100644 --- a/src/test/codegen/async-fn-debug.rs +++ b/src/test/codegen/async-fn-debug.rs @@ -17,7 +17,7 @@ async fn async_fn_test() { // FIXME: No way to reliably check the filename. // CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn#0}", scope: [[ASYNC_FN]] +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[ASYNC_FN]] // CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: discriminator: [[DISC:![0-9]*]] diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs index 1c8cc61f204dd..35fd275fd2897 100644 --- a/src/test/codegen/debug-vtable.rs +++ b/src/test/codegen/debug-vtable.rs @@ -1,25 +1,36 @@ -// compile-flags: -Cdebuginfo=2 -Copt-level=0 -Ccodegen-units=1 -// ignore-tidy-linelength - // This test checks the debuginfo for the expected 3 vtables is generated for correct names and number // of entries. -// NONMSVC-LABEL: !DIGlobalVariable(name: "::{vtable}" -// MSVC-LABEL: !DIGlobalVariable(name: "impl$::vtable$" +// 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 +// ignore-tidy-linelength + +// NONMSVC: !DIGlobalVariable(name: "::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$::vtable$" // NONMSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()", // MSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$ >", // CHECK: !DISubrange(count: 5 -// NONMSVC-LABEL: !DIGlobalVariable(name: ">::{vtable}" -// MSVC-LABEL: !DIGlobalVariable(name: "impl$ >::vtable$" +// NONMSVC: !DIGlobalVariable(name: ">::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$ >::vtable$" // CHECK: !DISubrange(count: 4 -// NONMSVC-LABEL: !DIGlobalVariable(name: "::{vtable}" -// MSVC-LABEL: !DIGlobalVariable(name: "impl$::vtable$" +// NONMSVC: !DIGlobalVariable(name: "::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$::vtable$" // CHECK: !DISubrange(count: 3 -// NONMSVC-LABEL: !DIGlobalVariable(name: ">)>>::{vtable}" -// MSVC-LABEL: !DIGlobalVariable(name: "impl$,assoc$ > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$" +// NONMSVC: !DIGlobalVariable(name: ">)>>::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$,assoc$ > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$" + +// NONMSVC: !DIGlobalVariable(name: " as core::ops::function::FnOnce<()>>::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$, core::ops::function::FnOnce > >::vtable$ + +// NONMSVC: !DIGlobalVariable(name: " as core::ops::function::FnOnce<()>>::{vtable}" +// MSVC: !DIGlobalVariable(name: "impl$, core::ops::function::FnOnce > >::vtable$ #![crate_type = "lib"] @@ -31,8 +42,12 @@ pub trait SomeTrait { } impl SomeTrait for Foo { - fn method1(&self) -> u32 { 1 } - fn method2(&self) -> u32 { 2 } + fn method1(&self) -> u32 { + 1 + } + fn method2(&self) -> u32 { + 2 + } } pub trait SomeTraitWithGenerics { @@ -40,7 +55,9 @@ pub trait SomeTraitWithGenerics { } impl SomeTraitWithGenerics for Foo { - fn method1(&self) -> (u64, i8) { (1, 2) } + fn method1(&self) -> (u64, i8) { + (1, 2) + } } pub fn foo(x: &Foo) -> (u32, (u64, i8), &dyn Send) { @@ -55,3 +72,11 @@ pub fn foo(x: &Foo) -> (u32, (u64, i8), &dyn Send) { pub fn bar() -> Box)> { Box::new(|_x: Option<&dyn Fn()>| {}) } + +fn generic_closure(x: T) -> Box T> { + Box::new(move || x) +} + +pub fn instantiate_generic_closures() -> (Box u32>, Box bool>) { + (generic_closure(1u32), generic_closure(false)) +} diff --git a/src/test/codegen/debuginfo-generic-closure-env-names.rs b/src/test/codegen/debuginfo-generic-closure-env-names.rs new file mode 100644 index 0000000000000..6e5ac95126130 --- /dev/null +++ b/src/test/codegen/debuginfo-generic-closure-env-names.rs @@ -0,0 +1,91 @@ +// 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. +// +// 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. + +// ignore-tidy-linelength + +// 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 --edition 2021 -Copt-level=0 -Csymbol-mangling-version=v0 + + +// CHECK: [[non_generic_closure_NAMESPACE:!.*]] = !DINamespace(name: "non_generic_closure" +// CHECK: [[function_containing_closure_NAMESPACE:!.*]] = !DINamespace(name: "function_containing_closure" +// CHECK: [[generic_async_function_NAMESPACE:!.*]] = !DINamespace(name: "generic_async_function" +// CHECK: [[generic_async_block_NAMESPACE:!.*]] = !DINamespace(name: "generic_async_block" + +// non_generic_closure() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[non_generic_closure_NAMESPACE]] +// MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: [[non_generic_closure_NAMESPACE]] + +// function_containing_closure() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[function_containing_closure_NAMESPACE]] +// MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: [[function_containing_closure_NAMESPACE]] + +// generic_async_function() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[generic_async_function_NAMESPACE]] + +// generic_async_function() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[generic_async_function_NAMESPACE]] + +// generic_async_block() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}", scope: [[generic_async_block_NAMESPACE]] + +// generic_async_block() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}", scope: [[generic_async_block_NAMESPACE]] + +// function_containing_closure() +// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[function_containing_closure_NAMESPACE]] +// MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: [[function_containing_closure_NAMESPACE]] + + +#![crate_type = "lib"] +use std::future::Future; + +pub struct Foo; + +pub fn non_generic_closure(x: Foo) -> Box Foo> { + // 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 Box::new(move || x); +} + +fn function_containing_closure(x: T) -> impl FnOnce() -> T { + static _X: u8 = 0; // Same as above + + return move || x; +} + +async fn generic_async_function(x: T) -> T { + static _X: u8 = 0; // Same as above + x +} + +fn generic_async_block(x: T) -> impl Future { + 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); +} diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs index 68d138f8df2f0..fb8b9e09fd24d 100644 --- a/src/test/codegen/generator-debug-msvc.rs +++ b/src/test/codegen/generator-debug-msvc.rs @@ -21,7 +21,7 @@ fn generator_test() -> impl Generator { // FIXME: No way to reliably check the filename. // CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator$0" +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator_env$0" // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]], // For brevity, we only check the struct name and members of the last variant. // CHECK-SAME: file: [[FILE:![0-9]*]], line: 14, diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs index ea324695c15d7..e777fe3af63e0 100644 --- a/src/test/codegen/generator-debug.rs +++ b/src/test/codegen/generator-debug.rs @@ -21,7 +21,7 @@ fn generator_test() -> impl Generator { // FIXME: No way to reliably check the filename. // CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{generator#0}", scope: [[GEN_FN]] +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{generator_env#0}", scope: [[GEN_FN]] // CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: discriminator: [[DISC:![0-9]*]] diff --git a/src/test/debuginfo/captured-fields-1.rs b/src/test/debuginfo/captured-fields-1.rs index 65f9e5f532279..afbf942d40471 100644 --- a/src/test/debuginfo/captured-fields-1.rs +++ b/src/test/debuginfo/captured-fields-1.rs @@ -4,44 +4,44 @@ // gdb-command:run // gdb-command:print test -// gdbr-check:$1 = captured_fields_1::main::{closure#0} {_ref__my_ref__my_field1: 0x[...]} +// gdbr-check:$1 = captured_fields_1::main::{closure_env#0} {_ref__my_ref__my_field1: 0x[...]} // gdb-command:continue // gdb-command:print test -// gdbr-check:$2 = captured_fields_1::main::{closure#1} {_ref__my_ref__my_field2: 0x[...]} +// gdbr-check:$2 = captured_fields_1::main::{closure_env#1} {_ref__my_ref__my_field2: 0x[...]} // gdb-command:continue // gdb-command:print test -// gdbr-check:$3 = captured_fields_1::main::{closure#2} {_ref__my_ref: 0x[...]} +// gdbr-check:$3 = captured_fields_1::main::{closure_env#2} {_ref__my_ref: 0x[...]} // gdb-command:continue // gdb-command:print test -// gdbr-check:$4 = captured_fields_1::main::{closure#3} {my_ref: 0x[...]} +// gdbr-check:$4 = captured_fields_1::main::{closure_env#3} {my_ref: 0x[...]} // gdb-command:continue // gdb-command:print test -// gdbr-check:$5 = captured_fields_1::main::{closure#4} {my_var__my_field2: 22} +// gdbr-check:$5 = captured_fields_1::main::{closure_env#4} {my_var__my_field2: 22} // gdb-command:continue // gdb-command:print test -// gdbr-check:$6 = captured_fields_1::main::{closure#5} {my_var: captured_fields_1::MyStruct {my_field1: 11, my_field2: 22}} +// gdbr-check:$6 = captured_fields_1::main::{closure_env#5} {my_var: captured_fields_1::MyStruct {my_field1: 11, my_field2: 22}} // gdb-command:continue // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#0}) $0 = { _ref__my_ref__my_field1 = 0x[...] } +// lldbg-check:(captured_fields_1::main::{closure_env#0}) $0 = { _ref__my_ref__my_field1 = 0x[...] } // lldb-command:continue // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#1}) $1 = { _ref__my_ref__my_field2 = 0x[...] } +// lldbg-check:(captured_fields_1::main::{closure_env#1}) $1 = { _ref__my_ref__my_field2 = 0x[...] } // lldb-command:continue // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#2}) $2 = { _ref__my_ref = 0x[...] } +// lldbg-check:(captured_fields_1::main::{closure_env#2}) $2 = { _ref__my_ref = 0x[...] } // lldb-command:continue // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#3}) $3 = { my_ref = 0x[...] } +// lldbg-check:(captured_fields_1::main::{closure_env#3}) $3 = { my_ref = 0x[...] } // lldb-command:continue // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#4}) $4 = { my_var__my_field2 = 22 } +// lldbg-check:(captured_fields_1::main::{closure_env#4}) $4 = { my_var__my_field2 = 22 } // lldb-command:continue // lldb-command:print test -// lldbg-check:(captured_fields_1::main::{closure#5}) $5 = { my_var = { my_field1 = 11 my_field2 = 22 } } +// lldbg-check:(captured_fields_1::main::{closure_env#5}) $5 = { my_var = { my_field1 = 11 my_field2 = 22 } } // lldb-command:continue #![feature(capture_disjoint_fields)] @@ -53,10 +53,7 @@ struct MyStruct { } fn main() { - let mut my_var = MyStruct { - my_field1: 11, - my_field2: 22, - }; + let mut my_var = MyStruct { my_field1: 11, my_field2: 22 }; let my_ref = &mut my_var; let test = || { diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs index ac9a02cce0481..73e34d4bb3211 100644 --- a/src/test/debuginfo/function-names.rs +++ b/src/test/debuginfo/function-names.rs @@ -27,9 +27,9 @@ // Closure // gdb-command:info functions -q function_names::.*::{closure.* -// gdb-check:[...]static fn function_names::generic_func::{closure#0}(*mut function_names::generic_func::{closure#0}); -// gdb-check:[...]static fn function_names::main::{closure#0}(*mut function_names::main::{closure#0}); -// gdb-check:[...]static fn function_names::{impl#2}::impl_function::{closure#0}(*mut function_names::{impl#2}::impl_function::{closure#0}); +// gdb-check:[...]static fn function_names::generic_func::{closure#0}(*mut function_names::generic_func::{closure_env#0}); +// gdb-check:[...]static fn function_names::main::{closure#0}(*mut function_names::main::{closure_env#0}); +// gdb-check:[...]static fn function_names::{impl#2}::impl_function::{closure#0}(*mut function_names::{impl#2}::impl_function::{closure_env#0}); // Generator // Generators don't seem to appear in GDB's symbol table. @@ -86,9 +86,9 @@ #![feature(adt_const_params, generators, generator_trait)] #![allow(incomplete_features)] -use Mod1::TestTrait2; use std::ops::Generator; use std::pin::Pin; +use Mod1::TestTrait2; fn main() { // Implementations @@ -107,16 +107,19 @@ fn main() { let _ = generic_func(42i32); // Closure - let closure = || { TestStruct1 }; + let closure = || TestStruct1; closure(); // Generator - let mut generator = || { yield; return; }; + let mut generator = || { + yield; + return; + }; Pin::new(&mut generator).resume(()); // Const generic functions const_generic_fn_bool::(); - const_generic_fn_non_int::<{()}>(); + const_generic_fn_non_int::<{ () }>(); const_generic_fn_signed_int::<-7>(); const_generic_fn_unsigned_int::<14>(); } @@ -158,7 +161,7 @@ struct GenericStruct(std::marker::PhantomData<(T1, T2)>); impl GenericStruct { pub fn impl_function() { // Closure in a generic implementation - let closure = || { TestStruct1 }; + let closure = || TestStruct1; closure(); } } @@ -190,7 +193,7 @@ impl TestTrait1 for GenericStruct<[T; N], f32> { // Generic function fn generic_func(value: T) -> T { // Closure in a generic function - let closure = || { TestStruct1 }; + let closure = || TestStruct1; closure(); value diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index 9bf33a7bb8796..aee19736e7e1d 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -11,31 +11,31 @@ // gdb-command:run // gdb-command:print b -// gdb-check:$1 = generator_objects::main::{generator#0}::Unresumed{_ref__a: 0x[...]} +// gdb-check:$1 = generator_objects::main::{generator_env#0}::Unresumed{_ref__a: 0x[...]} // gdb-command:continue // gdb-command:print b -// gdb-check:$2 = generator_objects::main::{generator#0}::Suspend0{c: 6, d: 7, _ref__a: 0x[...]} +// gdb-check:$2 = generator_objects::main::{generator_env#0}::Suspend0{c: 6, d: 7, _ref__a: 0x[...]} // gdb-command:continue // gdb-command:print b -// gdb-check:$3 = generator_objects::main::{generator#0}::Suspend1{c: 7, d: 8, _ref__a: 0x[...]} +// gdb-check:$3 = generator_objects::main::{generator_env#0}::Suspend1{c: 7, d: 8, _ref__a: 0x[...]} // gdb-command:continue // gdb-command:print b -// gdb-check:$4 = generator_objects::main::{generator#0}::Returned{_ref__a: 0x[...]} +// gdb-check:$4 = generator_objects::main::{generator_env#0}::Returned{_ref__a: 0x[...]} // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:print b -// lldbg-check:(generator_objects::main::{generator#0}) $0 = +// lldbg-check:(generator_objects::main::{generator_env#0}) $0 = // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::{generator#0}) $1 = +// lldbg-check:(generator_objects::main::{generator_env#0}) $1 = // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::{generator#0}) $2 = +// lldbg-check:(generator_objects::main::{generator_env#0}) $2 = // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::{generator#0}) $3 = +// lldbg-check:(generator_objects::main::{generator_env#0}) $3 = #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] @@ -66,4 +66,6 @@ fn main() { _zzz(); // #break } -fn _zzz() {()} +fn _zzz() { + () +} diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs index 1a26b0a3255b7..62e7eb13c2dc9 100644 --- a/src/test/debuginfo/issue-57822.rs +++ b/src/test/debuginfo/issue-57822.rs @@ -11,20 +11,20 @@ // gdb-command:run // gdb-command:print g -// gdb-check:$1 = issue_57822::main::{closure#1} {f: issue_57822::main::{closure#0} {x: 1}} +// gdb-check:$1 = issue_57822::main::{closure_env#1} {f: issue_57822::main::{closure_env#0} {x: 1}} // gdb-command:print b -// gdb-check:$2 = issue_57822::main::{generator#3}::Unresumed{a: issue_57822::main::{generator#2}::Unresumed{y: 2}} +// gdb-check:$2 = issue_57822::main::{generator_env#3}::Unresumed{a: issue_57822::main::{generator_env#2}::Unresumed{y: 2}} // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:print g -// lldbg-check:(issue_57822::main::{closure#1}) $0 = { f = { x = 1 } } +// lldbg-check:(issue_57822::main::{closure_env#1}) $0 = { f = { x = 1 } } // lldb-command:print b -// lldbg-check:(issue_57822::main::{generator#3}) $1 = +// lldbg-check:(issue_57822::main::{generator_env#3}) $1 = #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] @@ -50,4 +50,6 @@ fn main() { zzz(); // #break } -fn zzz() { () } +fn zzz() { + () +} diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 2c10360fc924e..c96921285626a 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -122,7 +122,6 @@ // gdb-command:whatis has_associated_type_trait // gdb-check:type = &(dyn type_names::Trait3 + core::marker::Send) - // BARE FUNCTIONS // gdb-command:whatis rust_fn // gdb-check:type = (fn(core::option::Option, core::option::Option<&type_names::mod1::Struct2>), usize) @@ -153,10 +152,10 @@ // CLOSURES // gdb-command:whatis closure1 -// gdb-check:type = (type_names::main::{closure#0}, usize) +// gdb-check:type = (type_names::main::{closure_env#0}, usize) // gdb-command:whatis closure2 -// gdb-check:type = (type_names::main::{closure#1}, usize) +// gdb-check:type = (type_names::main::{closure_env#1}, usize) // FOREIGN TYPES // gdb-command:whatis foreign1 @@ -254,8 +253,8 @@ // CLOSURES // cdb-command:dv /t closure* -// cdb-check:struct tuple$ closure2 = [...] -// cdb-check:struct tuple$ closure1 = [...] +// cdb-check:struct tuple$ closure2 = [...] +// cdb-check:struct tuple$ closure1 = [...] // FOREIGN TYPES // cdb-command:dv /t foreign* @@ -279,7 +278,9 @@ enum Enum1 { Variant2(isize), } -extern { type ForeignType1; } +extern "C" { + type ForeignType1; +} mod mod1 { pub use self::Enum2::{Variant1, Variant2}; @@ -300,7 +301,9 @@ mod mod1 { } } - extern { pub type ForeignType2; } + extern "C" { + pub type ForeignType2; + } } trait Trait1 { @@ -311,7 +314,9 @@ trait Trait2 { } trait Trait3 { type AssocType; - fn dummy(&self) -> T { panic!() } + fn dummy(&self) -> T { + panic!() + } } impl Trait1 for isize {} @@ -441,8 +446,8 @@ fn main() { let closure2 = (|x: i8, y: f32| (x as f32) + y, 0_usize); // Foreign Types - let foreign1 = unsafe{ 0 as *const ForeignType1 }; - let foreign2 = unsafe{ 0 as *const mod1::ForeignType2 }; + let foreign1 = unsafe { 0 as *const ForeignType1 }; + let foreign2 = unsafe { 0 as *const mod1::ForeignType2 }; zzz(); // #break } diff --git a/src/test/debuginfo/var-captured-in-nested-closure.rs b/src/test/debuginfo/var-captured-in-nested-closure.rs index d811915c38767..537c0b50b8b64 100644 --- a/src/test/debuginfo/var-captured-in-nested-closure.rs +++ b/src/test/debuginfo/var-captured-in-nested-closure.rs @@ -108,7 +108,7 @@ // cdb-command: dx closure_local // cdb-check:closure_local : 8 [Type: [...]] // cdb-command: dx nested_closure -// cdb-check:nested_closure [Type: var_captured_in_nested_closure::main::closure$0::closure$0] +// cdb-check:nested_closure [Type: var_captured_in_nested_closure::main::closure$0::closure_env$0] // cdb-command: g