From 39986eb142a1f84a58f3b1c9414a06842d41f48b Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 14:14:42 -0400 Subject: [PATCH 01/13] feat: Add `subspan` helper method to SpanUtil Helper method to get the `Span` of a known substring within a span. --- src/source_map.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/source_map.rs b/src/source_map.rs index 76e0d24cf1e..148b9560a07 100644 --- a/src/source_map.rs +++ b/src/source_map.rs @@ -5,9 +5,11 @@ use rustc_span::{BytePos, Span}; use crate::comment::FindUncommented; use crate::config::file_lines::LineRange; +use crate::utils::mk_sp; use crate::visitor::SnippetProvider; pub(crate) trait SpanUtils { + fn subspan(&self, original: Span, needle: &str) -> Span; fn span_after(&self, original: Span, needle: &str) -> BytePos; fn span_after_last(&self, original: Span, needle: &str) -> BytePos; fn span_before(&self, original: Span, needle: &str) -> BytePos; @@ -26,6 +28,12 @@ pub(crate) trait LineRangeUtils { } impl SpanUtils for SnippetProvider { + fn subspan(&self, original: Span, needle: &str) -> Span { + let lo = self.span_before(original, needle); + let hi = lo + BytePos(needle.len() as u32); + mk_sp(lo, hi) + } + fn span_after(&self, original: Span, needle: &str) -> BytePos { self.opt_span_after(original, needle).unwrap_or_else(|| { panic!( From 6a6b3b692dd228f1baaba0a64711d5032c417a49 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 14:22:54 -0400 Subject: [PATCH 02/13] refactor: Add `HeaderPart::keyword` helper and refactor macro formatting Simplify macro header formatting by using the new `HeaderPart::keyword` associated function. --- src/header.rs | 12 ++++++++++++ src/macros.rs | 4 +--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/header.rs b/src/header.rs index 5a9d2beb010..877cb5c7a4e 100644 --- a/src/header.rs +++ b/src/header.rs @@ -15,6 +15,7 @@ use tracing::debug; use crate::comment::{combine_strs_with_missing_comments, contains_comment}; use crate::rewrite::RewriteContext; use crate::shape::Shape; +use crate::source_map::SpanUtils; use crate::utils::rewrite_ident; pub(crate) fn format_header( @@ -68,6 +69,17 @@ pub(crate) struct HeaderPart<'a> { } impl<'a> HeaderPart<'a> { + /// Find the `keyword` for the header within the give `span` + pub(crate) fn keyword( + context: &RewriteContext<'_>, + span: Span, + keyword: impl Into>, + ) -> Self { + let snippet = keyword.into(); + let span = context.snippet_provider.subspan(span, &snippet); + Self::new(snippet, span) + } + pub(crate) fn new(snippet: impl Into>, span: Span) -> Self { Self { snippet: snippet.into(), diff --git a/src/macros.rs b/src/macros.rs index 2d56021069c..8513d5a1f73 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -435,11 +435,9 @@ pub(crate) fn rewrite_macro_def( let pos = context.snippet_provider.span_after(span, "macro_rules!"); vec![HeaderPart::new("macro_rules!", span.with_hi(pos))] } else { - let macro_lo = context.snippet_provider.span_before(span, "macro"); - let macro_hi = macro_lo + BytePos("macro".len() as u32); vec![ HeaderPart::visibility(context, vis), - HeaderPart::new("macro", mk_sp(macro_lo, macro_hi)), + HeaderPart::keyword(context, span, "macro"), ] }; From 5901b8b422567af463b5bf6c0af75b88950e6184 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 14:32:41 -0400 Subject: [PATCH 03/13] feat: add HeaderPart methods to format `constness`, `safety`, and `auto` --- src/header.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/header.rs b/src/header.rs index 877cb5c7a4e..e1103148515 100644 --- a/src/header.rs +++ b/src/header.rs @@ -8,8 +8,8 @@ use std::borrow::Cow; use rustc_ast as ast; -use rustc_span::Span; use rustc_span::symbol::Ident; +use rustc_span::{DUMMY_SP, Span}; use tracing::debug; use crate::comment::{combine_strs_with_missing_comments, contains_comment}; @@ -69,6 +69,12 @@ pub(crate) struct HeaderPart<'a> { } impl<'a> HeaderPart<'a> { + /// Create a new empty HeaderPart with a DUMMY_SP. + /// Because the snippet is empty these will be skipped when calling `format_header`. + fn empty() -> Self { + Self::new("", DUMMY_SP) + } + /// Find the `keyword` for the header within the give `span` pub(crate) fn keyword( context: &RewriteContext<'_>, @@ -115,4 +121,26 @@ impl<'a> HeaderPart<'a> { Self::new(snippet, vis.span) } + + pub(crate) fn constness(constness: ast::Const) -> Self { + match constness { + ast::Const::No => Self::empty(), + ast::Const::Yes(span) => Self::new("const", span), + } + } + + pub(crate) fn safety(safety: ast::Safety) -> Self { + match safety { + ast::Safety::Default => Self::empty(), + ast::Safety::Unsafe(span) => Self::new("unsafe", span), + ast::Safety::Safe(span) => Self::new("safe", span), + } + } + + pub(crate) fn auto(context: &RewriteContext<'_>, span: Span, is_auto: ast::IsAuto) -> Self { + match is_auto { + ast::IsAuto::No => Self::empty(), + ast::IsAuto::Yes => Self::keyword(context, span, "auto"), + } + } } From b82ab6839c09cd5a9eef08bf4d8dfe1e705bd0e7 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 11 Jun 2026 20:44:09 -0400 Subject: [PATCH 04/13] refactor: add HeaderPart method to format `impl_restriction` --- src/header.rs | 15 ++++++++++++++- src/utils.rs | 11 ++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/header.rs b/src/header.rs index e1103148515..5288128fab1 100644 --- a/src/header.rs +++ b/src/header.rs @@ -16,7 +16,7 @@ use crate::comment::{combine_strs_with_missing_comments, contains_comment}; use crate::rewrite::RewriteContext; use crate::shape::Shape; use crate::source_map::SpanUtils; -use crate::utils::rewrite_ident; +use crate::utils::{format_impl_restriction, rewrite_ident}; pub(crate) fn format_header( context: &RewriteContext<'_>, @@ -122,6 +122,19 @@ impl<'a> HeaderPart<'a> { Self::new(snippet, vis.span) } + pub(crate) fn impl_restriction( + context: &RewriteContext<'_>, + impl_restriction: &ast::ImplRestriction, + ) -> Self { + match impl_restriction.kind { + ast::RestrictionKind::Unrestricted => Self::empty(), + ast::RestrictionKind::Restricted { .. } => { + let restriction = format_impl_restriction(context, impl_restriction); + Self::new(restriction, impl_restriction.span) + } + } + } + pub(crate) fn constness(constness: ast::Const) -> Self { match constness { ast::Const::No => Self::empty(), diff --git a/src/utils.rs b/src/utils.rs index d0e27a908b8..f9b4410fa67 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -78,20 +78,21 @@ pub(crate) fn format_impl_restriction( context: &RewriteContext<'_>, impl_restriction: &ImplRestriction, ) -> String { - format_restriction("impl", context, &impl_restriction.kind) + format_restriction("impl", context, &impl_restriction.kind, false) } pub(crate) fn format_mut_restriction( context: &RewriteContext<'_>, mut_restriction: &MutRestriction, ) -> String { - format_restriction("mut", context, &mut_restriction.kind) + format_restriction("mut", context, &mut_restriction.kind, true) } fn format_restriction( kw: &'static str, context: &RewriteContext<'_>, restriction: &RestrictionKind, + trailing_space: bool, ) -> String { match restriction { RestrictionKind::Unrestricted => String::new(), @@ -110,7 +111,11 @@ fn format_restriction( let path = itertools::join(segments_iter, "::"); let in_str = if *shorthand { "" } else { "in " }; - format!("{kw}({in_str}{path}) ") + if trailing_space { + format!("{kw}({in_str}{path}) ") + } else { + format!("{kw}({in_str}{path})") + } } } } From 4b380cfbe35687faab7f507660c6d44f480d0d6a Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 14:42:18 -0400 Subject: [PATCH 05/13] refactor: use `HeaderPart` to simplify `trait` header formatting --- src/items.rs | 26 ++++++++++++++++---------- src/utils.rs | 2 ++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/items.rs b/src/items.rs index 484c5b50adf..c8f2909c68a 100644 --- a/src/items.rs +++ b/src/items.rs @@ -21,6 +21,7 @@ use crate::expr::{ rewrite_assign_rhs_with, rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, rewrite_let_else_block, }; +use crate::header::HeaderPart; use crate::lists::{ListFormatting, Separator, definitive_tactic, itemize_list, write_list}; use crate::macros::{MacroPosition, rewrite_macro}; use crate::overflow; @@ -1166,19 +1167,24 @@ pub(crate) fn format_trait( } = *trait_; let mut result = String::with_capacity(128); - let header = format!( - "{}{}{}{}{}trait ", - format_visibility(context, &item.vis), - format_impl_restriction(context, impl_restriction), - format_constness(constness), - format_safety(safety), - format_auto(is_auto), - ); - result.push_str(&header); + let header = vec![ + HeaderPart::visibility(context, &item.vis), + HeaderPart::impl_restriction(context, impl_restriction), + HeaderPart::constness(constness), + HeaderPart::safety(safety), + HeaderPart::auto(context, item.span, is_auto), + HeaderPart::keyword(context, item.span, "trait"), + ]; + + let shape = Shape::indented(offset, context.config); + let header_rewrite = crate::header::format_header(context, shape, header); let body_lo = context.snippet_provider.span_after(item.span, "{"); + result.push_str(&header_rewrite); + result.push(' '); - let shape = Shape::indented(offset, context.config).offset_left(result.len(), item.span)?; + let shape = + Shape::indented(offset, context.config).offset_left(last_line_width(&result), item.span)?; let generics_str = rewrite_generics(context, rewrite_ident(context, ident), generics, shape)?; result.push_str(&generics_str); diff --git a/src/utils.rs b/src/utils.rs index f9b4410fa67..fed233100d0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -155,6 +155,8 @@ pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str { } } +// FIXME(ytmimi) might want to get rid of `format_auto` since we now have `HeaderPart::auto` +#[allow(unused)] #[inline] pub(crate) fn format_auto(is_auto: ast::IsAuto) -> &'static str { match is_auto { From a1cecf3b85b260aca263dd3d7ec9c2f8a94e1416 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 15:52:28 -0400 Subject: [PATCH 06/13] fix: prevent duplicating comments and tokens in trait header Keep track of the `lo` span when rewriting parts the header so that we can correctly recover comments between the last rewritten part of the trait definition and the body of the trait. --- src/items.rs | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/items.rs b/src/items.rs index c8f2909c68a..1ebec540f6b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1179,7 +1179,6 @@ pub(crate) fn format_trait( let shape = Shape::indented(offset, context.config); let header_rewrite = crate::header::format_header(context, shape, header); - let body_lo = context.snippet_provider.span_after(item.span, "{"); result.push_str(&header_rewrite); result.push(' '); @@ -1188,6 +1187,9 @@ pub(crate) fn format_trait( let generics_str = rewrite_generics(context, rewrite_ident(context, ident), generics, shape)?; result.push_str(&generics_str); + // Keep track of the last position that we've written. This will help us recover comments + let mut current_rewite_lo = generics.span.hi(); + // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds. if !bounds.is_empty() { // Retrieve *unnormalized* ident (See #6069) @@ -1207,6 +1209,8 @@ pub(crate) fn format_trait( &RhsAssignKind::Bounds, RhsTactics::ForceNextLineWithoutIndent, )?; + + current_rewite_lo = bound_hi; } // Rewrite where-clause. @@ -1214,11 +1218,6 @@ pub(crate) fn format_trait( let where_on_new_line = context.config.indent_style() != IndentStyle::Block; let where_budget = context.budget(last_line_width(&result)); - let pos_before_where = if bounds.is_empty() { - generics.where_clause.span.lo() - } else { - bounds[bounds.len() - 1].span().hi() - }; let option = WhereClauseOption::snuggled(&generics_str); let where_clause_str = rewrite_where_clause( context, @@ -1228,7 +1227,7 @@ pub(crate) fn format_trait( where_on_new_line, "{", None, - pos_before_where, + current_rewite_lo, option, )?; @@ -1244,27 +1243,23 @@ pub(crate) fn format_trait( } result.push_str(&where_clause_str); } else { - let item_snippet = context.snippet(item.span); - if let Some(lo) = item_snippet.find('/') { - // 1 = `{` - let comment_hi = if generics.params.len() > 0 { - generics.span.lo() - BytePos(1) - } else { - body_lo - BytePos(1) - }; - let comment_lo = item.span.lo() + BytePos(lo as u32); - if comment_lo < comment_hi { - match recover_missing_comment_in_span( - mk_sp(comment_lo, comment_hi), - Shape::indented(offset, context.config), - context, - last_line_width(&result), - ) { - Ok(ref missing_comment) if !missing_comment.is_empty() => { - result.push_str(missing_comment); - } - _ => (), + let span_rest = mk_sp(current_rewite_lo, item.span.hi()); + let body_lo = context.snippet_provider.span_before(span_rest, "{"); + let comment_span = span_rest.with_hi(body_lo); + let snippet = context.snippet(comment_span); + + if let Some(lo) = snippet.find('/') { + let comment_span = comment_span.with_lo(comment_span.lo() + BytePos(lo as u32)); + match recover_missing_comment_in_span( + comment_span, + Shape::indented(offset, context.config), + context, + last_line_width(&result), + ) { + Ok(ref missing_comment) if !missing_comment.is_empty() => { + result.push_str(missing_comment); } + _ => (), } } } From f409211f38bc73b0c7d57ea3dbbb3c62d7a16174 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 15:57:50 -0400 Subject: [PATCH 07/13] test: Add formatting test case for issue 6160 --- tests/target/issue_6160.rs | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/target/issue_6160.rs diff --git a/tests/target/issue_6160.rs b/tests/target/issue_6160.rs new file mode 100644 index 00000000000..86bb1ee3e1c --- /dev/null +++ b/tests/target/issue_6160.rs @@ -0,0 +1 @@ +pub/* (crate) */ trait MyTrait {} From 7b1cefd628175579653fd87dfa745c2596e9568f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 16:02:05 -0400 Subject: [PATCH 08/13] test: add test case for issue 5841 --- tests/source/issue_5841.rs | 2 ++ tests/target/issue_5841.rs | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 tests/source/issue_5841.rs create mode 100644 tests/target/issue_5841.rs diff --git a/tests/source/issue_5841.rs b/tests/source/issue_5841.rs new file mode 100644 index 00000000000..428ed96e9e5 --- /dev/null +++ b/tests/source/issue_5841.rs @@ -0,0 +1,2 @@ +pub // should the following be private? +trait Asso<'ciativity> {} diff --git a/tests/target/issue_5841.rs b/tests/target/issue_5841.rs new file mode 100644 index 00000000000..01493aa41cc --- /dev/null +++ b/tests/target/issue_5841.rs @@ -0,0 +1,4 @@ +pub // should the following be private? +trait Asso<'ciativity> +{ +} From 1ab70d0c182cdca0654945b6abc5c7b63ee37a4b Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 20 Mar 2026 16:36:42 -0400 Subject: [PATCH 09/13] test: Add more trait header test cases with comments --- tests/source/trait.rs | 17 +++++++++++++++++ tests/target/trait.rs | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/source/trait.rs b/tests/source/trait.rs index 1970646f777..2662f137c5c 100644 --- a/tests/source/trait.rs +++ b/tests/source/trait.rs @@ -102,9 +102,26 @@ trait FooBar = Foo // #2637 auto trait Example {} + +auto /* post auto comment */ trait AutoExampleWithComments {} + pub auto trait PubExample {} + +pub /* post pub comment */ auto /* post auto comment */ trait PubAutoExampleWithComments {} + pub unsafe auto trait PubUnsafeExample {} +pub // post pub comment +unsafe +/* post unsafe comment */ +auto /* post auto comment */ trait PubUnsafeAutoExampleWithComments {} + +pub // post pub comment +const /* post const comment */ +unsafe +/* post unsafe comment */ +auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments {} + // #3006 trait Foo<'a> { type Bar< 'a >; diff --git a/tests/target/trait.rs b/tests/target/trait.rs index 7a65b13d629..ab3bba1a50f 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -137,9 +137,30 @@ trait FooBar = Foo // #2637 auto trait Example {} + +auto /* post auto comment */ trait AutoExampleWithComments {} + pub auto trait PubExample {} + +pub /* post pub comment */ auto /* post auto comment */ trait PubAutoExampleWithComments {} + pub unsafe auto trait PubUnsafeExample {} +pub // post pub comment +unsafe +/* post unsafe comment */ +auto /* post auto comment */ trait PubUnsafeAutoExampleWithComments +{ +} + +pub // post pub comment +const /* post const comment */ +unsafe +/* post unsafe comment */ +auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments +{ +} + // #3006 trait Foo<'a> { type Bar<'a>; From be56f6eafc2b526aa9b7c57a35898a6f6e77447c Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 23 Mar 2026 12:57:09 -0400 Subject: [PATCH 10/13] chore: remove unused `crate::utils::format_auto` Using `HeaderPart::auto` for formatting instead. --- src/utils.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index fed233100d0..cbf2ac47079 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -155,16 +155,6 @@ pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str { } } -// FIXME(ytmimi) might want to get rid of `format_auto` since we now have `HeaderPart::auto` -#[allow(unused)] -#[inline] -pub(crate) fn format_auto(is_auto: ast::IsAuto) -> &'static str { - match is_auto { - ast::IsAuto::Yes => "auto ", - ast::IsAuto::No => "", - } -} - #[inline] pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str { match mutability { From a4e23ff0a12d3e3ef68fd2d59edecd1f7643a282 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 23 Mar 2026 13:00:21 -0400 Subject: [PATCH 11/13] chore: fix typo `give` -> `given` --- src/header.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/header.rs b/src/header.rs index 5288128fab1..9b1dcdaf5a7 100644 --- a/src/header.rs +++ b/src/header.rs @@ -75,7 +75,7 @@ impl<'a> HeaderPart<'a> { Self::new("", DUMMY_SP) } - /// Find the `keyword` for the header within the give `span` + /// Find the `keyword` for the header within the given `span` pub(crate) fn keyword( context: &RewriteContext<'_>, span: Span, From 8280773677cf947d170eae308bd78a7787e323e7 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 23 Mar 2026 20:45:09 -0400 Subject: [PATCH 12/13] fix: recover comments between `trait` keyword and `ident` --- src/items.rs | 20 ++++++++++++++++---- tests/source/trait.rs | 2 ++ tests/target/trait.rs | 2 ++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/items.rs b/src/items.rs index 1ebec540f6b..b7a61e9af48 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1180,12 +1180,24 @@ pub(crate) fn format_trait( let header_rewrite = crate::header::format_header(context, shape, header); result.push_str(&header_rewrite); - result.push(' '); - let shape = - Shape::indented(offset, context.config).offset_left(last_line_width(&result), item.span)?; + // +1 to account for space between `trait` and the `ident` + let offset_left = last_line_width(&result) + 1; + let shape = Shape::indented(offset, context.config).offset_left(offset_left, item.span)?; let generics_str = rewrite_generics(context, rewrite_ident(context, ident), generics, shape)?; - result.push_str(&generics_str); + + let comment_span_lo = context.snippet_provider.span_after(item.span, "trait"); + let comment_span = mk_sp(comment_span_lo, ident.span.lo() - BytePos(1)); + + result = combine_strs_with_missing_comments( + context, + &result, + &generics_str, + comment_span, + // infinite_width so we don't put the `ident + generics_str` on the next line + shape.infinite_width(), + true, + )?; // Keep track of the last position that we've written. This will help us recover comments let mut current_rewite_lo = generics.span.hi(); diff --git a/tests/source/trait.rs b/tests/source/trait.rs index 2662f137c5c..de1e83145b6 100644 --- a/tests/source/trait.rs +++ b/tests/source/trait.rs @@ -122,6 +122,8 @@ unsafe /* post unsafe comment */ auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments {} +pub /* first */ trait /* second */ MyTrait /* third */ {} + // #3006 trait Foo<'a> { type Bar< 'a >; diff --git a/tests/target/trait.rs b/tests/target/trait.rs index ab3bba1a50f..92ce45f05a1 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -161,6 +161,8 @@ auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments { } +pub /* first */ trait /* second */ MyTrait /* third */ {} + // #3006 trait Foo<'a> { type Bar<'a>; From 7003775f1194377016819a95e57a5f25da240184 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 26 Mar 2026 22:47:14 -0400 Subject: [PATCH 13/13] test: add test case with indented trait header comments --- tests/source/trait.rs | 8 ++++++++ tests/target/trait.rs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/source/trait.rs b/tests/source/trait.rs index de1e83145b6..49b0ffc8d7c 100644 --- a/tests/source/trait.rs +++ b/tests/source/trait.rs @@ -124,6 +124,14 @@ auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments {} pub /* first */ trait /* second */ MyTrait /* third */ {} +pub + /* a */ + trait + /* b */ + Foo + /* c */ +{} + // #3006 trait Foo<'a> { type Bar< 'a >; diff --git a/tests/target/trait.rs b/tests/target/trait.rs index 92ce45f05a1..53e942267c0 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -163,6 +163,14 @@ auto /* post auto comment */ trait PubConstUnsafeAutoExampleWithComments pub /* first */ trait /* second */ MyTrait /* third */ {} +pub + /* a */ + trait +/* b */ +Foo /* c */ +{ +} + // #3006 trait Foo<'a> { type Bar<'a>;