diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index fc2921fbd3f..4b1563ca3c9 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -226,13 +226,18 @@ fn push_debuginfo_type_name<'tcx>( if projection_bounds.len() != 0 { if principal_has_generic_params { // push_generic_params_internal() above added a `>` but we actually - // want to add more items to that list, so remove that again. + // want to add more items to that list, so remove that again... pop_close_angle_bracket(output); + // .. and add a comma to separate the regular generic args from the + // associated types. + push_arg_separator(cpp_like_debuginfo, output); + } else { + // push_generic_params_internal() did not add `<...>`, so we open + // angle brackets here. + output.push('<'); } for (item_def_id, ty) in projection_bounds { - push_arg_separator(cpp_like_debuginfo, output); - if cpp_like_debuginfo { output.push_str("assoc$<"); push_item_name(tcx, item_def_id, false, output); @@ -244,8 +249,10 @@ fn push_debuginfo_type_name<'tcx>( output.push('='); push_debuginfo_type_name(tcx, ty, true, output, visited); } + push_arg_separator(cpp_like_debuginfo, output); } + pop_arg_separator(output); push_close_angle_bracket(cpp_like_debuginfo, output); } diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 52841d50f64..b040a6e7494 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -122,6 +122,9 @@ // gdb-command:whatis has_associated_type_trait // gdb-check:type = &(dyn type_names::Trait3 + core::marker::Send) +// gdb-command:whatis has_associated_type_but_no_generics_trait +// gdb-check:type = &dyn type_names::TraitNoGenericsButWithAssocType + // BARE FUNCTIONS // gdb-command:whatis rust_fn // gdb-check:type = (fn(core::option::Option, core::option::Option<&type_names::mod1::Struct2>), usize) @@ -228,6 +231,7 @@ // cdb-check:struct ref_mut$ > mut_ref_trait = [...] // cdb-check:struct alloc::boxed::Box,alloc::alloc::Global> no_principal_trait = [...] // cdb-check:struct ref$ >,core::marker::Send> > has_associated_type_trait = struct ref$ >,core::marker::Send> > +// cdb-check:struct ref$ > > > has_associated_type_but_no_generics_trait = struct ref$ > > > // BARE FUNCTIONS // cdb-command:dv /t *_fn* @@ -317,12 +321,22 @@ trait Trait3 { panic!() } } +trait TraitNoGenericsButWithAssocType { + type Output; + fn foo(&self) -> Self::Output; +} impl Trait1 for isize {} impl Trait2 for isize {} impl Trait3 for isize { type AssocType = isize; } +impl TraitNoGenericsButWithAssocType for isize { + type Output = isize; + fn foo(&self) -> Self::Output { + *self + } +} fn rust_fn(_: Option, _: Option<&mod1::Struct2>) {} extern "C" fn extern_c_fn(_: isize) {} @@ -413,6 +427,8 @@ fn main() { let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1; let no_principal_trait = Box::new(0_isize) as Box<(dyn Send + Sync)>; let has_associated_type_trait = &0_isize as &(dyn Trait3 + Send); + let has_associated_type_but_no_generics_trait = + &0_isize as &dyn TraitNoGenericsButWithAssocType; let generic_box_trait = Box::new(0_isize) as Box>; let generic_ref_trait = (&0_isize) as &dyn Trait2;