Skip to content

Commit 98d3012

Browse files
committed
Use version-sorting for all sorting
Add a description of a version-sorting algorithm. (This algorithm does not precisely match `strverscmp`; it's intentionally simpler in its handling of leading zeroes, and produces a result easier for humans to easily understand and do by hand.) Change all references to sorting to use version-sorting. Change all references to "ASCIIbetically" to instead say "sort non-lowercase before lowercase".
1 parent c60ff10 commit 98d3012

File tree

4 files changed

+56
-11
lines changed

4 files changed

+56
-11
lines changed

src/doc/style-guide/src/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,42 @@ fn bar() {}
9999
fn baz() {}
100100
```
101101

102+
### Sorting
103+
104+
In various cases, the default Rust style specifies to sort things. If not
105+
otherwise specified, such sorting should be "version sorting", which ensures
106+
that (for instance) `x8` comes before `x16` even though the character `1` comes
107+
before the character `8`. (If not otherwise specified, version-sorting is
108+
lexicographical.)
109+
110+
For the purposes of the Rust style, to compare two strings for version-sorting:
111+
112+
- Compare the strings by (Unicode) character as normal, finding the index of
113+
the first differing character. (If the two strings do not have the same
114+
length, this may be the end of the shorter string.)
115+
- For both strings, determine the sequence of ASCII digits containing either
116+
that character or the character before. (If either string doesn't have such a
117+
sequence of ASCII digits, fall back to comparing the strings as normal.)
118+
- Compare the numeric values of the number specified by the sequence of digits.
119+
(Note that an implementation of this algorithm can easily check this without
120+
accumulating copies of the digits or converting to a number: longer sequences
121+
of digits are larger numbers, equal-length sequences can be sorted
122+
lexicographically.)
123+
- If the numbers have the same numeric value, the one with more leading zeroes
124+
comes first.
125+
126+
Note that there exist various algorithms called "version sorting", which differ
127+
most commonly in their handling of numbers with leading zeroes. This algorithm
128+
does not purport to precisely match the behavior of any particular other
129+
algorithm, only to produce a simple and satisfying result for Rust formatting.
130+
(In particular, this algorithm aims to produce a satisfying result for a set of
131+
symbols that have the same number of leading zeroes, and an acceptable and
132+
easily understandable result for a set of symbols that has varying numbers of
133+
leading zeroes.)
134+
135+
As an example, version-sorting will sort the following symbols in the order
136+
given: `x000`, `x00`, `x0`, `x01`, `x1`, `x09`, `x9`, `x010`, `x10`.
137+
102138
### [Module-level items](items.md)
103139

104140
### [Statements](statements.md)

src/doc/style-guide/src/cargo.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Put a blank line between the last key-value pair in a section and the header of
88
the next section. Do not place a blank line between section headers and the
99
key-value pairs in that section, or between key-value pairs in a section.
1010

11-
Sort key names alphabetically within each section, with the exception of the
11+
Version-sort key names within each section, with the exception of the
1212
`[package]` section. Put the `[package]` section at the top of the file; put
1313
the `name` and `version` keys in that order at the top of that section,
14-
followed by the remaining keys other than `description` in alphabetical order,
15-
followed by the `description` at the end of that section.
14+
followed by the remaining keys other than `description` in order, followed by
15+
the `description` at the end of that section.
1616

1717
Don't use quotes around any standard key names; use bare keys. Only use quoted
1818
keys for non-standard keys whose names require them, and avoid introducing such

src/doc/style-guide/src/editions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ history of the style guide. Notable changes in the Rust 2024 style edition
3737
include:
3838

3939
- Miscellaneous `rustfmt` bugfixes.
40+
- Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
41+
- Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
4042

4143
## Rust 2015/2018/2021 style edition
4244

src/doc/style-guide/src/items.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ an item appears at module level or within another item.
99
alphabetically.
1010

1111
`use` statements, and module *declarations* (`mod foo;`, not `mod { ... }`)
12-
must come before other items. Put imports before module declarations. Sort each
13-
alphabetically, except that `self` and `super` must come before any other
12+
must come before other items. Put imports before module declarations.
13+
Version-sort each, except that `self` and `super` must come before any other
1414
names.
1515

1616
Don't automatically move module declarations annotated with `#[macro_use]`,
@@ -441,8 +441,10 @@ foo::{
441441
A *group* of imports is a set of imports on the same or sequential lines. One or
442442
more blank lines or other items (e.g., a function) separate groups of imports.
443443

444-
Within a group of imports, imports must be sorted ASCIIbetically (uppercase
445-
before lowercase). Groups of imports must not be merged or re-ordered.
444+
Within a group of imports, imports must be version-sorted, except that
445+
non-lowercase characters (characters that can start an `UpperCamelCase`
446+
identifier) must be sorted before lowercase characters. Groups of imports must
447+
not be merged or re-ordered.
446448

447449
E.g., input:
448450

@@ -469,10 +471,15 @@ re-ordering.
469471

470472
### Ordering list import
471473

472-
Names in a list import must be sorted ASCIIbetically, but with `self` and
473-
`super` first, and groups and glob imports last. This applies recursively. For
474-
example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g.,
475-
`use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`.
474+
Names in a list import must be version-sorted, except that:
475+
- `self` and `super` always come first if present,
476+
- non-lowercase characters (characters that can start an `UpperCamelCase`
477+
identifier) must be sorted before lowercase characters, and
478+
- groups and glob imports always come last if present.
479+
480+
This applies recursively. For example, `a::*` comes before `b::a` but `a::b`
481+
comes before `a::*`. E.g., `use foo::bar::{a, b::c, b::d, b::d::{x, y, z},
482+
b::{self, r, s}};`.
476483

477484
### Normalisation
478485

0 commit comments

Comments
 (0)