Skip to content

Incorrect indentation on multi-line single generic bound #4689

Closed
@calebcartwright

Description

@calebcartwright

We have a bug in the generic bounds formatting code that does not properly account for the case where there's a single bound that itself has to be formatted across multiple lines.

Input

pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    >
    {
         //
    }

Output

pub trait PrettyPrinter<'tcx>:
    Printer<
    'tcx,
    Error = fmt::Error,
    Path = Self,
    Region = Self,
    Type = Self,
    DynExistential = Self,
    Const = Self,
>
{
    //
}

Expected output
The same indentation as if there were 2+ bounds

pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    >
{
    //
}

// what it would look like with an extra bound:
pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    > + fmt::Write
{
    //
}

Meta

  • rustfmt version: all (latest 1.x version as of 1.4.36 and 2.0-rc on master branch
  • From where did you install rustfmt?: any

The problematic code can be found here:

if !force_newline
&& items.len() > 1
&& (result.0.contains('\n') || result.0.len() > shape.width)
{
join_bounds_inner(context, shape, items, need_indent, true)
} else {
Some(result.0)
}

The issue is an incorrect assumption that if there's just one bound, or multiple bounds but which were able to be formatted on a single line without exceeding the max width limit, then we'll be formatting the bound(s) on a single line and there's no need to reformat the bounds with the proper indentation. However, as noted above this fails to catch the multi-lined single bound case so this check will need to be updated to also account for that case.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions