From cc0daadc498d69953989d7954a9ad6c34ba23715 Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Mon, 22 Mar 2021 09:35:17 +0200 Subject: [PATCH] Changes per comments and with added test cases --- src/formatting/expr.rs | 38 ++++++++- src/formatting/items.rs | 26 +++--- src/formatting/macros.rs | 3 + .../lhs-to-rhs-between-comments/trait.rs | 41 ++++++++++ .../lhs-to-rhs-between-comments/trait.rs | 81 +++++++++++++++++++ tests/target/trait.rs | 10 ++- tests/target/trait_2015_edition.rs | 10 ++- 7 files changed, 181 insertions(+), 28 deletions(-) diff --git a/src/formatting/expr.rs b/src/formatting/expr.rs index 0cbd9ac3587..4c44c222d4d 100644 --- a/src/formatting/expr.rs +++ b/src/formatting/expr.rs @@ -1938,12 +1938,13 @@ pub(crate) fn rewrite_assign_rhs, R: Rewrite>( rewrite_assign_rhs_with(context, lhs, ex, shape, RhsTactics::Default) } -pub(crate) fn rewrite_assign_rhs_expr( +pub(crate) fn rewrite_rhs_expr( context: &RewriteContext<'_>, lhs: &str, ex: &R, shape: Shape, rhs_tactics: RhsTactics, + lhs_separator: &str, ) -> Option { let last_line_width = last_line_width(&lhs).saturating_sub(if lhs.contains('\n') { shape.indent.width() @@ -1956,7 +1957,7 @@ pub(crate) fn rewrite_assign_rhs_expr( offset: shape.offset + last_line_width + 1, ..shape }); - let has_rhs_comment = if let Some(offset) = lhs.find_last_uncommented("=") { + let has_rhs_comment = if let Some(offset) = lhs.find_last_uncommented(lhs_separator) { lhs.trim_end().len() > offset + 1 } else { false @@ -1980,7 +1981,7 @@ pub(crate) fn rewrite_assign_rhs_with, R: Rewrite>( rhs_tactics: RhsTactics, ) -> Option { let lhs = lhs.into(); - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_rhs_expr(context, &lhs, ex, shape, rhs_tactics, "=")?; Some(lhs + &rhs) } @@ -2000,7 +2001,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( } else { shape }; - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_rhs_expr(context, &lhs, ex, shape, rhs_tactics, "=")?; if contains_comment { let rhs = rhs.trim_start(); @@ -2010,6 +2011,35 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( } } +pub(crate) fn rewrite_trait_rhs_with_comments, R: Rewrite>( + context: &RewriteContext<'_>, + lhs: S, + ex: &R, + shape: Shape, + rhs_tactics: RhsTactics, + between_span: Span, + allow_extend: bool, +) -> Option { + let lhs = lhs.into(); + let contains_comment = contains_comment(context.snippet(between_span)); + + let rhs = rewrite_rhs_expr(context, &lhs, ex, shape, rhs_tactics, ":")?; + + if contains_comment { + let rhs = rhs.trim_start(); + combine_strs_with_missing_comments( + context, + &lhs, + &rhs, + between_span, + shape.block_left(context.config.tab_spaces())?, + allow_extend, + ) + } else { + Some(lhs + &rhs) + } +} + fn choose_rhs( context: &RewriteContext<'_>, expr: &R, diff --git a/src/formatting/items.rs b/src/formatting/items.rs index 241a071d817..0d40d337326 100644 --- a/src/formatting/items.rs +++ b/src/formatting/items.rs @@ -19,7 +19,7 @@ use crate::formatting::{ }, expr::{ is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with, - rewrite_assign_rhs_with_comments, RhsTactics, + rewrite_assign_rhs_with_comments, rewrite_trait_rhs_with_comments, RhsTactics, }, lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}, macros::{rewrite_macro, MacroPosition}, @@ -1122,6 +1122,12 @@ pub(crate) fn format_trait( if let ast::ItemKind::Trait(trait_kind) = &item.kind { let ast::TraitKind(is_auto, unsafety, ref generics, ref generic_bounds, ref trait_items) = **trait_kind; + + // FIXME: rustfmt fails to format when there are comments before the ident. + if contains_comment(context.snippet(mk_sp(item.span.lo(), item.ident.span.lo()))) { + return None; + } + let mut result = String::with_capacity(128); let header = format!( "{}{}{}trait ", @@ -1131,11 +1137,6 @@ pub(crate) fn format_trait( ); result.push_str(&header); - // FIXME: rustfmt fails to format when there are comments before the ident. - if contains_comment(context.snippet(mk_sp(item.span.lo(), generics.span.lo()))) { - return None; - } - let body_lo = context.snippet_provider.span_after(item.span, "{"); let shape = Shape::indented(offset, context.config).offset_left(result.len())?; @@ -1143,23 +1144,16 @@ pub(crate) fn format_trait( rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape)?; result.push_str(&generics_str); - // FIXME(#2055): rustfmt fails to format when there are comments within trait bounds. if !generic_bounds.is_empty() { - let bound_lo = generic_bounds.first().unwrap().span().lo(); - let bound_hi = generic_bounds.last().unwrap().span().hi(); - let snippet = context.snippet(mk_sp(bound_lo, bound_hi)); - if contains_comment(snippet) { - return None; - } - // Rewrite rhs and combine lhs with pre-bound comment + let bound_lo = generic_bounds.first().unwrap().span().lo(); let ident_hi = context .snippet_provider .span_after(item.span, &item.ident.as_str()); let ident_hi = context .snippet_provider .span_after(mk_sp(ident_hi, item.span.hi()), ":"); - result = rewrite_assign_rhs_with_comments( + result = rewrite_trait_rhs_with_comments( context, result + ":", generic_bounds, @@ -1205,7 +1199,7 @@ pub(crate) fn format_trait( result.push_str(&where_clause_str); } - /* Note: `where_clause` always exists; Span is empty when no where clause in the code */ + /* Note: `where_clause` always exists; Span is empty when no `where` clause in the code */ let pre_block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); let pre_block_snippet = context.snippet(pre_block_span); if let Some(lo) = pre_block_snippet.find('/') { diff --git a/src/formatting/macros.rs b/src/formatting/macros.rs index 53032f58c7a..e4104f9b225 100644 --- a/src/formatting/macros.rs +++ b/src/formatting/macros.rs @@ -1356,6 +1356,9 @@ impl MacroBranch { result += " =>"; } + // Note (from issue #4759): comments between the end of `whole_body` and + // the end of `span` are currently ignored. + if !context.config.format_macro_bodies() { result += " "; result += context.snippet(self.whole_body); diff --git a/tests/source/lhs-to-rhs-between-comments/trait.rs b/tests/source/lhs-to-rhs-between-comments/trait.rs index aec52320bd8..6da8c5f32c5 100644 --- a/tests/source/lhs-to-rhs-between-comments/trait.rs +++ b/tests/source/lhs-to-rhs-between-comments/trait.rs @@ -25,6 +25,15 @@ A + C + B {} pub trait Foo6:/* A and C */A + C + B{} +pub trait Foo7: +A+C +// and B ++B{} +pub trait Foo8: +// A and C +A+C +// and B ++B{} // Other cases trait Person{ @@ -68,3 +77,35 @@ trait /* comment 1 */ Programmer /* comment2 */ { trait /* comment1 */ CompSciStudent1: /* comment2 */ Programmer + Student /* comment3 */ { fn git_username(&self) -> String; } + +// Traits with where and comments +trait Bar where Self: Sized, Option: Foo +{} +/*comment0*/trait Bar/*comment1*/where Self: Sized/*comment2*/,/*comment3*/Option: Foo/*comment4*/ +{} +trait Bar//comment1 Longgggggggggggggggggggggggggggggggggggggggggggggggggg +where Self: Sized/*comment2*/,/*comment3*/Option: Foo/*comment4*/ +{} +trait Bar/*comment1*/where Self: Sized/*comment2*/,/*comment3*/Option: Foo//comment4 Longgggggggggggggggggggggggggggggggggggggggggggggggggg +{} +trait Bar/*comment1 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/where Self: Sized/*comment2 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/,/*comment3 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/Option: Foo/*comment4 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/ +{} +trait ConstCheck:/*comment1*/Foo where T: Baz/*comment2*/{ + const J: i32; +} + +// Some other trait cases with comments +/*comment0*/auto trait Example/*comment1*/{} +pub unsafe auto trait PubUnsafeExample/*comment1*/{} +pub unsafe auto trait PubUnsafeExample// comment1 +{} +trait Foo/*comment1*/{ type Bar: Baz; type Inner: Foo = Box< Foo >; } +pub trait Iterator/*comment1*/{ + type Item; + fn next(&mut self) -> Option; +} +pub trait Iterator//comment1 +{ + type Item; + fn next(&mut self) -> Option; +} diff --git a/tests/target/lhs-to-rhs-between-comments/trait.rs b/tests/target/lhs-to-rhs-between-comments/trait.rs index 4bb13cdd8bb..5e092978afc 100644 --- a/tests/target/lhs-to-rhs-between-comments/trait.rs +++ b/tests/target/lhs-to-rhs-between-comments/trait.rs @@ -19,6 +19,21 @@ pub trait Foo4: // A and C } pub trait Foo5: /* A and C */ A + C + B {} pub trait Foo6: /* A and C */ A + C + B {} +pub trait Foo7: + A + + C + // and B + + B +{ +} +pub trait Foo8: + // A and C + A + + C + // and B + + B +{ +} // Other cases trait Person { @@ -68,3 +83,69 @@ trait /* comment 1 */ Programmer /* comment2 */ { trait /* comment1 */ CompSciStudent1: /* comment2 */ Programmer + Student /* comment3 */ { fn git_username(&self) -> String; } + +// Traits with where and comments +trait Bar +where + Self: Sized, + Option: Foo, +{ +} +/*comment0*/ +trait Bar +/*comment1*/ +where + Self: Sized, /*comment2*/ + /*comment3*/ Option: Foo, /*comment4*/ +{ +} +trait Bar +//comment1 Longgggggggggggggggggggggggggggggggggggggggggggggggggg +where + Self: Sized, /*comment2*/ + /*comment3*/ Option: Foo, /*comment4*/ +{ +} +trait Bar +/*comment1*/ +where + Self: Sized, /*comment2*/ + /*comment3*/ Option: Foo, +//comment4 Longgggggggggggggggggggggggggggggggggggggggggggggggggg +{ +} +trait Bar +/*comment1 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/ +where + Self: Sized, /*comment2 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/ + /*comment3 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/ Option: Foo, +/*comment4 Longgggggggggggggggggggggggggggggggggggggggggggggggggg*/ +{ +} +trait ConstCheck: /*comment1*/ Foo +where + T: Baz, /*comment2*/ +{ + const J: i32; +} + +// Some other trait cases with comments +/*comment0*/ +auto trait Example /*comment1*/ {} +pub unsafe auto trait PubUnsafeExample /*comment1*/ {} +pub unsafe auto trait PubUnsafeExample // comment1 +{ +} +trait Foo /*comment1*/ { + type Bar: Baz; + type Inner: Foo = Box; +} +pub trait Iterator /*comment1*/ { + type Item; + fn next(&mut self) -> Option; +} +pub trait Iterator //comment1 +{ + type Item; + fn next(&mut self) -> Option; +} diff --git a/tests/target/trait.rs b/tests/target/trait.rs index 7bfab72fb73..8e9d1ce0e7f 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -86,11 +86,13 @@ trait Y // comment // #2055 pub trait Foo: -// A and C -A + C -// and B + // A and C + A + + C + // and B + B -{} +{ +} // #2158 trait Foo { diff --git a/tests/target/trait_2015_edition.rs b/tests/target/trait_2015_edition.rs index 4a2ee0d0088..69f6b19034d 100644 --- a/tests/target/trait_2015_edition.rs +++ b/tests/target/trait_2015_edition.rs @@ -89,11 +89,13 @@ trait Y // comment // #2055 pub trait Foo: -// A and C -A + C -// and B + // A and C + A + + C + // and B + B -{} +{ +} // #2158 trait Foo {