diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 9409057d4847e..60b343afbed9c 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -49,12 +49,11 @@ impl SortedMap { } #[inline] - pub fn insert(&mut self, key: K, mut value: V) -> Option { + pub fn insert(&mut self, key: K, value: V) -> Option { match self.lookup_index_for(&key) { Ok(index) => { let slot = unsafe { self.data.get_unchecked_mut(index) }; - mem::swap(&mut slot.1, &mut value); - Some(value) + Some(mem::replace(&mut slot.1, value)) } Err(index) => { self.data.insert(index, (key, value)); diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index e1e3bcc05e74b..d313e8e012f20 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -727,7 +727,7 @@ where } /// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking -fn into_range_unchecked( +pub(crate) fn into_range_unchecked( len: usize, (start, end): (ops::Bound, ops::Bound), ) -> ops::Range { @@ -747,7 +747,7 @@ fn into_range_unchecked( /// Convert pair of `ops::Bound`s into `ops::Range`. /// Returns `None` on overflowing indices. -fn into_range( +pub(crate) fn into_range( len: usize, (start, end): (ops::Bound, ops::Bound), ) -> Option> { @@ -772,7 +772,7 @@ fn into_range( /// Convert pair of `ops::Bound`s into `ops::Range`. /// Panics on overflowing indices. -fn into_slice_range( +pub(crate) fn into_slice_range( len: usize, (start, end): (ops::Bound, ops::Bound), ) -> ops::Range { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 4f13ea9790d87..d95662afddd46 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -38,7 +38,7 @@ pub mod sort; mod ascii; mod cmp; -mod index; +pub(crate) mod index; mod iter; mod raw; mod rotate; diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 1d52335f28ebf..49f9f6d4ad1e3 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -252,6 +252,58 @@ unsafe impl SliceIndex for ops::Range { } } +/// Implements substring slicing for arbitrary bounds. +/// +/// Returns a slice of the given string bounded by the byte indices +/// provided by each bound. +/// +/// This operation is *O*(1). +/// +/// # Panics +/// +/// Panics if `begin` or `end` (if it exists and once adjusted for +/// inclusion/exclusion) does not point to the starting byte offset of +/// a character (as defined by `is_char_boundary`), if `begin > end`, or if +/// `end > len`. +#[stable(feature = "slice_index_str_with_ops_bound_pair", since = "CURRENT_RUSTC_VERSION")] +unsafe impl SliceIndex for (ops::Bound, ops::Bound) { + type Output = str; + + #[inline] + fn get(self, slice: &str) -> Option<&str> { + crate::slice::index::into_range(slice.len(), self)?.get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut str> { + crate::slice::index::into_range(slice.len(), self)?.get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const str { + let len = (slice as *const [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str { + let len = (slice as *mut [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &str) -> &str { + crate::slice::index::into_slice_range(slice.len(), self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut str) -> &mut str { + crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice) + } +} + /// Implements substring slicing with syntax `&self[.. end]` or `&mut /// self[.. end]`. /// diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 81b88d5de98b2..d8718d26848ca 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -24,6 +24,7 @@ use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo, Kind}; use build_helper::ci::CiEnv; +use build_helper::git::get_git_merge_base; #[derive(Clone)] pub struct LlvmResult { @@ -128,13 +129,19 @@ pub fn prebuilt_llvm_config( /// This retrieves the LLVM sha we *want* to use, according to git history. pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String { let llvm_sha = if is_git { + // We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we + // walk back further to the last bors merge commit that actually changed LLVM. The first + // step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD` + // in that case. + let closest_upstream = + get_git_merge_base(Some(&config.src)).unwrap_or_else(|_| "HEAD".into()); let mut rev_list = config.git(); rev_list.args(&[ PathBuf::from("rev-list"), format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(), "-n1".into(), "--first-parent".into(), - "HEAD".into(), + closest_upstream.into(), "--".into(), config.src.join("src/llvm-project"), config.src.join("src/bootstrap/download-ci-llvm-stamp"), diff --git a/src/doc/reference b/src/doc/reference index 1ea0178266b3f..9cd5c5a6ccbd4 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 1ea0178266b3f3f613b0fabdaf16a83961c99cdb +Subproject commit 9cd5c5a6ccbd4c07c65ab5c69a53286280308c95 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 8a87926a985ce..07e0df2f006e5 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 8a87926a985ce32ca1fad1be4008ee161a0b91eb +Subproject commit 07e0df2f006e59d171c6bf3cafa9d61dbeb520d8 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index b5a12d95e32ae..24eebb6df96d0 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit b5a12d95e32ae53791cc6ab44417774667ed2ac6 +Subproject commit 24eebb6df96d037aad285e4f7793bd0393a66878 diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 22ff51489af02..4448dac00a09b 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -101,7 +101,7 @@ target | notes `x86_64-unknown-freebsd` | 64-bit FreeBSD `x86_64-unknown-illumos` | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with MUSL -`x86_64-unknown-netbsd` | NetBSD/amd64 +[`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 ## Tier 2 @@ -128,7 +128,7 @@ target | std | notes `aarch64-apple-ios` | ✓ | ARM64 iOS [`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | Apple iOS Simulator on ARM64 `aarch64-fuchsia` | ✓ | Alias for `aarch64-unknown-fuchsia` -`aarch64-unknown-fuchsia` | ✓ | ARM64 Fuchsia +[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat @@ -159,7 +159,7 @@ target | std | notes `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL `mipsel-unknown-linux-musl` | ✓ | MIPS (LE) Linux with MUSL -`nvptx64-nvidia-cuda` | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] +[`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] `riscv32i-unknown-none-elf` | * | Bare RISC-V (RV32I ISA) `riscv32imac-unknown-none-elf` | * | Bare RISC-V (RV32IMAC ISA) `riscv32imc-unknown-none-elf` | * | Bare RISC-V (RV32IMC ISA) @@ -183,7 +183,7 @@ target | std | notes `x86_64-apple-ios` | ✓ | 64-bit x86 iOS [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX `x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia` -`x86_64-unknown-fuchsia` | ✓ | 64-bit Fuchsia +[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android `x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) @@ -337,6 +337,6 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | -`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) +[`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index 6bdb3ae26ace8..f4d759673700d 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -36,10 +36,10 @@ options. ### Indentation and line width -* Use spaces, not tabs. -* Each level of indentation must be 4 spaces (that is, all indentation +- Use spaces, not tabs. +- Each level of indentation must be 4 spaces (that is, all indentation outside of string literals and comments must be a multiple of 4). -* The maximum width for a line is 100 characters. +- The maximum width for a line is 100 characters. #### Block indent @@ -100,10 +100,12 @@ fn baz() {} ``` ### [Module-level items](items.md) + ### [Statements](statements.md) + ### [Expressions](expressions.md) -### [Types](types.md) +### [Types](types.md) ### Comments diff --git a/src/doc/style-guide/src/SUMMARY.md b/src/doc/style-guide/src/SUMMARY.md index 606485bfb6c7e..64540c3997cda 100644 --- a/src/doc/style-guide/src/SUMMARY.md +++ b/src/doc/style-guide/src/SUMMARY.md @@ -9,4 +9,5 @@ - [Other style advice](advice.md) - [`Cargo.toml` conventions](cargo.md) - [Guiding principles and rationale](principles.md) +- [Rust style editions](editions.md) - [Nightly-only syntax](nightly.md) diff --git a/src/doc/style-guide/src/advice.md b/src/doc/style-guide/src/advice.md index 9a617be509c38..65cf8cb6e909c 100644 --- a/src/doc/style-guide/src/advice.md +++ b/src/doc/style-guide/src/advice.md @@ -18,16 +18,16 @@ if y { ## Names - * Types shall be `UpperCamelCase`, - * Enum variants shall be `UpperCamelCase`, - * Struct fields shall be `snake_case`, - * Function and method names shall be `snake_case`, - * Local variables shall be `snake_case`, - * Macro names shall be `snake_case`, - * Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`. - * When a name is forbidden because it is a reserved word (such as `crate`), - either use a raw identifier (`r#crate`) or use a trailing underscore - (`crate_`). Don't misspell the word (`krate`). +- Types shall be `UpperCamelCase`, +- Enum variants shall be `UpperCamelCase`, +- Struct fields shall be `snake_case`, +- Function and method names shall be `snake_case`, +- Local variables shall be `snake_case`, +- Macro names shall be `snake_case`, +- Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`. +- When a name is forbidden because it is a reserved word (such as `crate`), + either use a raw identifier (`r#crate`) or use a trailing underscore + (`crate_`). Don't misspell the word (`krate`). ### Modules diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md new file mode 100644 index 0000000000000..5c67a185b8ffa --- /dev/null +++ b/src/doc/style-guide/src/editions.md @@ -0,0 +1,46 @@ +# Rust style editions + +The default Rust style evolves over time, as Rust does. However, to avoid +breaking established code style, and CI jobs checking code style, changes to +the default Rust style only appear in *style editions*. + +Code written in a given +[Rust edition](https://doc.rust-lang.org/edition-guide/) +uses the corresponding Rust style edition by default. To make it easier to +migrate code style separately from the semantic changes between Rust editions, +formatting tools such as `rustfmt` allow updating the style edition separately +from the Rust edition. + +The current version of the style guide describes the latest Rust style edition. +Each distinct past style will have a corresponding archived version of the +style guide. + +Note that archived versions of the style guide do not document formatting for +newer Rust constructs that did not exist at the time that version of the style +guide was archived. However, each style edition will still format all +constructs valid in that Rust edition, with the style of newer constructs +coming from the first subsequent style edition providing formatting rules for +that construct (without any of the systematic/global changes from that style +edition). + +Not all Rust editions have corresponding changes to the Rust style. For +instance, Rust 2015, Rust 2018, and Rust 2021 all use the same style edition. + +## Rust 2024 style edition + +This style guide describes the Rust 2024 style edition. The Rust 2024 style +edition is currently nightly-only and may change before the release of Rust +2024. + +For a full history of changes in the Rust 2024 style edition, see the git +history of the style guide. Notable changes in the Rust 2024 style edition +include: + +- Miscellaneous `rustfmt` bugfixes. + +## Rust 2015/2018/2021 style edition + +The archived version of the style guide at + +describes the style edition corresponding to Rust 2015, Rust 2018, and Rust +2021. diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index f0c2a189f12e7..32c604f9f3e10 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -1,6 +1,6 @@ -## Expressions +# Expressions -### Blocks +## Blocks A block expression must have a newline after the initial `{` and before the terminal `}`, unless it qualifies to be written as a single line based on @@ -63,10 +63,10 @@ Write an empty block as `{}`. Write a block on a single line if: -* it is either used in expression position (not statement position) or is an +- it is either used in expression position (not statement position) or is an unsafe block in statement position, -* it contains a single-line expression and no statements, and -* it contains no comments +- it contains a single-line expression and no statements, and +- it contains no comments For a single-line block, put spaces after the opening brace and before the closing brace. @@ -116,8 +116,7 @@ fn main() { } ``` - -### Closures +## Closures Don't put any extra spaces before the first `|` (unless the closure is prefixed by a keyword such as `move`); put a space between the second `|` and the @@ -155,8 +154,7 @@ move |arg1: i32, arg2: i32| -> i32 { } ``` - -### Struct literals +## Struct literals If a struct literal is *small*, format it on a single line, and do not use a trailing comma. If not, split it across multiple lines, with each field on its @@ -185,8 +183,7 @@ let f = Foo { }; ``` - -### Tuple literals +## Tuple literals Use a single-line form where possible. Do not put spaces between the opening parenthesis and the first element, or between the last element and the closing @@ -205,8 +202,7 @@ let x = ( ); ``` - -### Tuple struct literals +## Tuple struct literals Do not put space between the identifier and the opening parenthesis. Otherwise, follow the rules for tuple literals: @@ -220,8 +216,7 @@ let x = Foo( ); ``` - -### Enum literals +## Enum literals Follow the formatting rules for the various struct literals. Prefer using the name of the enum as a qualifying name, unless the enum is in the prelude: @@ -235,8 +230,7 @@ Foo::Baz { Ok(an_expr) ``` - -### Array literals +## Array literals Write small array literals on a single line. Do not put spaces between the opening square bracket and the first element, or between the last element and the closing @@ -276,8 +270,7 @@ fn main() { } ``` - -### Array accesses, indexing, and slicing. +## Array accesses, indexing, and slicing Don't put spaces around the square brackets. Avoid breaking lines if possible. Never break a line between the target expression and the opening square @@ -300,13 +293,13 @@ fn main() { } ``` -### Unary operations +## Unary operations Do not include a space between a unary op and its operand (i.e., `!x`, not `! x`). However, there must be a space after `&mut`. Avoid line-breaking between a unary operator and its operand. -### Binary operations +## Binary operations Do include spaces around binary ops (i.e., `x + 1`, not `x+1`) (including `=` and other assignment operators such as `+=` or `*=`). @@ -335,7 +328,7 @@ foo_bar Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather than at other binary operators. -### Control flow +## Control flow Do not include extraneous parentheses for `if` and `while` expressions. @@ -354,7 +347,7 @@ if (true) { Do include extraneous parentheses if it makes an arithmetic or logic expression easier to understand (`(x * 15) + (y * 20)` is fine) -### Function calls +## Function calls Do not put a space between the function name, and the opening parenthesis. @@ -364,7 +357,7 @@ Do put a space between an argument, and the comma which precedes it. Prefer not to break a line in the callee expression. -#### Single-line calls +### Single-line calls Do not put a space between the function name and open paren, between the open paren and the first argument, or between the last argument and the close paren. @@ -375,7 +368,7 @@ Do not put a comma after the last argument. foo(x, y, z) ``` -#### Multi-line calls +### Multi-line calls If the function call is not *small*, it would otherwise over-run the max width, or any argument or the callee is multi-line, then format the call across @@ -390,8 +383,7 @@ a_function_call( ) ``` - -### Method calls +## Method calls Follow the function rules for calling. @@ -401,15 +393,14 @@ Do not put any spaces around the `.`. x.foo().bar().baz(x, y, z); ``` - -### Macro uses +## Macro uses If a macro can be parsed like other constructs, format it like those constructs. For example, a macro use `foo!(a, b, c)` can be parsed like a function call (ignoring the `!`), so format it using the rules for function calls. -#### Special case macros +### Special case macros For macros which take a format string, if all other arguments are *small*, format the arguments before the format string on a single line if they fit, and @@ -430,8 +421,7 @@ assert_eq!( ); ``` - -### Casts (`as`) +## Casts (`as`) Put spaces before and after `as`: @@ -439,8 +429,7 @@ Put spaces before and after `as`: let cstr = "Hi\0" as *const str as *const [u8] as *const std::os::raw::c_char; ``` - -### Chains of fields and method calls +## Chains of fields and method calls A chain is a sequence of field accesses, method calls, and/or uses of the try operator `?`. E.g., `a.b.c().d` or `foo?.bar().baz?`. @@ -478,7 +467,7 @@ foo( .qux(); ``` -#### Multi-line elements +### Multi-line elements If any element in a chain is formatted across multiple lines, put that element and any later elements on their own lines. @@ -513,7 +502,7 @@ self.pre_comment.as_ref().map_or( ) ``` -### Control flow expressions +## Control flow expressions This section covers `if`, `if let`, `loop`, `while`, `while let`, and `for` expressions. @@ -584,8 +573,7 @@ if !self.config.file_lines().intersects( } ``` - -#### Single line `if else` +### Single line `if else` Put an `if else` or `if let else` on a single line if it occurs in expression context (i.e., is not a standalone statement), it contains a single `else` @@ -608,8 +596,7 @@ if x { } ``` - -### Match +## Match Prefer not to line-break inside the discriminant expression. Always break after the opening brace and before the closing brace. Block-indent the match arms @@ -718,7 +705,7 @@ match foo { } ``` -#### Line-breaking +### Line-breaking If using a block form on the right-hand side of a match arm makes it possible to avoid breaking on the left-hand side, do that: @@ -812,8 +799,7 @@ small_no_tuple: E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not. - -### Combinable expressions +## Combinable expressions Where a function call has a single argument, and that argument is formatted across multiple-lines, format the outer call as if it were a single-line call, @@ -861,8 +847,7 @@ foo(first_arg, x, |param| { }) ``` - -### Ranges +## Ranges Do not put spaces in ranges, e.g., `0..10`, `x..=y`, `..x.len()`, `foo..`. @@ -879,8 +864,7 @@ For the sake of indicating precedence, if either bound is a compound expression, use parentheses around it, e.g., `..(x + 1)`, `(x.f)..(x.f.len())`, or `0..(x - 10)`. - -### Hexadecimal literals +## Hexadecimal literals Hexadecimal literals may use upper- or lower-case letters, but they must not be mixed within the same literal. Projects should use the same case for all diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 6e5ea335e6ab2..a6d941f6d0454 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -1,4 +1,4 @@ -## Items +# Items Items consist of the set of things permitted at the top level of a module. However, Rust also allows some items to appear within some other types of @@ -16,7 +16,7 @@ names. Don't automatically move module declarations annotated with `#[macro_use]`, since that might change semantics. -### Function definitions +## Function definitions In Rust, people often find functions by searching for `fn [function-name]`, so the formatting of function definitions must enable this. @@ -46,14 +46,13 @@ fn foo( Note the trailing comma on the last argument. - -### Tuples and tuple structs +## Tuples and tuple structs Write the type list as you would a parameter list to a function. Build a tuple or tuple struct as you would call a function. -#### Single-line +### Single-line ```rust struct Bar(Type1, Type2); @@ -62,7 +61,7 @@ let x = Bar(11, 22); let y = (11, 22, 33); ``` -### Enums +## Enums In the declaration, put each variant on its own line, block indented. @@ -96,8 +95,7 @@ multiple lines, use the multi-line formatting for all struct variants. However, such a situation might be an indication that you should factor out the fields of the variant into their own struct. - -### Structs and Unions +## Structs and Unions Struct names follow on the same line as the `struct` keyword, with the opening brace on the same line when it fits within the right margin. All struct fields @@ -138,8 +136,7 @@ union Foo { } ``` - -### Tuple structs +## Tuple structs Put the whole struct on one line if possible. Separate types within the parentheses using a comma and space. Don't use a trailing comma for a @@ -165,8 +162,7 @@ pub struct Foo( ); ``` - -### Traits +## Traits Use block-indent for trait items. If there are no items, format the trait (including its `{}`) on a single line. Otherwise, break after the opening brace and before @@ -204,8 +200,7 @@ pub trait IndexRanges: } ``` - -### Impls +## Impls Use block-indent for impl items. If there are no items, format the impl (including its `{}`) on a single line. Otherwise, break after the opening brace @@ -231,15 +226,13 @@ impl Bar } ``` - -### Extern crate +## Extern crate `extern crate foo;` Use spaces around keywords, no spaces around the semicolon. - -### Modules +## Modules ```rust mod foo { @@ -253,7 +246,7 @@ mod foo; Use spaces around keywords and before the opening brace, no spaces around the semicolon. -### macro\_rules! +## `macro_rules!` Use `{}` for the full definition of the macro. @@ -262,8 +255,7 @@ macro_rules! foo { } ``` - -### Generics +## Generics Prefer to put a generics clause on one line. Break other parts of an item declaration rather than line-breaking a generics clause. If a generics clause is @@ -299,8 +291,7 @@ If an associated type is bound in a generic type, put spaces around the `=`: Prefer to use single-letter names for generic parameters. - -### `where` clauses +## `where` clauses These rules apply for `where` clauses on any item. @@ -373,7 +364,7 @@ where + Index, ``` -### Type aliases +## Type aliases Keep type aliases on one line when they fit. If necessary to break the line, do so after the `=`, and block-indent the right-hand side: @@ -398,8 +389,7 @@ where = AnEvenLongerType>; ``` - -### Associated types +## Associated types Format associated types like type aliases. Where an associated type has a bound, put a space after the colon but not before: @@ -408,15 +398,13 @@ bound, put a space after the colon but not before: pub type Foo: Bar; ``` - -### extern items +## extern items When writing extern items (such as `extern "C" fn`), always specify the ABI. For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or `extern "C" { ... }`. - -### Imports (`use` statements) +## Imports (`use` statements) Format imports on one line where possible. Don't put spaces around braces. @@ -426,8 +414,7 @@ use a::b::d::*; use a::b::{foo, bar, baz}; ``` - -#### Large list imports +### Large list imports Prefer to use multiple imports rather than a multi-line import. However, tools should not split imports by default. @@ -437,7 +424,6 @@ does not fit within the max width, or because of the rules for nested imports below), then break after the opening brace and before the closing brace, use a trailing comma, and block indent the names. - ```rust // Prefer foo::{long, list, of, imports}; @@ -450,8 +436,7 @@ foo::{ }; ``` - -#### Ordering of imports +### Ordering of imports 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. @@ -459,7 +444,6 @@ 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. - E.g., input: ```rust @@ -483,27 +467,25 @@ use b; Because of `macro_use`, attributes must also start a new group and prevent re-ordering. -#### Ordering list import +### 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}};`. - -#### Normalisation +### Normalisation Tools must make the following normalisations, recursively: -* `use a::self;` -> `use a;` -* `use a::{};` -> (nothing) -* `use a::{b};` -> `use a::b;` +- `use a::self;` -> `use a;` +- `use a::{};` -> (nothing) +- `use a::{b};` -> `use a::b;` Tools must not otherwise merge or un-merge import lists or adjust glob imports (without an explicit option). - -#### Nested imports +### Nested imports If there are any nested imports in a list import, then use the multi-line form, even if the import fits on one line. Each nested import must be on its own line, @@ -519,8 +501,7 @@ use a::b::{ }; ``` - -#### Merging/un-merging imports +### Merging/un-merging imports An example: diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md index 031811b0e6ff8..66e7fa3c9f89c 100644 --- a/src/doc/style-guide/src/nightly.md +++ b/src/doc/style-guide/src/nightly.md @@ -1,3 +1,5 @@ +# Nightly + This chapter documents style and formatting for nightly-only syntax. The rest of the style guide documents style for stable Rust syntax; nightly syntax only appears in this chapter. Each section here includes the name of the feature gate, so that searches (e.g. `git grep`) for a nightly feature in the Rust repository also turn up the style guide section. Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization. diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index d548693e39ed0..ce57c649a2d0b 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -3,27 +3,27 @@ When deciding on style guidelines, the style team follows these guiding principles (in rough priority order): -* readability - - scan-ability - - avoiding misleading formatting - - accessibility - readable and editable by users using the widest - variety of hardware, including non-visual accessibility interfaces - - readability of code in contexts without syntax highlighting or IDE - assistance, such as rustc error messages, diffs, grep, and other - plain-text contexts +- readability + - scan-ability + - avoiding misleading formatting + - accessibility - readable and editable by users using the widest + variety of hardware, including non-visual accessibility interfaces + - readability of code in contexts without syntax highlighting or IDE + assistance, such as rustc error messages, diffs, grep, and other + plain-text contexts -* aesthetics - - sense of 'beauty' - - consistent with other languages/tools +- aesthetics + - sense of 'beauty' + - consistent with other languages/tools -* specifics - - compatibility with version control practices - preserving diffs, - merge-friendliness, etc. - - preventing rightward drift - - minimising vertical space +- specifics + - compatibility with version control practices - preserving diffs, + merge-friendliness, etc. + - preventing rightward drift + - minimising vertical space -* application - - ease of manual application - - ease of implementation (in `rustfmt`, and in other tools/editors/code generators) - - internal consistency - - simplicity of formatting rules +- application + - ease of manual application + - ease of implementation (in `rustfmt`, and in other tools/editors/code generators) + - internal consistency + - simplicity of formatting rules diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index 8c8f893fbe904..6f322b3d65b54 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -1,6 +1,6 @@ -## Statements +# Statements -### Let statements +## Let statements Put a space after the `:` and on both sides of the `=` (if they are present). Don't put a space before the semicolon. @@ -28,7 +28,6 @@ use block indentation. If the type requires multiple lines, even after line-breaking after the `:`, then place the first line on the same line as the `:`, subject to the [combining rules](expressions.html#combinable-expressions). - ```rust let pattern: Type = @@ -101,7 +100,7 @@ let Foo { ); ``` -#### else blocks (let-else statements) +### else blocks (let-else statements) A let statement can contain an `else` component, making it a let-else statement. In this case, always apply the same formatting rules to the components preceding @@ -231,7 +230,7 @@ fn main() { } ``` -### Macros in statement position +## Macros in statement position For a macro use in statement position, use parentheses or square brackets as delimiters, and terminate it with a semicolon. Do not put spaces around the @@ -242,8 +241,7 @@ name, `!`, the delimiters, or the `;`. a_macro!(...); ``` - -### Expressions in statement position +## Expressions in statement position Do not put space between the expression and the semicolon. diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md index 15b001d4f2ea5..b7921c8914e45 100644 --- a/src/doc/style-guide/src/types.md +++ b/src/doc/style-guide/src/types.md @@ -1,23 +1,22 @@ -## Types and Bounds - -### Single line formatting - -* `[T]` no spaces -* `[T; expr]`, e.g., `[u32; 42]`, `[Vec; 10 * 2 + foo()]` (space after colon, no spaces around square brackets) -* `*const T`, `*mut T` (no space after `*`, space before type) -* `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words) -* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets) -* `!` gets treated like any other type name, `Name` -* `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple) -* ` as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`) -* `Foo::Bar` (spaces after commas, no trailing comma, no spaces around angle brackets) -* `T + T + T` (single spaces between types, and `+`). -* `impl T + T + T` (single spaces between keyword, types, and `+`). +# Types and Bounds + +## Single line formatting + +- `[T]` no spaces +- `[T; expr]`, e.g., `[u32; 42]`, `[Vec; 10 * 2 + foo()]` (space after colon, no spaces around square brackets) +- `*const T`, `*mut T` (no space after `*`, space before type) +- `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words) +- `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets) +- `!` gets treated like any other type name, `Name` +- `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple) +- ` as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`) +- `Foo::Bar` (spaces after commas, no trailing comma, no spaces around angle brackets) +- `T + T + T` (single spaces between types, and `+`). +- `impl T + T + T` (single spaces between keyword, types, and `+`). Do not put space around parentheses used in types, e.g., `(Foo)` - -### Line breaks +## Line breaks Avoid breaking lines in types where possible. Prefer breaking at outermost scope, e.g., prefer diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs index 66876e02c1914..f20b7a2b4d729 100644 --- a/src/tools/build_helper/src/git.rs +++ b/src/tools/build_helper/src/git.rs @@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result { /// We will then fall back to origin/master in the hope that at least this exists. pub fn updated_master_branch(git_dir: Option<&Path>) -> Result { let upstream_remote = get_rust_lang_rust_remote(git_dir)?; - let upstream_master = format!("{upstream_remote}/master"); - if rev_exists(&upstream_master, git_dir)? { - return Ok(upstream_master); + for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] { + if rev_exists(&upstream_master, git_dir)? { + return Ok(upstream_master); + } } - // We could implement smarter logic here in the future. - Ok("origin/master".into()) + Err(format!("Cannot find any suitable upstream master branch")) +} + +pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result { + let updated_master = updated_master_branch(git_dir)?; + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned()) } /// Returns the files that have been modified in the current branch compared to the master branch. @@ -94,20 +103,13 @@ pub fn get_git_modified_files( git_dir: Option<&Path>, extensions: &Vec<&str>, ) -> Result>, String> { - let Ok(updated_master) = updated_master_branch(git_dir) else { - return Ok(None); - }; - - let git = || { - let mut git = Command::new("git"); - if let Some(git_dir) = git_dir { - git.current_dir(git_dir); - } - git - }; + let merge_base = get_git_merge_base(git_dir)?; - let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?; - let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))? + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))? .lines() .map(|s| s.trim().to_owned()) .filter(|f| {