Skip to content

Commit 5f9de6b

Browse files
fee1-deadcalebcartwright
authored andcommitted
Recover comments between attrs and generic param
Fixes #5320.
1 parent e903fcd commit 5f9de6b

File tree

3 files changed

+67
-31
lines changed

3 files changed

+67
-31
lines changed

src/overflow.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ impl<'a> Context<'a> {
589589

590590
fn rewrite_items(&self) -> Option<(bool, String)> {
591591
let span = self.items_span();
592+
debug!("items: {:?}", self.items);
593+
592594
let items = itemize_list(
593595
self.context.snippet_provider,
594596
self.items.iter(),
@@ -603,6 +605,8 @@ impl<'a> Context<'a> {
603605
);
604606
let mut list_items: Vec<_> = items.collect();
605607

608+
debug!("items: {list_items:?}");
609+
606610
// Try letting the last argument overflow to the next line with block
607611
// indentation. If its first line fits on one line with the other arguments,
608612
// we format the function arguments horizontally.

src/types.rs

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -572,49 +572,41 @@ impl Rewrite for ast::GenericBounds {
572572

573573
impl Rewrite for ast::GenericParam {
574574
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
575-
let mut result = String::with_capacity(128);
576575
// FIXME: If there are more than one attributes, this will force multiline.
577-
match self.attrs.rewrite(context, shape) {
578-
Some(ref rw) if !rw.is_empty() => {
579-
result.push_str(rw);
580-
// When rewriting generic params, an extra newline should be put
581-
// if the attributes end with a doc comment
582-
if let Some(true) = self.attrs.last().map(|a| a.is_doc_comment()) {
583-
result.push_str(&shape.indent.to_string_with_newline(context.config));
584-
} else {
585-
result.push(' ');
586-
}
587-
}
588-
_ => (),
589-
}
576+
let mut result = self.attrs.rewrite(context, shape).unwrap_or(String::new());
577+
let has_attrs = !result.is_empty();
590578

591-
if let ast::GenericParamKind::Const {
579+
let mut param = String::with_capacity(128);
580+
581+
let param_start = if let ast::GenericParamKind::Const {
592582
ref ty,
593-
kw_span: _,
583+
kw_span,
594584
default,
595585
} = &self.kind
596586
{
597-
result.push_str("const ");
598-
result.push_str(rewrite_ident(context, self.ident));
599-
result.push_str(": ");
600-
result.push_str(&ty.rewrite(context, shape)?);
587+
param.push_str("const ");
588+
param.push_str(rewrite_ident(context, self.ident));
589+
param.push_str(": ");
590+
param.push_str(&ty.rewrite(context, shape)?);
601591
if let Some(default) = default {
602592
let eq_str = match context.config.type_punctuation_density() {
603593
TypeDensity::Compressed => "=",
604594
TypeDensity::Wide => " = ",
605595
};
606-
result.push_str(eq_str);
607-
let budget = shape.width.checked_sub(result.len())?;
596+
param.push_str(eq_str);
597+
let budget = shape.width.checked_sub(param.len())?;
608598
let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?;
609-
result.push_str(&rewrite);
599+
param.push_str(&rewrite);
610600
}
601+
kw_span.lo()
611602
} else {
612-
result.push_str(rewrite_ident(context, self.ident));
613-
}
603+
param.push_str(rewrite_ident(context, self.ident));
604+
self.ident.span.lo()
605+
};
614606

615607
if !self.bounds.is_empty() {
616-
result.push_str(type_bound_colon(context));
617-
result.push_str(&self.bounds.rewrite(context, shape)?)
608+
param.push_str(type_bound_colon(context));
609+
param.push_str(&self.bounds.rewrite(context, shape)?)
618610
}
619611
if let ast::GenericParamKind::Type {
620612
default: Some(ref def),
@@ -624,11 +616,33 @@ impl Rewrite for ast::GenericParam {
624616
TypeDensity::Compressed => "=",
625617
TypeDensity::Wide => " = ",
626618
};
627-
result.push_str(eq_str);
628-
let budget = shape.width.checked_sub(result.len())?;
619+
param.push_str(eq_str);
620+
let budget = shape.width.checked_sub(param.len())?;
629621
let rewrite =
630-
def.rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?;
631-
result.push_str(&rewrite);
622+
def.rewrite(context, Shape::legacy(budget, shape.indent + param.len()))?;
623+
param.push_str(&rewrite);
624+
}
625+
626+
if let Some(last_attr) = self.attrs.last().filter(|last_attr| {
627+
contains_comment(context.snippet(mk_sp(last_attr.span.hi(), param_start)))
628+
}) {
629+
result = combine_strs_with_missing_comments(
630+
context,
631+
&result,
632+
&param,
633+
mk_sp(last_attr.span.hi(), param_start),
634+
shape,
635+
!last_attr.is_doc_comment(),
636+
)?;
637+
} else {
638+
// When rewriting generic params, an extra newline should be put
639+
// if the attributes end with a doc comment
640+
if let Some(true) = self.attrs.last().map(|a| a.is_doc_comment()) {
641+
result.push_str(&shape.indent.to_string_with_newline(context.config));
642+
} else if has_attrs {
643+
result.push(' ');
644+
}
645+
result.push_str(&param);
632646
}
633647

634648
Some(result)

tests/target/doc-of-generic-item.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,21 @@ struct Foo<
1212
/// doc of N
1313
const N: item,
1414
>;
15+
16+
// Non-doc pre-comment of Foo
17+
/// doc of Foo
18+
// Non-doc post-comment of Foo
19+
struct Foo<
20+
// Non-doc pre-comment of 'a
21+
/// doc of 'a
22+
// Non-doc post-comment of 'a
23+
'a,
24+
// Non-doc pre-comment of T
25+
/// doc of T
26+
// Non-doc post-comment of T
27+
T,
28+
// Non-doc pre-comment of N
29+
/// doc of N
30+
// Non-doc post-comment of N
31+
const N: item,
32+
>;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy