Skip to content

Inconsistent Imports Sorting Order #4648

Open
@davidBar-On

Description

@davidBar-On

Input

use ::Foo;
use ::foo;
use ::foo::bar;
use ::foo::Bar;
use Foo;
use ::*;

Output

Same as input.

Expected output

Either:

use ::foo;
use ::Foo;
use ::foo::bar;
use ::foo::Bar;
use ::*;
use Foo;

or:

use ::Foo;
use ::foo;
use ::foo::Bar;
use ::foo::bar;
use ::*;
use Foo;

This issue is based on problems found while developing PR #4591 that related to imports sorting order. The following are the two problems that were identified, but they were not fixed as their fix is not backward compatible with the current imports sorting order.

For the discussion, an import that starts with :: is referred to as it starts with the global prefix segment. The issues are:

  1. Inconsistency in lower and upper case letters sorting order: for simple segments following a global prefix segment, uppercase letters precede lowercase letters. However, in the following segments, lowercase letters precede uppercase letters. E.g., use ::Foo precede use ::foo but use ::foo::bar precede use ::foo::Bar.
    Note that according to the Style Guide, uppercase letters should precede lowercase letters, as this is the ascii-betically order.

  2. ::* is sorted last: it is expected that this import will be sorted as the last of the imports that start with the global prefix, but that it will precede other prefixes.

The root cause for these issues is that if the first segment is the global segment, for sorting purposes it is concatenated with the next segment. E.g. sorting of ::foo is not done by sorting first by the global prefix "::" and then sorting by "foo", but the first element that is sorted is "::foo".

The problem with this is that when the sorted element starts with a letter, Ord for UseSegment cmp() puts lowercase letters before uppercase. However, because the :: was added, compare_as_versions() is used, and that function sort uppercase letters before lowercase letters.

The right behavior, if backward compatibility is ignored, is probably that Ord for UseSegment cmp() will sort according to the ascii-betically order, i.e. uppercase letters before lowercase letters. In addition, the global prefix segment :: should be sorted on is own and not be combined with the following segment.

Meta

  • rustfmt version: 2.0.0-rc.2-nightly (2d52e71 2021-01-05)
  • From where did you install rustfmt?: self build

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions