Recover comments between attrs and generic param

Fixes #5320.
This commit is contained in:
Deadbeef 2023-06-10 17:27:24 +00:00 committed by Caleb Cartwright
parent e903fcdaae
commit 5f9de6bfc9
3 changed files with 67 additions and 31 deletions

View File

@ -589,6 +589,8 @@ impl<'a> Context<'a> {
fn rewrite_items(&self) -> Option<(bool, String)> {
let span = self.items_span();
debug!("items: {:?}", self.items);
let items = itemize_list(
self.context.snippet_provider,
self.items.iter(),
@ -603,6 +605,8 @@ impl<'a> Context<'a> {
);
let mut list_items: Vec<_> = items.collect();
debug!("items: {list_items:?}");
// Try letting the last argument overflow to the next line with block
// indentation. If its first line fits on one line with the other arguments,
// we format the function arguments horizontally.

View File

@ -572,49 +572,41 @@ impl Rewrite for ast::GenericBounds {
impl Rewrite for ast::GenericParam {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
let mut result = String::with_capacity(128);
// FIXME: If there are more than one attributes, this will force multiline.
match self.attrs.rewrite(context, shape) {
Some(ref rw) if !rw.is_empty() => {
result.push_str(rw);
// When rewriting generic params, an extra newline should be put
// if the attributes end with a doc comment
if let Some(true) = self.attrs.last().map(|a| a.is_doc_comment()) {
result.push_str(&shape.indent.to_string_with_newline(context.config));
} else {
result.push(' ');
}
}
_ => (),
}
let mut result = self.attrs.rewrite(context, shape).unwrap_or(String::new());
let has_attrs = !result.is_empty();
if let ast::GenericParamKind::Const {
let mut param = String::with_capacity(128);
let param_start = if let ast::GenericParamKind::Const {
ref ty,
kw_span: _,
kw_span,
default,
} = &self.kind
{
result.push_str("const ");
result.push_str(rewrite_ident(context, self.ident));
result.push_str(": ");
result.push_str(&ty.rewrite(context, shape)?);
param.push_str("const ");
param.push_str(rewrite_ident(context, self.ident));
param.push_str(": ");
param.push_str(&ty.rewrite(context, shape)?);
if let Some(default) = default {
let eq_str = match context.config.type_punctuation_density() {
TypeDensity::Compressed => "=",
TypeDensity::Wide => " = ",
};
result.push_str(eq_str);
let budget = shape.width.checked_sub(result.len())?;
param.push_str(eq_str);
let budget = shape.width.checked_sub(param.len())?;
let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?;
result.push_str(&rewrite);
param.push_str(&rewrite);
}
kw_span.lo()
} else {
result.push_str(rewrite_ident(context, self.ident));
}
param.push_str(rewrite_ident(context, self.ident));
self.ident.span.lo()
};
if !self.bounds.is_empty() {
result.push_str(type_bound_colon(context));
result.push_str(&self.bounds.rewrite(context, shape)?)
param.push_str(type_bound_colon(context));
param.push_str(&self.bounds.rewrite(context, shape)?)
}
if let ast::GenericParamKind::Type {
default: Some(ref def),
@ -624,11 +616,33 @@ impl Rewrite for ast::GenericParam {
TypeDensity::Compressed => "=",
TypeDensity::Wide => " = ",
};
result.push_str(eq_str);
let budget = shape.width.checked_sub(result.len())?;
param.push_str(eq_str);
let budget = shape.width.checked_sub(param.len())?;
let rewrite =
def.rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?;
result.push_str(&rewrite);
def.rewrite(context, Shape::legacy(budget, shape.indent + param.len()))?;
param.push_str(&rewrite);
}
if let Some(last_attr) = self.attrs.last().filter(|last_attr| {
contains_comment(context.snippet(mk_sp(last_attr.span.hi(), param_start)))
}) {
result = combine_strs_with_missing_comments(
context,
&result,
&param,
mk_sp(last_attr.span.hi(), param_start),
shape,
!last_attr.is_doc_comment(),
)?;
} else {
// When rewriting generic params, an extra newline should be put
// if the attributes end with a doc comment
if let Some(true) = self.attrs.last().map(|a| a.is_doc_comment()) {
result.push_str(&shape.indent.to_string_with_newline(context.config));
} else if has_attrs {
result.push(' ');
}
result.push_str(&param);
}
Some(result)

View File

@ -12,3 +12,21 @@ struct Foo<
/// doc of N
const N: item,
>;
// Non-doc pre-comment of Foo
/// doc of Foo
// Non-doc post-comment of Foo
struct Foo<
// Non-doc pre-comment of 'a
/// doc of 'a
// Non-doc post-comment of 'a
'a,
// Non-doc pre-comment of T
/// doc of T
// Non-doc post-comment of T
T,
// Non-doc pre-comment of N
/// doc of N
// Non-doc post-comment of N
const N: item,
>;