Skip to content

Commit bdd09c3

Browse files
[debuginfo] Make use of spaces and separators in debuginfo names more uniform.
1 parent e6e1e09 commit bdd09c3

File tree

3 files changed

+86
-67
lines changed

3 files changed

+86
-67
lines changed

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+67-48
Original file line numberDiff line numberDiff line change
@@ -85,25 +85,14 @@ pub fn push_debuginfo_type_name<'tcx>(
8585

8686
for component_type in component_types {
8787
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
88-
output.push(',');
89-
90-
// Natvis does not always like having spaces between parts of the type name
91-
// and this causes issues when we need to write a typename in natvis, for example
92-
// as part of a cast like the `HashMap` visualizer does.
93-
if !cpp_like_names {
94-
output.push(' ');
95-
}
88+
push_arg_separator(cpp_like_names, output);
9689
}
9790
if !component_types.is_empty() {
98-
output.pop();
99-
100-
if !cpp_like_names {
101-
output.pop();
102-
}
91+
pop_arg_separator(output);
10392
}
10493

10594
if cpp_like_names {
106-
push_close_angle_bracket(tcx, output);
95+
push_close_angle_bracket(cpp_like_names, output);
10796
} else {
10897
output.push(')');
10998
}
@@ -125,7 +114,7 @@ pub fn push_debuginfo_type_name<'tcx>(
125114
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
126115

127116
if cpp_like_names {
128-
push_close_angle_bracket(tcx, output);
117+
push_close_angle_bracket(cpp_like_names, output);
129118
}
130119
}
131120
ty::Ref(_, inner_type, mutbl) => {
@@ -151,7 +140,7 @@ pub fn push_debuginfo_type_name<'tcx>(
151140
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
152141

153142
if cpp_like_names && !is_slice_or_str {
154-
push_close_angle_bracket(tcx, output);
143+
push_close_angle_bracket(cpp_like_names, output);
155144
}
156145
}
157146
ty::Array(inner_type, len) => {
@@ -183,7 +172,7 @@ pub fn push_debuginfo_type_name<'tcx>(
183172
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
184173

185174
if cpp_like_names {
186-
push_close_angle_bracket(tcx, output);
175+
push_close_angle_bracket(cpp_like_names, output);
187176
} else {
188177
output.push(']');
189178
}
@@ -196,7 +185,7 @@ pub fn push_debuginfo_type_name<'tcx>(
196185
false
197186
} else {
198187
if trait_data.len() > 1 && auto_traits.len() != 0 {
199-
// We need enclosing parens
188+
// We need enclosing parens because there is more than one trait
200189
output.push_str("(dyn ");
201190
true
202191
} else {
@@ -209,7 +198,8 @@ pub fn push_debuginfo_type_name<'tcx>(
209198
let principal =
210199
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
211200
push_item_name(tcx, principal.def_id, qualified, output);
212-
push_generic_params_internal(tcx, principal.substs, output, visited);
201+
let principal_has_generic_params =
202+
push_generic_params_internal(tcx, principal.substs, output, visited);
213203

214204
let projection_bounds: SmallVec<[_; 4]> = trait_data
215205
.projection_bounds()
@@ -220,25 +210,29 @@ pub fn push_debuginfo_type_name<'tcx>(
220210
.collect();
221211

222212
if projection_bounds.len() != 0 {
223-
pop_close_angle_bracket(output);
213+
if principal_has_generic_params {
214+
// push_generic_params_internal() above added a `>` but we actually
215+
// want to add more items to that list, so remove that again.
216+
pop_close_angle_bracket(output);
217+
}
224218

225219
for (item_def_id, ty) in projection_bounds {
226-
output.push_str(", ");
220+
push_arg_separator(cpp_like_names, output);
227221

228222
if cpp_like_names {
229223
output.push_str("assoc$<");
230224
push_item_name(tcx, item_def_id, false, output);
231-
output.push_str(", ");
225+
push_arg_separator(cpp_like_names, output);
232226
push_debuginfo_type_name(tcx, ty, true, output, visited);
233-
push_close_angle_bracket(tcx, output);
227+
push_close_angle_bracket(cpp_like_names, output);
234228
} else {
235229
push_item_name(tcx, item_def_id, false, output);
236230
output.push('=');
237231
push_debuginfo_type_name(tcx, ty, true, output, visited);
238232
}
239233
}
240234

241-
push_close_angle_bracket(tcx, output);
235+
push_close_angle_bracket(cpp_like_names, output);
242236
}
243237

244238
if auto_traits.len() != 0 {
@@ -262,11 +256,11 @@ pub fn push_debuginfo_type_name<'tcx>(
262256
push_auto_trait_separator(cpp_like_names, output);
263257
}
264258

265-
pop_auto_trait_separator(cpp_like_names, output);
259+
pop_auto_trait_separator(output);
266260
}
267261

268262
if cpp_like_names {
269-
push_close_angle_bracket(tcx, output);
263+
push_close_angle_bracket(cpp_like_names, output);
270264
} else if has_enclosing_parens {
271265
output.push(')');
272266
}
@@ -320,10 +314,9 @@ pub fn push_debuginfo_type_name<'tcx>(
320314
if !sig.inputs().is_empty() {
321315
for &parameter_type in sig.inputs() {
322316
push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
323-
output.push_str(", ");
317+
push_arg_separator(cpp_like_names, output);
324318
}
325-
output.pop();
326-
output.pop();
319+
pop_arg_separator(output);
327320
}
328321

329322
if sig.c_variadic {
@@ -429,21 +422,25 @@ pub fn push_debuginfo_type_name<'tcx>(
429422
output.push_str(&format!(", {}", variant));
430423
}
431424
}
432-
push_close_angle_bracket(tcx, output);
425+
push_close_angle_bracket(true, output);
433426
}
434427

435-
fn auto_trait_separator(cpp_like_names: bool) -> &'static str {
436-
if cpp_like_names { ", " } else { " + " }
437-
}
428+
const NON_CPP_AUTO_TRAIT_SEPARATOR: &str = " + ";
438429

439430
fn push_auto_trait_separator(cpp_like_names: bool, output: &mut String) {
440-
output.push_str(auto_trait_separator(cpp_like_names));
431+
if cpp_like_names {
432+
push_arg_separator(cpp_like_names, output);
433+
} else {
434+
output.push_str(NON_CPP_AUTO_TRAIT_SEPARATOR);
435+
}
441436
}
442437

443-
fn pop_auto_trait_separator(cpp_like_names: bool, output: &mut String) {
444-
let sep = auto_trait_separator(cpp_like_names);
445-
assert!(output.ends_with(sep));
446-
output.truncate(output.len() - sep.len());
438+
fn pop_auto_trait_separator(output: &mut String) {
439+
if output.ends_with(NON_CPP_AUTO_TRAIT_SEPARATOR) {
440+
output.truncate(output.len() - NON_CPP_AUTO_TRAIT_SEPARATOR.len());
441+
} else {
442+
pop_arg_separator(output);
443+
}
447444
}
448445
}
449446

@@ -504,13 +501,15 @@ fn push_generic_params_internal<'tcx>(
504501
substs: SubstsRef<'tcx>,
505502
output: &mut String,
506503
visited: &mut FxHashSet<Ty<'tcx>>,
507-
) {
504+
) -> bool {
508505
if substs.non_erasable_generics().next().is_none() {
509-
return;
506+
return false;
510507
}
511508

512509
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
513510

511+
let cpp_like_names = cpp_like_names(tcx);
512+
514513
output.push('<');
515514

516515
for type_parameter in substs.non_erasable_generics() {
@@ -524,13 +523,12 @@ fn push_generic_params_internal<'tcx>(
524523
other => bug!("Unexpected non-erasable generic: {:?}", other),
525524
}
526525

527-
output.push_str(", ");
526+
push_arg_separator(cpp_like_names, output);
528527
}
528+
pop_arg_separator(output);
529+
push_close_angle_bracket(cpp_like_names, output);
529530

530-
output.pop();
531-
output.pop();
532-
533-
push_close_angle_bracket(tcx, output);
531+
true
534532
}
535533

536534
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
@@ -583,24 +581,45 @@ pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, out
583581
push_generic_params_internal(tcx, substs, output, &mut visited);
584582
}
585583

586-
fn push_close_angle_bracket<'tcx>(tcx: TyCtxt<'tcx>, output: &mut String) {
584+
fn push_close_angle_bracket(cpp_like_names: bool, output: &mut String) {
587585
// MSVC debugger always treats `>>` as a shift, even when parsing templates,
588586
// so add a space to avoid confusion.
589-
if cpp_like_names(tcx) && output.ends_with('>') {
587+
if cpp_like_names && output.ends_with('>') {
590588
output.push(' ')
591589
};
592590

593591
output.push('>');
594592
}
595593

596594
fn pop_close_angle_bracket(output: &mut String) {
597-
assert!(output.ends_with('>'));
595+
assert!(output.ends_with('>'), "'output' does not end with '>': {}", output);
598596
output.pop();
599597
if output.ends_with(' ') {
600598
output.pop();
601599
}
602600
}
603601

602+
fn push_arg_separator(cpp_like_names: bool, output: &mut String) {
603+
// Natvis does not always like having spaces between parts of the type name
604+
// and this causes issues when we need to write a typename in natvis, for example
605+
// as part of a cast like the `HashMap` visualizer does.
606+
if cpp_like_names {
607+
output.push(',');
608+
} else {
609+
output.push_str(", ");
610+
};
611+
}
612+
613+
fn pop_arg_separator(output: &mut String) {
614+
if output.ends_with(' ') {
615+
output.pop();
616+
}
617+
618+
assert!(output.ends_with(','));
619+
620+
output.pop();
621+
}
622+
604623
fn cpp_like_names(tcx: TyCtxt<'_>) -> bool {
605624
tcx.sess.target.is_like_msvc
606625
}

src/test/debuginfo/function-names.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,21 @@
5252
// cdb-command:x a!function_names::*::impl_function*
5353
// cdb-check:[...] a!function_names::Mod1::TestStruct2::impl_function (void)
5454
// cdb-check:[...] a!function_names::TestStruct1::impl_function (void)
55-
// cdb-check:[...] a!function_names::GenericStruct<i32, i32>::impl_function<i32, i32> (void)
55+
// cdb-check:[...] a!function_names::GenericStruct<i32,i32>::impl_function<i32,i32> (void)
5656

5757
// Trait implementations
5858
// cdb-command:x a!function_names::*::trait_function*
5959
// cdb-check:[...] a!function_names::impl$3::trait_function<i32> (void)
60+
// cdb-check:[...] a!function_names::impl$6::trait_function<i32,1> (void)
6061
// cdb-check:[...] a!function_names::impl$1::trait_function (void)
61-
// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 1> (void)
6262
// cdb-check:[...] a!function_names::impl$5::trait_function3<function_names::TestStruct1> (void)
6363
// cdb-check:[...] a!function_names::Mod1::impl$1::trait_function (void)
6464

6565
// Closure
6666
// cdb-command:x a!function_names::*::closure*
67+
// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32,i32> (void)
6768
// cdb-check:[...] a!function_names::main::closure$0 (void)
6869
// cdb-check:[...] a!function_names::generic_func::closure$0<i32> (void)
69-
// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32, i32> (void)
7070

7171
// Generator
7272
// cdb-command:x a!function_names::*::generator*

src/test/debuginfo/type-names.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
// 0-sized structs appear to be optimized away in some cases, so only check the structs that do
174174
// actually appear.
175175
// cdb-command:dv /t *_struct
176-
// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> mut_generic_struct = [...]
176+
// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
177177

178178
// ENUMS
179179
// cdb-command:dv /t *_enum_*
@@ -190,15 +190,15 @@
190190

191191
// BOX
192192
// cdb-command:dv /t box*
193-
// cdb-check:struct tuple$<alloc::boxed::Box<f32, alloc::alloc::Global>,i32> box1 = [...]
194-
// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >, alloc::alloc::Global>,i32> box2 = [...]
193+
// cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
194+
// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
195195

196196
// REFERENCES
197197
// cdb-command:dv /t *ref*
198198
// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
199-
// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char, type_names::Struct1> >,i32> ref2 = [...]
199+
// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
200200
// cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
201-
// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> >,i32> mut_ref2 = [...]
201+
// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
202202

203203
// RAW POINTERS
204204
// cdb-command:dv /t *_ptr*
@@ -213,31 +213,31 @@
213213
// cdb-command:dv /t *vec*
214214
// cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
215215
// cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
216-
// cdb-check:struct alloc::vec::Vec<usize, alloc::alloc::Global> vec1 = [...]
217-
// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>, alloc::alloc::Global> vec2 = [...]
216+
// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
217+
// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
218218
// cdb-command:dv /t slice*
219219
// cdb-check:struct slice$<usize> slice1 = [...]
220220
// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
221221

222222
// TRAITS
223223
// cdb-command:dv /t *_trait
224-
// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize> > > > generic_mut_ref_trait = [...]
225-
// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1, type_names::Struct1> > > generic_ref_trait = [...]
226-
// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32, type_names::mod1::Struct2> >, alloc::alloc::Global> generic_box_trait = [...]
227-
// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>, alloc::alloc::Global> box_trait = [...]
224+
// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3,type_names::GenericStruct<usize,isize> > > > generic_mut_ref_trait = [...]
225+
// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1,type_names::Struct1> > > generic_ref_trait = [...]
226+
// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
227+
// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
228228
// cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
229229
// cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
230-
// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send, core::marker::Sync>, alloc::alloc::Global> no_principal_trait = [...]
231-
// 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> >
230+
// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send,core::marker::Sync>,alloc::alloc::Global> no_principal_trait = [...]
231+
// 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> >
232232

233233
// BARE FUNCTIONS
234234
// cdb-command:dv /t *_fn*
235-
// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16, u8>),usize> unsafe_fn_with_return_value = [...]
235+
// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
236236
// cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
237237
// cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
238-
// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char, f64> >),usize> unsafe_fn = [...]
238+
// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
239239
// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
240-
// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >, enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
240+
// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
241241
// cdb-command:dv /t *_function*
242242
// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
243243
// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]

0 commit comments

Comments
 (0)