From 92144e1ee183fc8ed097c937fcc4754242b69a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:41:19 +0200 Subject: [PATCH 01/27] Remove `josh-sync` tooling and update README --- src/doc/rustc-dev-guide/README.md | 35 +- src/doc/rustc-dev-guide/josh-sync/Cargo.lock | 430 ------------------ src/doc/rustc-dev-guide/josh-sync/Cargo.toml | 9 - src/doc/rustc-dev-guide/josh-sync/README.md | 4 - src/doc/rustc-dev-guide/josh-sync/src/main.rs | 41 -- src/doc/rustc-dev-guide/josh-sync/src/sync.rs | 275 ----------- 6 files changed, 5 insertions(+), 789 deletions(-) delete mode 100644 src/doc/rustc-dev-guide/josh-sync/Cargo.lock delete mode 100644 src/doc/rustc-dev-guide/josh-sync/Cargo.toml delete mode 100644 src/doc/rustc-dev-guide/josh-sync/README.md delete mode 100644 src/doc/rustc-dev-guide/josh-sync/src/main.rs delete mode 100644 src/doc/rustc-dev-guide/josh-sync/src/sync.rs diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 0425c15f83c1c..f11290e44d8f5 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -72,49 +72,24 @@ including the `` marker at the place where you want the TOC. ## Synchronizing josh subtree with rustc -This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the following commands to synchronize the subtree in both directions. +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. -You'll need to install `josh-proxy` locally via - -``` -cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 -``` -Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version. +You can install the tool using `cargo install --locked --git https://github.com/rust-lang/josh-sync`. ### Pull changes from `rust-lang/rust` into this repository 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command ``` - cargo run --manifest-path josh-sync/Cargo.toml rustc-pull + rustc-josh-sync pull ``` 3) Push the branch to your fork and create a PR into `rustc-dev-guide` + - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. ### Push changes from this repository into `rust-lang/rust` -NOTE: If you use Git protocol to push to your fork of `rust-lang/rust`, -ensure that you have this entry in your Git config, -else the 2 steps that follow would prompt for a username and password: - -``` -[url "git@github.com:"] -insteadOf = "https://github.com/" -``` - 1) Run the push command to create a branch named `` in a `rustc` fork under the `` account ``` - cargo run --manifest-path josh-sync/Cargo.toml rustc-push + rustc-josh-sync push ``` 2) Create a PR from `` into `rust-lang/rust` - -#### Minimal git config - -For simplicity (ease of implementation purposes), the josh-sync script simply calls out to system git. This means that the git invocation may be influenced by global (or local) git configuration. - -You may observe "Nothing to pull" even if you *know* rustc-pull has something to pull if your global git config sets `fetch.prunetags = true` (and possibly other configurations may cause unexpected outcomes). - -To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. - -``` -GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull -``` diff --git a/src/doc/rustc-dev-guide/josh-sync/Cargo.lock b/src/doc/rustc-dev-guide/josh-sync/Cargo.lock deleted file mode 100644 index a8183a740db3b..0000000000000 --- a/src/doc/rustc-dev-guide/josh-sync/Cargo.lock +++ /dev/null @@ -1,430 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "anstream" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anstyle-parse" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" -dependencies = [ - "anstyle", - "windows-sys 0.59.0", -] - -[[package]] -name = "anyhow" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.5.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "josh-sync" -version = "0.0.0" -dependencies = [ - "anyhow", - "clap", - "directories", - "xshell", -] - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags", - "libc", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "proc-macro2" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-ident" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "xshell" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7290c623014758632efe00737145b6867b66292c42167f2ec381eb566a373d" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547" diff --git a/src/doc/rustc-dev-guide/josh-sync/Cargo.toml b/src/doc/rustc-dev-guide/josh-sync/Cargo.toml deleted file mode 100644 index 1f8bf2a009333..0000000000000 --- a/src/doc/rustc-dev-guide/josh-sync/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "josh-sync" -edition = "2024" - -[dependencies] -anyhow = "1.0.95" -clap = { version = "4.5.21", features = ["derive"] } -directories = "5" -xshell = "0.2.6" diff --git a/src/doc/rustc-dev-guide/josh-sync/README.md b/src/doc/rustc-dev-guide/josh-sync/README.md deleted file mode 100644 index a3dd876e8b87b..0000000000000 --- a/src/doc/rustc-dev-guide/josh-sync/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Git josh sync -This utility serves for syncing the josh git subtree to and from the rust-lang/rust repository. - -See CLI help for usage. diff --git a/src/doc/rustc-dev-guide/josh-sync/src/main.rs b/src/doc/rustc-dev-guide/josh-sync/src/main.rs deleted file mode 100644 index aeedee5be22d1..0000000000000 --- a/src/doc/rustc-dev-guide/josh-sync/src/main.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clap::Parser; - -use crate::sync::{GitSync, RustcPullError}; - -mod sync; - -#[derive(clap::Parser)] -enum Args { - /// Pull changes from the main `rustc` repository. - /// This creates new commits that should be then merged into `rustc-dev-guide`. - RustcPull, - /// Push changes from `rustc-dev-guide` to the given `branch` of a `rustc` fork under the given - /// GitHub `username`. - /// The pushed branch should then be merged into the `rustc` repository. - RustcPush { branch: String, github_username: String }, -} - -fn main() -> anyhow::Result<()> { - let args = Args::parse(); - let sync = GitSync::from_current_dir()?; - match args { - Args::RustcPull => { - if let Err(error) = sync.rustc_pull(None) { - match error { - RustcPullError::NothingToPull => { - eprintln!("Nothing to pull"); - std::process::exit(2); - } - RustcPullError::PullFailed(error) => { - eprintln!("Pull failure: {error:?}"); - std::process::exit(1); - } - } - } - } - Args::RustcPush { github_username, branch } => { - sync.rustc_push(github_username, branch)?; - } - } - Ok(()) -} diff --git a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs deleted file mode 100644 index ed38d1403a02b..0000000000000 --- a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs +++ /dev/null @@ -1,275 +0,0 @@ -use std::io::Write; -use std::ops::Not; -use std::path::PathBuf; -use std::time::Duration; -use std::{env, net, process}; - -use anyhow::{Context, anyhow, bail}; -use xshell::{Shell, cmd}; - -/// Used for rustc syncs. -const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide"; -const JOSH_PORT: u16 = 42042; -const UPSTREAM_REPO: &str = "rust-lang/rust"; - -pub enum RustcPullError { - /// No changes are available to be pulled. - NothingToPull, - /// A rustc-pull has failed, probably a git operation error has occurred. - PullFailed(anyhow::Error), -} - -impl From for RustcPullError -where - E: Into, -{ - fn from(error: E) -> Self { - Self::PullFailed(error.into()) - } -} - -pub struct GitSync { - dir: PathBuf, -} - -/// This code was adapted from the miri repository -/// (https://github.com/rust-lang/miri/blob/6a68a79f38064c3bc30617cca4bdbfb2c336b140/miri-script/src/commands.rs#L236). -impl GitSync { - pub fn from_current_dir() -> anyhow::Result { - Ok(Self { dir: std::env::current_dir()? }) - } - - pub fn rustc_pull(&self, commit: Option) -> Result<(), RustcPullError> { - let sh = Shell::new()?; - sh.change_dir(&self.dir); - let commit = commit.map(Ok).unwrap_or_else(|| { - let rust_repo_head = - cmd!(sh, "git ls-remote https://github.com/{UPSTREAM_REPO}/ HEAD").read()?; - rust_repo_head - .split_whitespace() - .next() - .map(|front| front.trim().to_owned()) - .ok_or_else(|| anyhow!("Could not obtain Rust repo HEAD from remote.")) - })?; - // Make sure the repo is clean. - if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - return Err(anyhow::anyhow!( - "working directory must be clean before performing rustc pull" - ) - .into()); - } - // Make sure josh is running. - let josh = Self::start_josh()?; - let josh_url = - format!("http://localhost:{JOSH_PORT}/{UPSTREAM_REPO}.git@{commit}{JOSH_FILTER}.git"); - - let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); - if previous_base_commit == commit { - return Err(RustcPullError::NothingToPull); - } - - // Update rust-version file. As a separate commit, since making it part of - // the merge has confused the heck out of josh in the past. - // We pass `--no-verify` to avoid running git hooks. - // We do this before the merge so that if there are merge conflicts, we have - // the right rust-version file while resolving them. - sh.write_file("rust-version", format!("{commit}\n"))?; - const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc"; - cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}") - .run() - .context("FAILED to commit rust-version file, something went wrong")?; - - // Fetch given rustc commit. - cmd!(sh, "git fetch {josh_url}") - .run() - .inspect_err(|_| { - // Try to un-do the previous `git commit`, to leave the repo in the state we found it. - cmd!(sh, "git reset --hard HEAD^") - .run() - .expect("FAILED to clean up again after failed `git fetch`, sorry for that"); - }) - .context("FAILED to fetch new commits, something went wrong (committing the rust-version file has been undone)")?; - - // This should not add any new root commits. So count those before and after merging. - let num_roots = || -> anyhow::Result { - Ok(cmd!(sh, "git rev-list HEAD --max-parents=0 --count") - .read() - .context("failed to determine the number of root commits")? - .parse::()?) - }; - let num_roots_before = num_roots()?; - - let sha = - cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; - - // Merge the fetched commit. - const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc"; - cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}") - .run() - .context("FAILED to merge new commits, something went wrong")?; - - let current_sha = - cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout; - if current_sha == sha { - cmd!(sh, "git reset --hard HEAD^") - .run() - .expect("FAILED to clean up after creating the preparation commit"); - eprintln!( - "No merge was performed, no changes to pull were found. Rolled back the preparation commit." - ); - return Err(RustcPullError::NothingToPull); - } - - // Check that the number of roots did not increase. - if num_roots()? != num_roots_before { - return Err(anyhow::anyhow!( - "Josh created a new root commit. This is probably not the history you want." - ) - .into()); - } - - drop(josh); - Ok(()) - } - - pub fn rustc_push(&self, github_user: String, branch: String) -> anyhow::Result<()> { - let sh = Shell::new()?; - sh.change_dir(&self.dir); - let base = sh.read_file("rust-version")?.trim().to_owned(); - // Make sure the repo is clean. - if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - bail!("working directory must be clean before running `rustc-push`"); - } - // Make sure josh is running. - let josh = Self::start_josh()?; - let josh_url = - format!("http://localhost:{JOSH_PORT}/{github_user}/rust.git{JOSH_FILTER}.git"); - - // Find a repo we can do our preparation in. - if let Ok(rustc_git) = env::var("RUSTC_GIT") { - // If rustc_git is `Some`, we'll use an existing fork for the branch updates. - sh.change_dir(rustc_git); - } else { - // Otherwise, do this in the local repo. - println!( - "This will pull a copy of the rust-lang/rust history into this checkout, growing it by about 1GB." - ); - print!( - "To avoid that, abort now and set the `RUSTC_GIT` environment variable to an existing rustc checkout. Proceed? [y/N] " - ); - std::io::stdout().flush()?; - let mut answer = String::new(); - std::io::stdin().read_line(&mut answer)?; - if answer.trim().to_lowercase() != "y" { - std::process::exit(1); - } - }; - // Prepare the branch. Pushing works much better if we use as base exactly - // the commit that we pulled from last time, so we use the `rust-version` - // file to find out which commit that would be. - println!("Preparing {github_user}/rust (base: {base})..."); - if cmd!(sh, "git fetch https://github.com/{github_user}/rust {branch}") - .ignore_stderr() - .read() - .is_ok() - { - println!( - "The branch '{branch}' seems to already exist in 'https://github.com/{github_user}/rust'. Please delete it and try again." - ); - std::process::exit(1); - } - cmd!(sh, "git fetch https://github.com/{UPSTREAM_REPO} {base}").run()?; - cmd!(sh, "git push https://github.com/{github_user}/rust {base}:refs/heads/{branch}") - .ignore_stdout() - .ignore_stderr() // silence the "create GitHub PR" message - .run()?; - println!(); - - // Do the actual push. - sh.change_dir(&self.dir); - println!("Pushing changes..."); - cmd!(sh, "git push {josh_url} HEAD:{branch}").run()?; - println!(); - - // Do a round-trip check to make sure the push worked as expected. - cmd!(sh, "git fetch {josh_url} {branch}").ignore_stderr().read()?; - let head = cmd!(sh, "git rev-parse HEAD").read()?; - let fetch_head = cmd!(sh, "git rev-parse FETCH_HEAD").read()?; - if head != fetch_head { - bail!( - "Josh created a non-roundtrip push! Do NOT merge this into rustc!\n\ - Expected {head}, got {fetch_head}." - ); - } - println!( - "Confirmed that the push round-trips back to rustc-dev-guide properly. Please create a rustc PR:" - ); - println!( - // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=rustc-dev-guide+subtree+update&body=r?+@ghost" - ); - - drop(josh); - Ok(()) - } - - fn start_josh() -> anyhow::Result { - // Determine cache directory. - let local_dir = { - let user_dirs = - directories::ProjectDirs::from("org", "rust-lang", "rustc-dev-guide-josh").unwrap(); - user_dirs.cache_dir().to_owned() - }; - - // Start josh, silencing its output. - let mut cmd = process::Command::new("josh-proxy"); - cmd.arg("--local").arg(local_dir); - cmd.arg("--remote").arg("https://github.com"); - cmd.arg("--port").arg(JOSH_PORT.to_string()); - cmd.arg("--no-background"); - cmd.stdout(process::Stdio::null()); - cmd.stderr(process::Stdio::null()); - let josh = cmd.spawn().context("failed to start josh-proxy, make sure it is installed")?; - - // Create a wrapper that stops it on drop. - struct Josh(process::Child); - impl Drop for Josh { - fn drop(&mut self) { - #[cfg(unix)] - { - // Try to gracefully shut it down. - process::Command::new("kill") - .args(["-s", "INT", &self.0.id().to_string()]) - .output() - .expect("failed to SIGINT josh-proxy"); - // Sadly there is no "wait with timeout"... so we just give it some time to finish. - std::thread::sleep(Duration::from_millis(100)); - // Now hopefully it is gone. - if self.0.try_wait().expect("failed to wait for josh-proxy").is_some() { - return; - } - } - // If that didn't work (or we're not on Unix), kill it hard. - eprintln!( - "I have to kill josh-proxy the hard way, let's hope this does not break anything." - ); - self.0.kill().expect("failed to SIGKILL josh-proxy"); - } - } - - // Wait until the port is open. We try every 10ms until 1s passed. - for _ in 0..100 { - // This will generally fail immediately when the port is still closed. - let josh_ready = net::TcpStream::connect_timeout( - &net::SocketAddr::from(([127, 0, 0, 1], JOSH_PORT)), - Duration::from_millis(1), - ); - if josh_ready.is_ok() { - return Ok(Josh(josh)); - } - // Not ready yet. - std::thread::sleep(Duration::from_millis(10)); - } - bail!("Even after waiting for 1s, josh-proxy is still not available.") - } -} From 13dca5e1baede8fe0df76ccba1875a14dda10269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:44:58 +0200 Subject: [PATCH 02/27] Update CI workflow to use rustc-josh-sync --- src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 1e430d8b4e65a..7190fc733db01 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml @@ -24,11 +24,10 @@ jobs: run: rustup update stable - uses: Swatinem/rust-cache@v2 with: - workspaces: "josh-sync" # Cache the josh directory with checked out rustc - cache-directories: "/home/runner/.cache/rustc-dev-guide-josh" - - name: Install josh - run: RUSTFLAGS="--cap-lints warn" cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04 + cache-directories: "/home/runner/.cache/rustc-josh" + - name: Install rustc-josh-sync + run: cargo install --locked --git https://github.com/rust-lang/josh-sync - name: Setup bot git name and email run: | git config --global user.name 'The rustc-dev-guide Cronjob Bot' @@ -38,7 +37,7 @@ jobs: # Turn off -e to disable early exit shell: bash {0} run: | - cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + rustc-josh-sync pull exitcode=$? # If no pull was performed, we want to mark this job as successful, From 9d83749cdd02531b000eead51cd0de40ec9a59e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 13:14:23 +0200 Subject: [PATCH 03/27] Document `rustc-josh-sync` --- src/doc/rustc-dev-guide/README.md | 20 +----- src/doc/rustc-dev-guide/src/external-repos.md | 62 +++++++++++++++---- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index f11290e44d8f5..5932da467ab2d 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -74,22 +74,4 @@ including the `` marker at the place where you want the TOC. This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. -You can install the tool using `cargo install --locked --git https://github.com/rust-lang/josh-sync`. - -### Pull changes from `rust-lang/rust` into this repository - -1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` -2) Run the pull command - ``` - rustc-josh-sync pull - ``` -3) Push the branch to your fork and create a PR into `rustc-dev-guide` - - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. - -### Push changes from this repository into `rust-lang/rust` - -1) Run the push command to create a branch named `` in a `rustc` fork under the `` account - ``` - rustc-josh-sync push - ``` -2) Create a PR from `` into `rust-lang/rust` +You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index f3170c9222d88..a19b1116de82c 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -9,7 +9,7 @@ There are three main ways we use dependencies: As a general rule: - Use crates.io for libraries that could be useful for others in the ecosystem - Use subtrees for tools that depend on compiler internals and need to be updated if there are breaking -changes + changes - Use submodules for tools that are independent of the compiler ## External Dependencies (subtrees) @@ -23,6 +23,8 @@ The following external projects are managed using some form of a `subtree`: * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) * [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) * [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) +* [compiler-builtins](https://github.com/rust-lang/compiler-builtins) +* [stdarch](https://github.com/rust-lang/stdarch) In contrast to `submodule` dependencies (see below for those), the `subtree` dependencies are just regular files and directories which can @@ -34,20 +36,57 @@ implement a new tool feature or test, that should happen in one collective rustc `subtree` dependencies are currently managed by two distinct approaches: * Using `git subtree` - * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy)) - * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) - * `rustfmt` - * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) + * `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy)) + * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) + * `rustfmt` + * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) * Using the [josh] tool - * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) - * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) - * `rustc-dev-guide` ([sync guide](https://github.com/rust-lang/rustc-dev-guide#synchronizing-josh-subtree-with-rustc)) + * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) + * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) + * `rustc-dev-guide` + * `compiler-builtins` + * `stdarch` -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). +### Josh subtrees -Below you can find a guide on how to perform push and pull synchronization with the main rustc repo using `git subtree`, although these instructions might differ repo from repo. +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, it is described [below](#synchronizing-a-josh-subtree). -### Synchronizing a subtree +### Synchronizing a Josh subtree + +We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates. +Currently, we are migrating Josh repositories to it. So far, it is used in: + +- rustc-dev-guide + +To use the tool, first install it with `cargo install --locked --git https://github. +com/rust-lang/josh-sync`. + +Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize +changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first +switch to its repository checkout directory in your terminal). + +#### Performing pull +1) Checkout a new branch that will be used to create a PR into the subtree +2) Run the pull command + ``` + rustc-josh-sync pull + ``` +3) Push the branch to your fork and create a PR into the subtree repository + - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you. + +#### Performing push + +1) Run the push command to create a branch named `` in a `rustc` fork under the `` account + ``` + rustc-josh-sync push + ``` +2) Create a PR from `` into `rust-lang/rust` + +### Creating a new Josh subtree dependency + +If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg). + +### Synchronizing a git subtree Periodically the changes made to subtree based dependencies need to be synchronized between this repository and the upstream tool repositories. @@ -129,3 +168,4 @@ the week leading up to the beta cut. [toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/ [Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html [josh]: https://josh-project.github.io/josh/intro.html +[josh-sync]: https://github.com/rust-lang/josh-sync From f167f9b49ec85dae8756c21f5183cdb1f43c6d4d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 4 Jul 2025 14:13:15 +0200 Subject: [PATCH 04/27] external-repos.md: small fixes --- src/doc/rustc-dev-guide/src/external-repos.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index a19b1116de82c..fc40b5d2bfa5a 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -49,7 +49,7 @@ implement a new tool feature or test, that should happen in one collective rustc ### Josh subtrees -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, it is described [below](#synchronizing-a-josh-subtree). +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh; you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree). ### Synchronizing a Josh subtree @@ -58,8 +58,7 @@ Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide -To use the tool, first install it with `cargo install --locked --git https://github. -com/rust-lang/josh-sync`. +To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first From 922ee88762e36dea38113f84ca3898b2e59531ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 8 Jul 2025 08:57:05 +0200 Subject: [PATCH 05/27] Mention that stdarch is managed by josh-sync --- src/doc/rustc-dev-guide/src/external-repos.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index fc40b5d2bfa5a..0f7322357b9d4 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -43,9 +43,9 @@ implement a new tool feature or test, that should happen in one collective rustc * Using the [josh] tool * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) - * `rustc-dev-guide` + * `rustc-dev-guide` ([josh sync](#synchronizing-a-josh-subtree)) * `compiler-builtins` - * `stdarch` + * `stdarch` ([josh sync](#synchronizing-a-josh-subtree)) ### Josh subtrees @@ -57,6 +57,7 @@ We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Jos Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide +- stdarch To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. From 6b8bc68a503e0b27828404270759ab3523b1c91a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 07:13:44 +0200 Subject: [PATCH 06/27] use a consistent (and recommended) invocation ./x is recommended over running ./x.py directly, and is the more commonly-used invocation of bootstrap in the guide --- src/doc/rustc-dev-guide/src/autodiff/installation.md | 10 +++++----- src/doc/rustc-dev-guide/src/offload/installation.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md index c9b28dc43a6d1..92e79b2f3831d 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/installation.md +++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md @@ -13,7 +13,7 @@ cd rust Afterwards you can build rustc using: ```bash -./x.py build --stage 1 library +./x build --stage 1 library ``` Afterwards rustc toolchain link will allow you to use it through cargo: @@ -25,10 +25,10 @@ rustup toolchain install nightly # enables -Z unstable-options You can then run our test cases: ```bash -./x.py test --stage 1 tests/codegen/autodiff -./x.py test --stage 1 tests/pretty/autodiff -./x.py test --stage 1 tests/ui/autodiff -./x.py test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs +./x test --stage 1 tests/codegen/autodiff +./x test --stage 1 tests/pretty/autodiff +./x test --stage 1 tests/ui/autodiff +./x test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs ``` Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml diff --git a/src/doc/rustc-dev-guide/src/offload/installation.md b/src/doc/rustc-dev-guide/src/offload/installation.md index 2536af09a2369..8cfec44ec8e7d 100644 --- a/src/doc/rustc-dev-guide/src/offload/installation.md +++ b/src/doc/rustc-dev-guide/src/offload/installation.md @@ -13,7 +13,7 @@ cd rust Afterwards you can build rustc using: ```bash -./x.py build --stage 1 library +./x build --stage 1 library ``` Afterwards rustc toolchain link will allow you to use it through cargo: @@ -40,7 +40,7 @@ This gives you a working LLVM build. ## Testing run ``` -./x.py test --stage 1 tests/codegen/gpu_offload +./x test --stage 1 tests/codegen/gpu_offload ``` ## Usage From 7b394d2650472866162adb1e3e775d7c43ed8854 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 07:28:16 +0200 Subject: [PATCH 07/27] tweak some git clone commands - --depth=1 is more useful for once-off uses, like on ci - .git postfix on github repo url is not needed --- src/doc/rustc-dev-guide/src/autodiff/installation.md | 8 ++++---- src/doc/rustc-dev-guide/src/offload/installation.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md index 92e79b2f3831d..a550f6d233eb5 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/installation.md +++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md @@ -6,7 +6,7 @@ In the near future, `std::autodiff` should become available in nightly builds fo First you need to clone and configure the Rust repository: ```bash -git clone --depth=1 git@github.com:rust-lang/rust.git +git clone git@github.com:rust-lang/rust cd rust ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ``` @@ -45,7 +45,7 @@ apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmak ``` Then build rustc in a slightly altered way: ```bash -git clone --depth=1 https://github.com/rust-lang/rust.git +git clone https://github.com/rust-lang/rust cd rust ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ./x dist @@ -66,7 +66,7 @@ We recommend that approach, if you just want to use any of them and have no expe However, if you prefer to just build Enzyme without Rust, then these instructions might help. ```bash -git clone --depth=1 git@github.com:llvm/llvm-project.git +git clone git@github.com:llvm/llvm-project cd llvm-project mkdir build cd build @@ -77,7 +77,7 @@ ninja install This gives you a working LLVM build, now we can continue with building Enzyme. Leave the `llvm-project` folder, and execute the following commands: ```bash -git clone git@github.com:EnzymeAD/Enzyme.git +git clone git@github.com:EnzymeAD/Enzyme cd Enzyme/enzyme mkdir build cd build diff --git a/src/doc/rustc-dev-guide/src/offload/installation.md b/src/doc/rustc-dev-guide/src/offload/installation.md index 8cfec44ec8e7d..1962314c70ac8 100644 --- a/src/doc/rustc-dev-guide/src/offload/installation.md +++ b/src/doc/rustc-dev-guide/src/offload/installation.md @@ -6,7 +6,7 @@ In the future, `std::offload` should become available in nightly builds for user First you need to clone and configure the Rust repository: ```bash -git clone --depth=1 git@github.com:rust-lang/rust.git +git clone git@github.com:rust-lang/rust cd rust ./configure --enable-llvm-link-shared --release-channel=nightly --enable-llvm-assertions --enable-offload --enable-enzyme --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs ``` @@ -26,7 +26,7 @@ rustup toolchain install nightly # enables -Z unstable-options ## Build instruction for LLVM itself ```bash -git clone --depth=1 git@github.com:llvm/llvm-project.git +git clone git@github.com:llvm/llvm-project cd llvm-project mkdir build cd build From 42472f26452505cb42477990e6450bed21b3a50d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 22:49:41 +0200 Subject: [PATCH 08/27] add missing word --- src/doc/rustc-dev-guide/src/tests/misc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/misc.md b/src/doc/rustc-dev-guide/src/tests/misc.md index c0288b3dd10cd..39f881748792f 100644 --- a/src/doc/rustc-dev-guide/src/tests/misc.md +++ b/src/doc/rustc-dev-guide/src/tests/misc.md @@ -9,7 +9,7 @@ for testing: - `RUSTC_BOOTSTRAP=1` will "cheat" and bypass usual stability checking, allowing you to use unstable features and cli flags on a stable `rustc`. -- `RUSTC_BOOTSTRAP=-1` will force a given `rustc` to pretend that is a stable +- `RUSTC_BOOTSTRAP=-1` will force a given `rustc` to pretend it is a stable compiler, even if it's actually a nightly `rustc`. This is useful because some behaviors of the compiler (e.g. diagnostics) can differ depending on whether the compiler is nightly or not. From d99af0b77cde2cc7d13419d7ca9b244afbcd365f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 23:02:16 +0200 Subject: [PATCH 09/27] distcheck had only one possible invocation That is, calling it an example is misleading --- src/doc/rustc-dev-guide/src/tests/intro.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md index c55d60f4a5c7b..e97574f02de2f 100644 --- a/src/doc/rustc-dev-guide/src/tests/intro.md +++ b/src/doc/rustc-dev-guide/src/tests/intro.md @@ -116,7 +116,9 @@ This requires building all of the documentation, which might take a while. `distcheck` verifies that the source distribution tarball created by the build system will unpack, build, and run all tests. -> Example: `./x test distcheck` +```console +./x test distcheck +``` ### Tool tests From 99fc05bb1830f6c6132ff7b1e48e2e655c863ad6 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 9 Jul 2025 23:03:37 +0200 Subject: [PATCH 10/27] do not invent a name Nowhere else is this called "Dist check" --- src/doc/rustc-dev-guide/src/tests/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md index c55d60f4a5c7b..84f99e9461e87 100644 --- a/src/doc/rustc-dev-guide/src/tests/intro.md +++ b/src/doc/rustc-dev-guide/src/tests/intro.md @@ -111,7 +111,7 @@ and it can be invoked so: This requires building all of the documentation, which might take a while. -### Dist check +### `distcheck` `distcheck` verifies that the source distribution tarball created by the build system will unpack, build, and run all tests. From f1ae43f14d2b1737b71fc14c20b1242a74d66c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 10 Jul 2025 09:56:59 +0200 Subject: [PATCH 11/27] Mention that compiler-builtins is now using `rustc-josh-sync` --- src/doc/rustc-dev-guide/src/external-repos.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index 0f7322357b9d4..68986a0bc6886 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -44,7 +44,7 @@ implement a new tool feature or test, that should happen in one collective rustc * `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo)) * `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147)) * `rustc-dev-guide` ([josh sync](#synchronizing-a-josh-subtree)) - * `compiler-builtins` + * `compiler-builtins` ([josh sync](#synchronizing-a-josh-subtree)) * `stdarch` ([josh sync](#synchronizing-a-josh-subtree)) ### Josh subtrees @@ -56,6 +56,7 @@ The [josh] tool is an alternative to git subtrees, which manages git history in We use a dedicated tool called [`rustc-josh-sync`][josh-sync] for performing Josh subtree updates. Currently, we are migrating Josh repositories to it. So far, it is used in: +- compiler-builtins - rustc-dev-guide - stdarch From c6bedc1bf9752c482e7a2fd58e24c7569fb58555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 10 Jul 2025 10:02:39 +0200 Subject: [PATCH 12/27] Migrate rustc-pull to CI workflow from `josh-sync` --- .../.github/workflows/rustc-pull.yml | 111 ++---------------- 1 file changed, 9 insertions(+), 102 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 7190fc733db01..ad570ee4595d4 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml @@ -9,105 +9,12 @@ on: jobs: pull: if: github.repository == 'rust-lang/rustc-dev-guide' - runs-on: ubuntu-latest - outputs: - pr_url: ${{ steps.update-pr.outputs.pr_url }} - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@v4 - with: - # We need the full history for josh to work - fetch-depth: '0' - - name: Install stable Rust toolchain - run: rustup update stable - - uses: Swatinem/rust-cache@v2 - with: - # Cache the josh directory with checked out rustc - cache-directories: "/home/runner/.cache/rustc-josh" - - name: Install rustc-josh-sync - run: cargo install --locked --git https://github.com/rust-lang/josh-sync - - name: Setup bot git name and email - run: | - git config --global user.name 'The rustc-dev-guide Cronjob Bot' - git config --global user.email 'github-actions@github.com' - - name: Perform rustc-pull - id: rustc-pull - # Turn off -e to disable early exit - shell: bash {0} - run: | - rustc-josh-sync pull - exitcode=$? - - # If no pull was performed, we want to mark this job as successful, - # but we do not want to perform the follow-up steps. - if [ $exitcode -eq 0 ]; then - echo "pull_result=pull-finished" >> $GITHUB_OUTPUT - elif [ $exitcode -eq 2 ]; then - echo "pull_result=skipped" >> $GITHUB_OUTPUT - exitcode=0 - fi - - exit ${exitcode} - - name: Push changes to a branch - if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} - run: | - # Update a sticky branch that is used only for rustc pulls - BRANCH="rustc-pull" - git switch -c $BRANCH - git push -u origin $BRANCH --force - - name: Create pull request - id: update-pr - if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Check if an open pull request for an rustc pull update already exists - # If it does, the previous push has just updated it - # If not, we create it now - RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` - if [[ "$RESULT" -eq 0 ]]; then - echo "Creating new pull request" - PR_URL=`gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.'` - echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT - else - PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` - echo "Updating pull request ${PR_URL}" - echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT - fi - send-zulip-message: - needs: [pull] - if: ${{ !cancelled() }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Compute message - id: create-message - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - if [ "${{ needs.pull.result }}" == "failure" ]; then - WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT - else - CREATED_AT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].createdAt' --json createdAt,title` - PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` - week_ago=$(date +%F -d '7 days ago') - - # If there is an open PR that is at least a week old, post a message about it - if [[ -n $DATE_GH && $DATE_GH < $week_ago ]]; then - echo "message=A PR with a Rustc pull has been opened for more a week. Check out the [PR](${PR_URL})." >> $GITHUB_OUTPUT - fi - fi - - name: Send a Zulip message about updated PR - if: ${{ steps.create-message.outputs.message != '' }} - uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 - with: - api-key: ${{ secrets.ZULIP_API_TOKEN }} - email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com" - organization-url: "https://rust-lang.zulipchat.com" - to: 196385 - type: "stream" - topic: "Subtree sync automation" - content: ${{ steps.create-message.outputs.message }} + uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main + with: + zulip-stream-id: 196385 + zulip-bot-email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com" + pr-base-branch: master + branch-name: rustc-pull + secrets: + zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} From 7803c25deaa3f330a952a18c7c3d5ea3850e9ff7 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Fri, 11 Jul 2025 13:39:39 -0500 Subject: [PATCH 13/27] directives.md: build-aux-docs does not work with aux-crate --- src/doc/rustc-dev-guide/src/tests/directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 839076b809df8..63aa08c389cca 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -59,7 +59,7 @@ not be exhaustive. Directives can generally be found by browsing the | `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make` | `=` | | `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file | | `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make` | Path to auxiliary proc-macro `.rs` file | -| `build-aux-docs` | Build docs for auxiliaries as well | All except `run-make` | N/A | +| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make` | N/A | [^pm]: please see the Auxiliary proc-macro section in the [compiletest](./compiletest.md) chapter for specifics. From 0e423f441ade436bd732ececd3dd6c79885dd07c Mon Sep 17 00:00:00 2001 From: Edoardo Marangoni Date: Wed, 16 Jul 2025 09:24:30 +0200 Subject: [PATCH 14/27] Boostrap: add warning on `optimize = false` --- src/bootstrap/src/core/config/toml/rust.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index 0fae235bb93fb..01fbd83317ecb 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -541,6 +541,14 @@ impl Config { lld_enabled = lld_enabled_toml; std_features = std_features_toml; + if optimize_toml.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) { + eprintln!( + "WARNING: setting `optimize` to `false` is known to cause errors and \ + should be considered unsupported. Refer to `bootstrap.example.toml` \ + for more details." + ); + } + optimize = optimize_toml; self.rust_new_symbol_mangling = new_symbol_mangling; set(&mut self.rust_optimize_tests, optimize_tests); From 9ef3be2f8662a6f65c02f7551bae0f7476da8211 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 16 Jul 2025 21:29:16 +0200 Subject: [PATCH 15/27] go over invariants again :3 Co-authored-by: Boxy --- .../rustc-dev-guide/src/solve/invariants.md | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index fd12b19575748..2f5a134f4dfed 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -11,10 +11,8 @@ It is important to know about the things you can assume while working on - and w type system, so here's an incomplete and unofficial list of invariants of the core type system: -- ✅: this invariant mostly holds, with some weird exceptions, you can rely on it outside -of these cases -- ❌: this invariant does not hold, either due to bugs or by design, you must not rely on -it for soundness or have to be incredibly careful when doing so +- ✅: this invariant mostly holds, with some weird exceptions or current bugs +- ❌: this invariant does not hold, and is unlikely to do so in the future; do not rely on it for soundness or have to be incredibly careful when doing so ### `wf(X)` implies `wf(normalize(X))` ✅ @@ -23,6 +21,8 @@ well-formed after normalizing said aliases. We rely on this as otherwise we would have to re-check for well-formedness for these types. +This currently does not hold due to a type system unsoundness: [#84533](https://github.com/rust-lang/rust/issues/84533). + ### Structural equality modulo regions implies semantic equality ✅ If you have a some type and equate it to itself after replacing any regions with unique @@ -36,7 +36,7 @@ If this invariant is broken MIR typeck ends up failing with an ICE. TODO: this invariant is formulated in a weird way and needs to be elaborated. Pretty much: I would like this check to only fail if there's a solver bug: -https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 +https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 We should readd this check and see where it breaks :3 If we prove some goal/equate types/whatever, apply the resulting inference constraints, and then redo the original action, the result should be the same. @@ -73,40 +73,47 @@ Many of the currently known unsound issues end up relying on this invariant bein It is however very difficult to imagine a sound type system without this invariant, so the issue is that the invariant is broken, not that we incorrectly rely on it. -### Generic goals and their instantiations have the same result ✅ +### The type system is complete ❌ + +The type system is not complete, it often adds unnecessary inference constraints, and errors +even though the goal could hold. + +- method selection +- opaque type inference +- handling type outlives constraints +- preferring `ParamEnv` candidates over `Impl` candidates during candidate selection +in the trait solver + +### Goals keep their result from HIR typeck afterwards ✅ -Pretty much: If we successfully typecheck a generic function concrete instantiations -of that function should also typeck. We should not get errors post-monomorphization. -We can however get overflow errors at that point. +Having a goal which succeeds during HIR typeck but fails when being reevaluated during MIR borrowck causes ICE, e.g. [#140211](https://github.com/rust-lang/rust/issues/140211). -TODO: example for overflow error post-monomorphization +Having a goal which succeeds during HIR typeck but fails after being instantiated is unsound, e.g. [#140212](https://github.com/rust-lang/rust/issues/140212). + +It is interesting that we allow some incompleteness in the trait solver while still maintaining this limitation. It would be nice if there was a clear way to separate the "allowed incompleteness" from behavior which would break this invariant. + +#### Normalization must not change results This invariant is relied on to allow the normalization of generic aliases. Breaking it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893) +#### Goals may still overflow after instantiation + +As they start to hit the recursion limit. We also have diverging aliases which are scuffed. It's unclear how these should be handled :3 + ### Trait goals in empty environments are proven by a unique impl ✅ If a trait goal holds with an empty environment, there should be a unique `impl`, either user-defined or builtin, which is used to prove that goal. This is -necessary to select a unique method. +necessary to select unique methods and associated items. We do however break this invariant in few cases, some of which are due to bugs, some by design: - *marker traits* are allowed to overlap as they do not have associated items - *specialization* allows specializing impls to overlap with their parent - the builtin trait object trait implementation can overlap with a user-defined impl: -[#57893] +[#57893](https://github.com/rust-lang/rust/issues/57893) -### The type system is complete ❌ - -The type system is not complete, it often adds unnecessary inference constraints, and errors -even though the goal could hold. - -- method selection -- opaque type inference -- handling type outlives constraints -- preferring `ParamEnv` candidates over `Impl` candidates during candidate selection -in the trait solver #### The type system is complete during the implicit negative overlap check in coherence ✅ @@ -121,18 +128,19 @@ We have to be careful as it is quite easy to break: - generalization of aliases - generalization during subtyping binders (luckily not exploitable in coherence) -### Trait solving must be (free) lifetime agnostic ✅ +### Trait solving must not depend on lifetimes being different ✅ + +If a goal holds with lifetimes being different, it must also hold with these lifetimes being the same. We otherwise get post-monomorphization errors during codegen or unsoundness due to invalid vtables. + +We could also just get inconsistent behavior when first proving a goal with different lifetimes which are later constrained to be equal. -Trait solving during codegen should have the same result as during typeck. As we erase -all free regions during codegen we must not rely on them during typeck. A noteworthy example -is special behavior for `'static`. +### Trait solving in bodies must not depend on lifetimes being equal ✅ We also have to be careful with relying on equality of regions in the trait solver. This is fine for codegen, as we treat all erased regions as equal. We can however lose equality information from HIR to MIR typeck. -The new solver "uniquifies regions" during canonicalization, canonicalizing `u32: Trait<'x, 'x>` -as `exists<'0, '1> u32: Trait<'0, '1>`, to make it harder to rely on this property. +This currently does not hold with the new solver: [trait-system-refactor-initiative#27](https://github.com/rust-lang/trait-system-refactor-initiative/issues/27). ### Removing ambiguity makes strictly more things compile ❌ @@ -146,9 +154,16 @@ changes, breaking existing projects. Two types being equal in the type system must mean that they have the same `TypeId` after instantiating their generic parameters with concrete -arguments. This currently does not hold: [#97156]. +arguments. We can otherwise use their different `TypeId`s to impact trait selection. + +We lookup types using structural equality during codegen, but this shouldn't necessarily be unsound +- may result in redundant method codegen or backend type check errors? +- we also rely on it in CTFE assertions + +### Semantically different types have different `TypeId`s ✅ + +Semantically different `'static` types need different `TypeId`s to avoid transmutes, +for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. + -[#57893]: https://github.com/rust-lang/rust/issues/57893 -[#97156]: https://github.com/rust-lang/rust/issues/97156 -[#114936]: https://github.com/rust-lang/rust/issues/114936 -[coherence]: ../coherence.md +[coherence]: ../coherence.md From fad8dec970f51a2d4c23593b059b1684bd85472a Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Wed, 16 Jul 2025 15:39:31 +0900 Subject: [PATCH 16/27] fix: false positive double_negations when it jumps macro boundary --- compiler/rustc_lint/src/builtin.rs | 2 ++ tests/ui/lint/lint-double-negations-macro.rs | 16 +++++++++++++++ .../lint/lint-double-negations-macro.stderr | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 tests/ui/lint/lint-double-negations-macro.rs create mode 100644 tests/ui/lint/lint-double-negations-macro.stderr diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 255ff56f62b1d..93df056c43b92 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1584,6 +1584,8 @@ impl EarlyLintPass for DoubleNegations { if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind && let ExprKind::Unary(UnOp::Neg, ref inner2) = inner.kind && !matches!(inner2.kind, ExprKind::Unary(UnOp::Neg, _)) + // Don't lint if this jumps macro expansion boundary (Issue #143980) + && expr.span.eq_ctxt(inner.span) { cx.emit_span_lint( DOUBLE_NEGATIONS, diff --git a/tests/ui/lint/lint-double-negations-macro.rs b/tests/ui/lint/lint-double-negations-macro.rs new file mode 100644 index 0000000000000..a6583271d5a2a --- /dev/null +++ b/tests/ui/lint/lint-double-negations-macro.rs @@ -0,0 +1,16 @@ +//@ check-pass +macro_rules! neg { + ($e: expr) => { + -$e + }; +} +macro_rules! bad_macro { + ($e: expr) => { + --$e //~ WARN use of a double negation + }; +} + +fn main() { + neg!(-1); + bad_macro!(1); +} diff --git a/tests/ui/lint/lint-double-negations-macro.stderr b/tests/ui/lint/lint-double-negations-macro.stderr new file mode 100644 index 0000000000000..d6ac9be48f304 --- /dev/null +++ b/tests/ui/lint/lint-double-negations-macro.stderr @@ -0,0 +1,20 @@ +warning: use of a double negation + --> $DIR/lint-double-negations-macro.rs:9:9 + | +LL | --$e + | ^^^^ +... +LL | bad_macro!(1); + | ------------- in this macro invocation + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value + = note: `#[warn(double_negations)]` on by default + = note: this warning originates in the macro `bad_macro` (in Nightly builds, run with -Z macro-backtrace for more info) +help: add parentheses for clarity + | +LL | -(-$e) + | + + + +warning: 1 warning emitted + From 8df6a1d26636bb60fd9f8d45e3da9c0c2529ee29 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 17 Jul 2025 05:42:53 +0200 Subject: [PATCH 17/27] some improvements to "Invariants of the type system" --- .../rustc-dev-guide/src/solve/invariants.md | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index 2f5a134f4dfed..8ec15f339e51b 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -4,10 +4,10 @@ FIXME: This file talks about invariants of the type system as a whole, not only There are a lot of invariants - things the type system guarantees to be true at all times - which are desirable or expected from other languages and type systems. Unfortunately, quite -a few of them do not hold in Rust right now. This is either a fundamental to its design or -caused by bugs and something that may change in the future. +a few of them do not hold in Rust right now. This is either fundamental to its design or +caused by bugs, and something that may change in the future. -It is important to know about the things you can assume while working on - and with - the +It is important to know about the things you can assume while working on, and with, the type system, so here's an incomplete and unofficial list of invariants of the core type system: @@ -29,14 +29,15 @@ If you have a some type and equate it to itself after replacing any regions with inference variables in both the lhs and rhs, the now potentially structurally different types should still be equal to each other. -Needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck. -If this invariant is broken MIR typeck ends up failing with an ICE. +This is needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck. +If this invariant is broken, MIR typeck ends up failing with an ICE. ### Applying inference results from a goal does not change its result ❌ TODO: this invariant is formulated in a weird way and needs to be elaborated. Pretty much: I would like this check to only fail if there's a solver bug: -https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 We should readd this check and see where it breaks :3 +. +We should readd this check and see where it breaks :3 If we prove some goal/equate types/whatever, apply the resulting inference constraints, and then redo the original action, the result should be the same. @@ -75,8 +76,8 @@ the issue is that the invariant is broken, not that we incorrectly rely on it. ### The type system is complete ❌ -The type system is not complete, it often adds unnecessary inference constraints, and errors -even though the goal could hold. +The type system is not complete. +It often adds unnecessary inference constraints, and errors even though the goal could hold. - method selection - opaque type inference @@ -95,11 +96,13 @@ It is interesting that we allow some incompleteness in the trait solver while st #### Normalization must not change results This invariant is relied on to allow the normalization of generic aliases. Breaking -it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893) +it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893). #### Goals may still overflow after instantiation -As they start to hit the recursion limit. We also have diverging aliases which are scuffed. It's unclear how these should be handled :3 +This happens they start to hit the recursion limit. +We also have diverging aliases which are scuffed. +It's unclear how these should be handled :3 ### Trait goals in empty environments are proven by a unique impl ✅ @@ -107,8 +110,7 @@ If a trait goal holds with an empty environment, there should be a unique `impl` either user-defined or builtin, which is used to prove that goal. This is necessary to select unique methods and associated items. -We do however break this invariant in few cases, some of which are due to bugs, -some by design: +We do however break this invariant in a few cases, some of which are due to bugs, some by design: - *marker traits* are allowed to overlap as they do not have associated items - *specialization* allows specializing impls to overlap with their parent - the builtin trait object trait implementation can overlap with a user-defined impl: @@ -117,11 +119,12 @@ some by design: #### The type system is complete during the implicit negative overlap check in coherence ✅ -For more on overlap checking: [coherence] +For more on overlap checking, see [Coherence chapter]. -During the implicit negative overlap check in coherence we must never return *error* for -goals which can be proven. This would allow for overlapping impls with potentially different -associated items, breaking a bunch of other invariants. +During the implicit negative overlap check in coherence, +we must never return *error* for goals which can be proven. +This would allow for overlapping impls with potentially different associated items, +breaking a bunch of other invariants. This invariant is currently broken in many different ways while actually something we rely on. We have to be careful as it is quite easy to break: @@ -147,8 +150,8 @@ This currently does not hold with the new solver: [trait-system-refactor-initiat Ideally we *should* not rely on ambiguity for things to compile. Not doing that will cause future improvements to be breaking changes. -Due to *incompleteness* this is not the case and improving inference can result in inference -changes, breaking existing projects. +Due to *incompleteness* this is not the case, +and improving inference can result in inference changes, breaking existing projects. ### Semantic equality implies structural equality ✅ @@ -166,4 +169,4 @@ Semantically different `'static` types need different `TypeId`s to avoid transmu for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. -[coherence]: ../coherence.md +[coherence chapter]: ../coherence.md From 2faf5ed0cd20debd5eb6efe1795badccf6390c60 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 17 Jul 2025 04:14:28 +0000 Subject: [PATCH 18/27] Prepare for merging from rust-lang/rust This updates the rust-version file to fd2eb391d032181459773f3498c17b198513e0d0. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index e444613e6311c..3f10132b684b7 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -c96a69059ecc618b519da385a6ccd03155aa0237 +fd2eb391d032181459773f3498c17b198513e0d0 From dd364bd2261b37b6cd0d7f823b158a0c2903746b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 17 Jul 2025 06:32:23 +0200 Subject: [PATCH 19/27] copy-paste convenience --- src/doc/rustc-dev-guide/src/external-repos.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index 68986a0bc6886..ecc65b26ab7a0 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -60,7 +60,10 @@ Currently, we are migrating Josh repositories to it. So far, it is used in: - rustc-dev-guide - stdarch -To use the tool, first install it with `cargo install --locked --git https://github.com/rust-lang/josh-sync`. +To install the tool: +``` +cargo install --locked --git https://github.com/rust-lang/josh-sync +``` Both pulls (synchronize changes from rust-lang/rust into the subtree) and pushes (synchronize changes from the subtree to rust-lang/rust) are performed from the subtree repository (so first From 853333d4bdc7570b74e4bf02d506c2951a9d3e4b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 15 Jul 2025 09:57:44 +0000 Subject: [PATCH 20/27] constify `Option` methods --- library/core/src/option.rs | 137 ++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 40 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 9f432758a66f6..7633429fc5c0d 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -577,6 +577,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FusedIterator, TrustedLen}; +use crate::marker::Destruct; use crate::ops::{self, ControlFlow, Deref, DerefMut}; use crate::panicking::{panic, panic_display}; use crate::pin::Pin; @@ -649,7 +650,8 @@ impl Option { #[must_use] #[inline] #[stable(feature = "is_some_and", since = "1.70.0")] - pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn is_some_and(self, f: impl ~const FnOnce(T) -> bool + ~const Destruct) -> bool { match self { None => false, Some(x) => f(x), @@ -697,7 +699,8 @@ impl Option { #[must_use] #[inline] #[stable(feature = "is_none_or", since = "1.82.0")] - pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn is_none_or(self, f: impl ~const FnOnce(T) -> bool + ~const Destruct) -> bool { match self { None => true, Some(x) => f(x), @@ -1023,7 +1026,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, default: T) -> T { + #[rustc_allow_const_fn_unstable(const_precise_live_drops)] + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn unwrap_or(self, default: T) -> T + where + T: ~const Destruct, + { match self { Some(x) => x, None => default, @@ -1042,9 +1050,10 @@ impl Option { #[inline] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_else(self, f: F) -> T + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn unwrap_or_else(self, f: F) -> T where - F: FnOnce() -> T, + F: ~const FnOnce() -> T + ~const Destruct, { match self { Some(x) => x, @@ -1073,9 +1082,10 @@ impl Option { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_default(self) -> T + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn unwrap_or_default(self) -> T where - T: Default, + T: ~const Default, { match self { Some(x) => x, @@ -1139,9 +1149,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn map(self, f: F) -> Option where - F: FnOnce(T) -> U, + F: ~const FnOnce(T) -> U + ~const Destruct, { match self { Some(x) => Some(f(x)), @@ -1169,7 +1180,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "result_option_inspect", since = "1.76.0")] - pub fn inspect(self, f: F) -> Self { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn inspect(self, f: F) -> Self + where + F: ~const FnOnce(&T) + ~const Destruct, + { if let Some(ref x) = self { f(x); } @@ -1198,9 +1213,11 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the returned value, use `if let` instead"] - pub fn map_or(self, default: U, f: F) -> U + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn map_or(self, default: U, f: F) -> U where - F: FnOnce(T) -> U, + F: ~const FnOnce(T) -> U + ~const Destruct, + U: ~const Destruct, { match self { Some(t) => f(t), @@ -1243,10 +1260,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_or_else(self, default: D, f: F) -> U + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn map_or_else(self, default: D, f: F) -> U where - D: FnOnce() -> U, - F: FnOnce(T) -> U, + D: ~const FnOnce() -> U + ~const Destruct, + F: ~const FnOnce(T) -> U + ~const Destruct, { match self { Some(t) => f(t), @@ -1273,10 +1291,11 @@ impl Option { /// [default value]: Default::default #[inline] #[unstable(feature = "result_option_map_or_default", issue = "138099")] - pub fn map_or_default(self, f: F) -> U + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn map_or_default(self, f: F) -> U where - U: Default, - F: FnOnce(T) -> U, + U: ~const Default, + F: ~const FnOnce(T) -> U + ~const Destruct, { match self { Some(t) => f(t), @@ -1307,7 +1326,8 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or(self, err: E) -> Result { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn ok_or(self, err: E) -> Result { match self { Some(v) => Ok(v), None => Err(err), @@ -1332,9 +1352,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or_else(self, err: F) -> Result + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn ok_or_else(self, err: F) -> Result where - F: FnOnce() -> E, + F: ~const FnOnce() -> E + ~const Destruct, { match self { Some(v) => Ok(v), @@ -1463,7 +1484,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn and(self, optb: Option) -> Option + where + T: ~const Destruct, + U: ~const Destruct, + { match self { Some(_) => optb, None => None, @@ -1502,9 +1528,10 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("flat_map", "flatmap")] - pub fn and_then(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn and_then(self, f: F) -> Option where - F: FnOnce(T) -> Option, + F: ~const FnOnce(T) -> Option + ~const Destruct, { match self { Some(x) => f(x), @@ -1538,9 +1565,11 @@ impl Option { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - pub fn filter

(self, predicate: P) -> Self + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn filter

(self, predicate: P) -> Self where - P: FnOnce(&T) -> bool, + P: ~const FnOnce(&T) -> bool + ~const Destruct, + T: ~const Destruct, { if let Some(x) = self { if predicate(&x) { @@ -1579,7 +1608,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn or(self, optb: Option) -> Option + where + T: ~const Destruct, + { match self { x @ Some(_) => x, None => optb, @@ -1601,9 +1634,13 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or_else(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn or_else(self, f: F) -> Option where - F: FnOnce() -> Option, + F: ~const FnOnce() -> Option + ~const Destruct, + //FIXME(const_hack): this `T: ~const Destruct` is unnecessary, but even precise live drops can't tell + // no value of type `T` gets dropped here + T: ~const Destruct, { match self { x @ Some(_) => x, @@ -1634,7 +1671,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - pub fn xor(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn xor(self, optb: Option) -> Option + where + T: ~const Destruct, + { match (self, optb) { (a @ Some(_), None) => a, (None, b @ Some(_)) => b, @@ -1668,7 +1709,11 @@ impl Option { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - pub fn insert(&mut self, value: T) -> &mut T { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn insert(&mut self, value: T) -> &mut T + where + T: ~const Destruct, + { *self = Some(value); // SAFETY: the code above just filled the option @@ -1720,9 +1765,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_get_or_insert_default", since = "1.83.0")] - pub fn get_or_insert_default(&mut self) -> &mut T + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn get_or_insert_default(&mut self) -> &mut T where - T: Default, + T: ~const Default + ~const Destruct, { self.get_or_insert_with(T::default) } @@ -1746,9 +1792,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert_with(&mut self, f: F) -> &mut T + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn get_or_insert_with(&mut self, f: F) -> &mut T where - F: FnOnce() -> T, + F: ~const FnOnce() -> T + ~const Destruct, + T: ~const Destruct, { if let None = self { *self = Some(f()); @@ -1812,9 +1860,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_take_if", since = "1.80.0")] - pub fn take_if

(&mut self, predicate: P) -> Option + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn take_if

(&mut self, predicate: P) -> Option where - P: FnOnce(&mut T) -> bool, + P: ~const FnOnce(&mut T) -> bool + ~const Destruct, { if self.as_mut().map_or(false, predicate) { self.take() } else { None } } @@ -1859,7 +1908,12 @@ impl Option { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - pub fn zip(self, other: Option) -> Option<(T, U)> { + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn zip(self, other: Option) -> Option<(T, U)> + where + T: ~const Destruct, + U: ~const Destruct, + { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1895,9 +1949,12 @@ impl Option { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - pub fn zip_with(self, other: Option, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + pub const fn zip_with(self, other: Option, f: F) -> Option where - F: FnOnce(T, U) -> R, + F: ~const FnOnce(T, U) -> R + ~const Destruct, + T: ~const Destruct, + U: ~const Destruct, { match (self, other) { (Some(a), Some(b)) => Some(f(a, b)), From 2ca2d93035ecb4b7afab079329979262aae379a4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 17 Jul 2025 17:32:26 +0800 Subject: [PATCH 21/27] Auto-label `src/ci` and `.github/workflows` with `A-CI` And include `.github/workflows` for `T-infra` trigger files. --- triagebot.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2f8114aeb3b6b..cddb867c47157 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -471,6 +471,7 @@ trigger_files = [ [autolabel."T-infra"] trigger_files = [ + ".github/workflows", "src/ci", "src/tools/bump-stage0", "src/tools/cargotest", @@ -598,6 +599,12 @@ trigger_files = [ "src/tools/clippy", ] +[autolabel."A-CI"] +trigger_files = [ + ".github/workflows", + "src/ci", +] + # ------------------------------------------------------------------------------ # Prioritization and team nominations # ------------------------------------------------------------------------------ From 491b873d83052acb89d6b6ad5a5ab31d0a88a8c5 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 17 Jul 2025 17:33:44 +0800 Subject: [PATCH 22/27] Add myself to `infra-ci` reviewer group --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index cddb867c47157..61d8a814c89ee 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1323,6 +1323,7 @@ infra-ci = [ "@Kobzol", "@marcoieni", "@jdno", + "@jieyouxu", ] rustdoc = [ "@GuillaumeGomez", From f2048019718409885ac57c480f010bdfbfe5bfd0 Mon Sep 17 00:00:00 2001 From: codedump Date: Wed, 16 Jul 2025 23:21:47 +0800 Subject: [PATCH 23/27] fix: fix issue 143740, Wrong messages from compiler confusing methods with the same name from different traits --- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- ...all_method_without_import.no_import.stderr | 7 +--- .../no-method-suggested-traits.stderr | 8 ----- ...e-trait-object-with-separate-params.stderr | 16 ++------- tests/ui/methods/wrong-ambig-message.rs | 34 +++++++++++++++++++ tests/ui/methods/wrong-ambig-message.stderr | 30 ++++++++++++++++ 6 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 tests/ui/methods/wrong-ambig-message.rs create mode 100644 tests/ui/methods/wrong-ambig-message.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 94c93e7362749..d5ac17bd78586 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1649,7 +1649,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - let sources = candidates.iter().map(|p| self.candidate_source(p, self_ty)).collect(); + let sources = + applicable_candidates.iter().map(|p| self.candidate_source(p.0, self_ty)).collect(); return Some(Err(MethodError::Ambiguity(sources))); } diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr index e59409ea27e64..dbac74b224793 100644 --- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -22,15 +22,10 @@ LL | x.fmt(f); = help: items from traits can only be used if the trait is in scope help: the following traits which provide `fmt` are implemented but not in scope; perhaps you want to import one of them | -LL + use std::fmt::Binary; - | LL + use std::fmt::Debug; | -LL + use std::fmt::Display; - | -LL + use std::fmt::LowerExp; +LL + use std::fmt::Pointer; | - = and 5 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/no-method-suggested-traits.stderr b/tests/ui/impl-trait/no-method-suggested-traits.stderr index 061c9bd8f3501..b376f205411c6 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.stderr +++ b/tests/ui/impl-trait/no-method-suggested-traits.stderr @@ -9,12 +9,8 @@ help: the following traits which provide `method` are implemented but not in sco | LL + use foo::Bar; | -LL + use no_method_suggested_traits::Reexported; - | LL + use no_method_suggested_traits::foo::PubPub; | -LL + use no_method_suggested_traits::qux::PrivPub; - | help: there is a method `method2` with a similar name | LL | 1u32.method2(); @@ -31,12 +27,8 @@ help: the following traits which provide `method` are implemented but not in sco | LL + use foo::Bar; | -LL + use no_method_suggested_traits::Reexported; - | LL + use no_method_suggested_traits::foo::PubPub; | -LL + use no_method_suggested_traits::qux::PrivPub; - | help: there is a method `method2` with a similar name | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method2(); diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 32cff62284e09..aeecb82e9d910 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -20,17 +20,12 @@ error[E0034]: multiple applicable items in scope LL | let z = x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in the trait `FinalFoo` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:60:5 - | -LL | fn foo(&self) -> u8; - | ^^^^^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T` +note: candidate #1 is defined in an impl of the trait `NuisanceFoo` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:73:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ -note: candidate #3 is defined in an impl of the trait `X` for the type `T` +note: candidate #2 is defined in an impl of the trait `X` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:46:9 | LL | fn foo(self: Smaht) -> u64 { @@ -38,14 +33,9 @@ LL | fn foo(self: Smaht) -> u64 { help: disambiguate the method for candidate #1 | LL - let z = x.foo(); -LL + let z = FinalFoo::foo(&x); - | -help: disambiguate the method for candidate #2 - | -LL - let z = x.foo(); LL + let z = NuisanceFoo::foo(x); | -help: disambiguate the method for candidate #3 +help: disambiguate the method for candidate #2 | LL - let z = x.foo(); LL + let z = X::foo(x); diff --git a/tests/ui/methods/wrong-ambig-message.rs b/tests/ui/methods/wrong-ambig-message.rs new file mode 100644 index 0000000000000..f88d77e259d68 --- /dev/null +++ b/tests/ui/methods/wrong-ambig-message.rs @@ -0,0 +1,34 @@ +fn main() { + trait Hello { + fn name(&self) -> String; + } + + #[derive(Debug)] + struct Container2 { + val: String, + } + + trait AName2 { + fn name(&self) -> String; + } + + trait BName2 { + fn name(&self, v: bool) -> String; + } + + impl AName2 for Container2 { + fn name(&self) -> String { + "aname2".into() + } + } + + impl BName2 for Container2 { + fn name(&self, _v: bool) -> String { + "bname2".into() + } + } + + let c2 = Container2 { val: "abc".into() }; + println!("c2 = {:?}", c2.name()); + //~^ ERROR: multiple applicable items in scope +} diff --git a/tests/ui/methods/wrong-ambig-message.stderr b/tests/ui/methods/wrong-ambig-message.stderr new file mode 100644 index 0000000000000..9a254595e40bc --- /dev/null +++ b/tests/ui/methods/wrong-ambig-message.stderr @@ -0,0 +1,30 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/wrong-ambig-message.rs:32:30 + | +LL | println!("c2 = {:?}", c2.name()); + | ^^^^ multiple `name` found + | +note: candidate #1 is defined in an impl of the trait `AName2` for the type `Container2` + --> $DIR/wrong-ambig-message.rs:20:9 + | +LL | fn name(&self) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `BName2` for the type `Container2` + --> $DIR/wrong-ambig-message.rs:26:9 + | +LL | fn name(&self, _v: bool) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method for candidate #1 + | +LL - println!("c2 = {:?}", c2.name()); +LL + println!("c2 = {:?}", AName2::name(&c2)); + | +help: disambiguate the method for candidate #2 + | +LL - println!("c2 = {:?}", c2.name()); +LL + println!("c2 = {:?}", BName2::name(&c2)); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0034`. From a886852e23fad1be91648871b0240805fd52c13c Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:54:14 +0200 Subject: [PATCH 24/27] ci: use windows 22 for all free runners --- src/ci/github-actions/jobs.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 6c5e37b51ef23..f0c52fe3d1ca0 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -34,6 +34,8 @@ runners: os: windows-2022 <<: *base-job + # NOTE: windows-2025 has less disk space available than windows-2022, + # because the D drive is missing. - &job-windows-25 os: windows-2025 <<: *base-job @@ -542,13 +544,13 @@ auto: env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-py - <<: *job-windows-25 + <<: *job-windows - name: x86_64-msvc-2 env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-ps1 - <<: *job-windows-25 + <<: *job-windows # i686-msvc is split into two jobs to run tests in parallel. - name: i686-msvc-1 From 0a71873c34d38978121853f0d97358427bd54038 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 17 Jul 2025 14:12:03 +0000 Subject: [PATCH 25/27] panic_main.rs panic=unwind tests needs unwinding Only run the panic=unwind tests on platforms that support unwinding. --- tests/ui/panics/panic-main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui/panics/panic-main.rs b/tests/ui/panics/panic-main.rs index bf79de78a579c..2395f68241f5e 100644 --- a/tests/ui/panics/panic-main.rs +++ b/tests/ui/panics/panic-main.rs @@ -14,12 +14,15 @@ //@[unwind-zero] compile-flags: -Cpanic=unwind //@[unwind-zero] exec-env:RUST_BACKTRACE=0 +//@[unwind-zero] needs-unwind //@[unwind-one] compile-flags: -Cpanic=unwind //@[unwind-one] exec-env:RUST_BACKTRACE=1 +//@[unwind-one] needs-unwind //@[unwind-full] compile-flags: -Cpanic=unwind //@[unwind-full] exec-env:RUST_BACKTRACE=full +//@[unwind-full] needs-unwind //@ run-fail //@ error-pattern:moop From 10762d5001f6abe686b14bffb83e618ec8fa2bb6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:17:40 +0000 Subject: [PATCH 26/27] Fix debuginfo-lto-alloc.rs test This should have used build-pass rather than check-pass. --- tests/ui/lto/debuginfo-lto-alloc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ui/lto/debuginfo-lto-alloc.rs b/tests/ui/lto/debuginfo-lto-alloc.rs index 89043275329d1..d6855f8760d52 100644 --- a/tests/ui/lto/debuginfo-lto-alloc.rs +++ b/tests/ui/lto/debuginfo-lto-alloc.rs @@ -8,8 +8,9 @@ // This test reproduces the circumstances that caused the error to appear, and checks // that compilation is successful. -//@ check-pass +//@ build-pass //@ compile-flags: --test -C debuginfo=2 -C lto=fat +//@ no-prefer-dynamic //@ incremental extern crate alloc; From bf24c0dfa581bffed5e3627c2881e46cc76d4d93 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Jul 2025 22:12:26 +0200 Subject: [PATCH 27/27] miri sleep tests: increase slack --- src/tools/miri/tests/pass-dep/libc/libc-time.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-time.rs b/src/tools/miri/tests/pass-dep/libc/libc-time.rs index e8957846ad511..9e9fadfca9e7c 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-time.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-time.rs @@ -336,7 +336,7 @@ fn test_nanosleep() { let remainder = ptr::null_mut::(); let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) }; assert_eq!(is_error, 0); - assert!(start_test_sleep.elapsed() < Duration::from_millis(10)); + assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 }; @@ -390,7 +390,7 @@ mod test_clock_nanosleep { ) }; assert_eq!(error, 0); - assert!(start_test_sleep.elapsed() < Duration::from_millis(10)); + assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC)); @@ -417,7 +417,7 @@ mod test_clock_nanosleep { libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder) }; assert_eq!(error, 0); - assert!(start_test_sleep.elapsed() < Duration::from_millis(10)); + assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };