Skip to content

Backport PR #4730 #5390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,28 @@ fn join_bounds_inner(
ast::GenericBound::Trait(..) => last_line_extendable(s),
};

// Whether a GenericBound item is a PathSegment segment that includes internal array
// that contains more than one item
let is_item_with_multi_items_array = |item: &ast::GenericBound| match item {
ast::GenericBound::Trait(ref poly_trait_ref, ..) => {
let segments = &poly_trait_ref.trait_ref.path.segments;
if segments.len() > 1 {
true
} else {
if let Some(args_in) = &segments[0].args {
matches!(
args_in.deref(),
ast::GenericArgs::AngleBracketed(bracket_args)
if bracket_args.args.len() > 1
)
} else {
false
}
}
}
_ => false,
};

let result = items.iter().enumerate().try_fold(
(String::new(), None, false),
|(strs, prev_trailing_span, prev_extendable), (i, item)| {
Expand Down Expand Up @@ -1035,10 +1057,23 @@ fn join_bounds_inner(
},
)?;

if !force_newline
&& items.len() > 1
&& (result.0.contains('\n') || result.0.len() > shape.width)
{
// Whether retry the function with forced newline is needed:
// Only if result is not already multiline and did not exceed line width,
// and either there is more than one item;
// or the single item is of type `Trait`,
// and any of the internal arrays contains more than one item;
let retry_with_force_newline =
if force_newline || (!result.0.contains('\n') && result.0.len() <= shape.width) {
false
} else {
if items.len() > 1 {
true
} else {
is_item_with_multi_items_array(&items[0])
}
};

if retry_with_force_newline {
join_bounds_inner(context, shape, items, need_indent, true)
} else {
Some(result.0)
Expand Down
149 changes: 149 additions & 0 deletions tests/source/issue-4689/one.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// rustfmt-version: One

// Based on the issue description
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + fmt::Write
{
//
}
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + fmt::Write1 + fmt::Write2
{
//
}
pub trait PrettyPrinter<'tcx>:
fmt::Write + Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}
pub trait PrettyPrinter<'tcx>:
fmt::Write + Printer1<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + Printer2<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}

// Some test cases to ensure other cases formatting were not changed
fn f() -> Box<
FnMut() -> Thing<
WithType = LongItemName,
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
>,
> {
}
fn f() -> Box<
FnMut() -> Thing<
WithType = LongItemName,
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
> + fmt::Write1
+ fmt::Write2,
> {
}

fn foo<F>(foo2: F)
where
F: Fn(
// this comment is deleted
)
{
}
fn foo<F>(foo2: F)
where
F: Fn(
// this comment is deleted
) + fmt::Write
{
}

fn elaborate_bounds<F>(mut mk_cand: F)
where
F: for<> FnMut(
&mut ProbeContext<>,
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
),
{
}
fn elaborate_bounds<F>(mut mk_cand: F)
where
F: for<> FnMut(
&mut ProbeContext<>,
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
) + fmt::Write,
{
}

fn build_sorted_static_get_entry_names(
mut entries: entryyyyyyyy,
) -> (
impl Fn(
AlphabeticalTraversal,
Seconddddddddddddddddddddddddddddddddddd
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+ Sendddddddddddddddddddddddddddddddddddddddddddd
) {
}

pub trait SomeTrait:
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
{
}

trait B = where
for<'b> &'b Self: Send
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
149 changes: 149 additions & 0 deletions tests/source/issue-4689/two.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// rustfmt-version: Two

// Based on the issue description
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + fmt::Write
{
//
}
pub trait PrettyPrinter<'tcx>:
Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + fmt::Write1 + fmt::Write2
{
//
}
pub trait PrettyPrinter<'tcx>:
fmt::Write + Printer<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}
pub trait PrettyPrinter<'tcx>:
fmt::Write + Printer1<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
> + Printer2<
'tcx,
Error = fmt::Error,
Path = Self,
Region = Self,
Type = Self,
DynExistential = Self,
Const = Self,
>
{
//
}

// Some test cases to ensure other cases formatting were not changed
fn f() -> Box<
FnMut() -> Thing<
WithType = LongItemName,
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
>,
> {
}
fn f() -> Box<
FnMut() -> Thing<
WithType = LongItemName,
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
> + fmt::Write1
+ fmt::Write2,
> {
}

fn foo<F>(foo2: F)
where
F: Fn(
// this comment is deleted
)
{
}
fn foo<F>(foo2: F)
where
F: Fn(
// this comment is deleted
) + fmt::Write
{
}

fn elaborate_bounds<F>(mut mk_cand: F)
where
F: for<> FnMut(
&mut ProbeContext<>,
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
),
{
}
fn elaborate_bounds<F>(mut mk_cand: F)
where
F: for<> FnMut(
&mut ProbeContext<>,
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
) + fmt::Write,
{
}

fn build_sorted_static_get_entry_names(
mut entries: entryyyyyyyy,
) -> (
impl Fn(
AlphabeticalTraversal,
Seconddddddddddddddddddddddddddddddddddd
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+ Sendddddddddddddddddddddddddddddddddddddddddddd
) {
}

pub trait SomeTrait:
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
{
}

trait B = where
for<'b> &'b Self: Send
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
Loading