Skip to content

Commit

Permalink
Unrolled build for rust-lang#115046
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#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".
  • Loading branch information
rust-timer committed Jan 11, 2024
2 parents 0a89233 + 2e931b5 commit a33adf5
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 11 deletions.
84 changes: 84 additions & 0 deletions src/doc/style-guide/src/README.md
Expand Up @@ -112,6 +112,90 @@ fn bar() {}
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)

### [Statements](statements.md)
Expand Down
6 changes: 3 additions & 3 deletions src/doc/style-guide/src/cargo.md
Expand Up @@ -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
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
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 `description` at the end of that section.
followed by the remaining keys other than `description` in order, followed by
the `description` at the end of that section.

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
Expand Down
2 changes: 2 additions & 0 deletions src/doc/style-guide/src/editions.md
Expand Up @@ -37,6 +37,8 @@ history of the style guide. Notable changes in the Rust 2024 style edition
include:

- 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

Expand Down
23 changes: 15 additions & 8 deletions src/doc/style-guide/src/items.md
Expand Up @@ -9,8 +9,8 @@ an item appears at module level or within another item.
alphabetically.

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

Don't automatically move module declarations annotated with `#[macro_use]`,
Expand Down Expand Up @@ -467,8 +467,10 @@ foo::{
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.

Within a group of imports, imports must be sorted ASCIIbetically (uppercase
before lowercase). Groups of imports must not be merged or re-ordered.
Within a group of imports, imports must be version-sorted, except that
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:

Expand All @@ -495,10 +497,15 @@ re-ordering.

### Ordering list import

Names in a list import must be sorted ASCIIbetically, but with `self` and
`super` first, and groups and glob imports last. 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}};`.
Names in a list import must be version-sorted, except that:
- `self` and `super` always come first if present,
- non-lowercase characters (characters that can start an `UpperCamelCase`
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

Expand Down

0 comments on commit a33adf5

Please sign in to comment.