Skip to content

Line width computation in the linter and formatter #12133

@dhruvmanila

Description

@dhruvmanila

Related to #12130, it turns out that computing the line width on a char-by-char basis and as a whole str is different. From the docs of unicode-width, it's these cases where it differs specifically.

In the linter, the LineWidthBuilder determines the width by looking at each char individually. But, in some places the width is computed directly on &str which creates the panic as in #12130. These cases are:

if width.get() - last_chunk.width() <= limit.value() as usize {

.then_some(name.map(str::width).unwrap_or_default() + level as usize);

let maybe_length = settings.length_sort.then_some(name.width());

/// Returns `true` if the source code should be truncated when included in a user-facing
/// diagnostic.
fn should_truncate(source_code: &str) -> bool {
source_code.width() > 50 || source_code.contains(['\r', '\n'])
}

In the formatter,

// SAFETY: A u32 is sufficient to represent the width of a file <= 4GB
char.width().unwrap_or(0) as u32

// SAFETY: A u32 is sufficient to format files <= 4GB
#[allow(clippy::cast_possible_truncation)]
c => c.width().unwrap_or(0) as u32,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions