Rollup merge of #115046 - joshtriplett:master, r=compiler-errors

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".
This commit is contained in:
Matthias Krüger 2024-01-11 03:02:39 +01:00 committed by GitHub
commit 3cc4e02519
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 11 deletions

View File

@ -112,6 +112,90 @@ fn bar() {}
fn baz() {} fn baz() {}
``` ```
### Sorting
In various cases, the default Rust style specifies to sort things. If not
otherwise specified, such sorting should be "version sorting", which ensures
that (for instance) `x8` comes before `x16` even though the character `1` comes
before the character `8`. (If not otherwise specified, version-sorting is
lexicographical.)
For the purposes of the Rust style, to compare two strings for version-sorting:
- Process both strings from beginning to end as two sequences of maximal-length
chunks, where each chunk consists either of a sequence of characters other
than ASCII digits, or a sequence of ASCII digits (a numeric chunk), and
compare corresponding chunks from the strings.
- To compare two numeric chunks, compare them by numeric value, ignoring
leading zeroes. If the two chunks have equal numeric value, but different
numbers of leading digits, and this is the first time this has happened for
these strings, treat the chunks as equal (moving on to the next chunk) but
remember which string had more leading zeroes.
- To compare two chunks if both are not numeric, compare them by Unicode
character lexicographically, except that `_` (underscore) sorts immediately
after ` ` (space) but before any other character. (This treats underscore as
a word separator, as commonly used in identifiers.)
- If the use of version sorting specifies further modifiers, such as sorting
non-lowercase before lowercase, apply those modifiers to the lexicographic
sort in this step.
- If the comparison reaches the end of the string and considers each pair of
chunks equal:
- If one of the numeric comparisons noted the earliest point at which one
string had more leading zeroes than the other, sort the string with more
leading zeroes first.
- Otherwise, the strings are equal.
Note that there exist various algorithms called "version sorting", which
generally try to solve the same problem, but which differ in various ways (such
as in their handling of numbers with leading zeroes). This algorithm
does not purport to precisely match the behavior of any particular other
algorithm, only to produce a simple and satisfying result for Rust formatting.
In particular, this algorithm aims to produce a satisfying result for a set of
symbols that have the same number of leading zeroes, and an acceptable and
easily understandable result for a set of symbols that has varying numbers of
leading zeroes.
As an example, version-sorting will sort the following strings in the order
given:
- `_ZYWX`
- `u_zzz`
- `u8`
- `u16`
- `u32`
- `u64`
- `u128`
- `u256`
- `ua`
- `usize`
- `uz`
- `v000`
- `v00`
- `v0`
- `v0s`
- `v00t`
- `v0u`
- `v001`
- `v01`
- `v1`
- `v009`
- `v09`
- `v9`
- `v010`
- `v10`
- `w005s09t`
- `w5s009t`
- `x64`
- `x86`
- `x86_32`
- `x86_64`
- `x86_128`
- `x87`
- `Z_YWX`
- `ZY_WX`
- `ZYW_X`
- `ZYWX`
- `ZYWX_`
### [Module-level items](items.md) ### [Module-level items](items.md)
### [Statements](statements.md) ### [Statements](statements.md)

View File

@ -8,11 +8,11 @@ Put a blank line between the last key-value pair in a section and the header of
the next section. Do not place a blank line between section headers and the the next section. Do not place a blank line between section headers and the
key-value pairs in that section, or between key-value pairs in a section. key-value pairs in that section, or between key-value pairs in a section.
Sort key names alphabetically within each section, with the exception of the Version-sort key names within each section, with the exception of the
`[package]` section. Put the `[package]` section at the top of the file; put `[package]` section. Put the `[package]` section at the top of the file; put
the `name` and `version` keys in that order at the top of that section, the `name` and `version` keys in that order at the top of that section,
followed by the remaining keys other than `description` in alphabetical order, followed by the remaining keys other than `description` in order, followed by
followed by the `description` at the end of that section. the `description` at the end of that section.
Don't use quotes around any standard key names; use bare keys. Only use quoted Don't use quotes around any standard key names; use bare keys. Only use quoted
keys for non-standard keys whose names require them, and avoid introducing such keys for non-standard keys whose names require them, and avoid introducing such

View File

@ -37,6 +37,8 @@ history of the style guide. Notable changes in the Rust 2024 style edition
include: include:
- Miscellaneous `rustfmt` bugfixes. - Miscellaneous `rustfmt` bugfixes.
- Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
- Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
## Rust 2015/2018/2021 style edition ## Rust 2015/2018/2021 style edition

View File

@ -9,8 +9,8 @@ an item appears at module level or within another item.
alphabetically. alphabetically.
`use` statements, and module *declarations* (`mod foo;`, not `mod { ... }`) `use` statements, and module *declarations* (`mod foo;`, not `mod { ... }`)
must come before other items. Put imports before module declarations. Sort each must come before other items. Put imports before module declarations.
alphabetically, except that `self` and `super` must come before any other Version-sort each, except that `self` and `super` must come before any other
names. names.
Don't automatically move module declarations annotated with `#[macro_use]`, Don't automatically move module declarations annotated with `#[macro_use]`,
@ -467,8 +467,10 @@ foo::{
A *group* of imports is a set of imports on the same or sequential lines. One or A *group* of imports is a set of imports on the same or sequential lines. One or
more blank lines or other items (e.g., a function) separate groups of imports. more blank lines or other items (e.g., a function) separate groups of imports.
Within a group of imports, imports must be sorted ASCIIbetically (uppercase Within a group of imports, imports must be version-sorted, except that
before lowercase). Groups of imports must not be merged or re-ordered. non-lowercase characters (characters that can start an `UpperCamelCase`
identifier) must be sorted before lowercase characters. Groups of imports must
not be merged or re-ordered.
E.g., input: E.g., input:
@ -495,10 +497,15 @@ re-ordering.
### Ordering list import ### Ordering list import
Names in a list import must be sorted ASCIIbetically, but with `self` and Names in a list import must be version-sorted, except that:
`super` first, and groups and glob imports last. This applies recursively. For - `self` and `super` always come first if present,
example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g., - non-lowercase characters (characters that can start an `UpperCamelCase`
`use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`. identifier) must be sorted before lowercase characters, and
- groups and glob imports always come last if present.
This applies recursively. For example, `a::*` comes before `b::a` but `a::b`
comes before `a::*`. E.g., `use foo::bar::{a, b::c, b::d, b::d::{x, y, z},
b::{self, r, s}};`.
### Normalisation ### Normalisation