From 672828e07750eaf6cd55dde953272413cc64391e Mon Sep 17 00:00:00 2001 From: justanotheranonymoususer Date: Mon, 5 Jan 2026 17:55:54 +0200 Subject: [PATCH 01/12] Add missing mut to pin.rs docs Per my understanding, needed for mut access next line. --- library/core/src/pin.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 74ecb5ee4946f..e49faf9eddbdc 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -831,15 +831,13 @@ //! fn get_pin_mut(self: [Pin]<[`&mut Self`]>) -> [Pin]<[`&mut T`]>. //! Then we could do the following: //! ```compile_fail -//! # use std::cell::RefCell; -//! # use std::pin::Pin; -//! fn exploit_ref_cell(rc: Pin<&mut RefCell>) { +//! fn exploit_ref_cell(mut rc: Pin<&mut RefCell>) { //! // Here we get pinned access to the `T`. //! let _: Pin<&mut T> = rc.as_mut().get_pin_mut(); //! //! // And here we have `&mut T` to the same data. //! let shared: &RefCell = rc.into_ref().get_ref(); -//! let borrow = shared.borrow_mut(); +//! let mut borrow = shared.borrow_mut(); //! let content = &mut *borrow; //! } //! ``` From ee6dd56425125fde399c962f6a9f7c9a527616d0 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 22 Jan 2026 22:43:56 +0100 Subject: [PATCH 02/12] Add test for invalid `--remap-path-scope` arguments --- .../ui/compile-flags/invalid/remap-path-scope.foo.stderr | 2 ++ tests/ui/compile-flags/invalid/remap-path-scope.rs | 9 +++++++++ .../invalid/remap-path-scope.underscore.stderr | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr create mode 100644 tests/ui/compile-flags/invalid/remap-path-scope.rs create mode 100644 tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr b/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr new file mode 100644 index 0000000000000..dc72089e0d57b --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr @@ -0,0 +1,2 @@ +error: argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all` + diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.rs b/tests/ui/compile-flags/invalid/remap-path-scope.rs new file mode 100644 index 0000000000000..545c8c86cec78 --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.rs @@ -0,0 +1,9 @@ +// Error on invalid --remap-path-scope arguments + +//@ revisions: foo underscore +//@ [foo]compile-flags: --remap-path-scope=foo +//@ [underscore]compile-flags: --remap-path-scope=macro_object + +//~? ERROR argument for `--remap-path-scope + +fn main() {} diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr b/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr new file mode 100644 index 0000000000000..dc72089e0d57b --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr @@ -0,0 +1,2 @@ +error: argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all` + From 91e3e2a37f4a71dab6092e98785d54143fe8ca1f Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 22 Jan 2026 22:39:31 +0100 Subject: [PATCH 03/12] Add the remapping path `documentation` scope for rustdoc usage --- compiler/rustc_session/src/config.rs | 12 ++++++++-- compiler/rustc_span/src/lib.rs | 2 ++ src/doc/rustc/src/remap-source-paths.md | 2 +- tests/run-make/remap-path-prefix/rmake.rs | 24 +++++++++++++++++++ .../remap-path-scope-documentation.rs | 7 ++++++ .../remap-path-scope-documentation.stderr | 2 ++ 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tests/ui/feature-gates/remap-path-scope-documentation.rs create mode 100644 tests/ui/feature-gates/remap-path-scope-documentation.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 995dd5b29474a..5e2671ef4ef6b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1322,6 +1322,7 @@ impl OutputFilenames { pub(crate) fn parse_remap_path_scope( early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches, + unstable_opts: &UnstableOptions, ) -> RemapPathScopeComponents { if let Some(v) = matches.opt_str("remap-path-scope") { let mut slot = RemapPathScopeComponents::empty(); @@ -1329,11 +1330,18 @@ pub(crate) fn parse_remap_path_scope( slot |= match s { "macro" => RemapPathScopeComponents::MACRO, "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS, + "documentation" => { + if !unstable_opts.unstable_options { + early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified"); + } + + RemapPathScopeComponents::DOCUMENTATION + }, "debuginfo" => RemapPathScopeComponents::DEBUGINFO, "coverage" => RemapPathScopeComponents::COVERAGE, "object" => RemapPathScopeComponents::OBJECT, "all" => RemapPathScopeComponents::all(), - _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`"), + _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"), } } slot @@ -2677,7 +2685,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let externs = parse_externs(early_dcx, matches, &unstable_opts); let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts); - let remap_path_scope = parse_remap_path_scope(early_dcx, matches); + let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts); let pretty = parse_pretty(early_dcx, &unstable_opts); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 747cb2c17eb91..69f91cfab9e42 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -233,6 +233,8 @@ bitflags::bitflags! { const DEBUGINFO = 1 << 3; /// Apply remappings to coverage information const COVERAGE = 1 << 4; + /// Apply remappings to documentation information + const DOCUMENTATION = 1 << 5; /// An alias for `macro`, `debuginfo` and `coverage`. This ensures all paths in compiled /// executables, libraries and objects are remapped but not elsewhere. diff --git a/src/doc/rustc/src/remap-source-paths.md b/src/doc/rustc/src/remap-source-paths.md index 9912f353774be..1967981d5600a 100644 --- a/src/doc/rustc/src/remap-source-paths.md +++ b/src/doc/rustc/src/remap-source-paths.md @@ -52,7 +52,7 @@ The valid scopes are: - `debuginfo` - apply remappings to debug information - `coverage` - apply remappings to coverage information - `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,coverage,debuginfo`. -- `all` (default) - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`. +- `all` (default) - an alias for all of the above (and unstable scopes), also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`. The scopes accepted by `--remap-path-scope` are not exhaustive - new scopes may be added in future releases for eventual stabilisation. This implies that the `all` scope can correspond to different scopes between releases. diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index 22ffd4f1f0d19..3b866476e9501 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -12,7 +12,9 @@ fn main() { let mut out_simple = rustc(); let mut out_object = rustc(); let mut out_macro = rustc(); + let mut out_doc = rustc(); let mut out_diagobj = rustc(); + let mut out_diagdocobj = rustc(); out_simple .remap_path_prefix("auxiliary", "/the/aux") .crate_type("lib") @@ -28,11 +30,21 @@ fn main() { .crate_type("lib") .emit("metadata") .input("auxiliary/lib.rs"); + out_doc + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); out_diagobj .remap_path_prefix("auxiliary", "/the/aux") .crate_type("lib") .emit("metadata") .input("auxiliary/lib.rs"); + out_diagdocobj + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); out_simple.run(); rmeta_contains("/the/aux/lib.rs"); @@ -40,11 +52,17 @@ fn main() { out_object.arg("--remap-path-scope=object"); out_macro.arg("--remap-path-scope=macro"); + out_doc.arg("--remap-path-scope=documentation").arg("-Zunstable-options"); out_diagobj.arg("--remap-path-scope=diagnostics,object"); + out_diagdocobj + .arg("--remap-path-scope=diagnostics,documentation,object") + .arg("-Zunstable-options"); if is_darwin() { out_object.arg("-Csplit-debuginfo=off"); out_macro.arg("-Csplit-debuginfo=off"); + out_doc.arg("-Csplit-debuginfo=off"); out_diagobj.arg("-Csplit-debuginfo=off"); + out_diagdocobj.arg("-Csplit-debuginfo=off"); } out_object.run(); @@ -53,8 +71,14 @@ fn main() { out_macro.run(); rmeta_contains("/the/aux/lib.rs"); rmeta_contains("auxiliary"); + out_doc.run(); + rmeta_contains("/the/aux/lib.rs"); + rmeta_contains("auxiliary"); out_diagobj.run(); rmeta_contains("/the/aux/lib.rs"); + rmeta_contains("auxiliary"); + out_diagdocobj.run(); + rmeta_contains("/the/aux/lib.rs"); rmeta_not_contains("auxiliary"); } diff --git a/tests/ui/feature-gates/remap-path-scope-documentation.rs b/tests/ui/feature-gates/remap-path-scope-documentation.rs new file mode 100644 index 0000000000000..55610c0376285 --- /dev/null +++ b/tests/ui/feature-gates/remap-path-scope-documentation.rs @@ -0,0 +1,7 @@ +// Test that documentation scope is unstable + +//@ compile-flags: --remap-path-scope=documentation + +//~? ERROR remapping `documentation` path scope requested but `-Zunstable-options` not specified + +fn main() {} diff --git a/tests/ui/feature-gates/remap-path-scope-documentation.stderr b/tests/ui/feature-gates/remap-path-scope-documentation.stderr new file mode 100644 index 0000000000000..03316ad86a549 --- /dev/null +++ b/tests/ui/feature-gates/remap-path-scope-documentation.stderr @@ -0,0 +1,2 @@ +error: remapping `documentation` path scope requested but `-Zunstable-options` not specified + From fbab2c0e92608c93bb353622023fbe955aca44c8 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 22 Jan 2026 22:43:27 +0100 Subject: [PATCH 04/12] Make rustdoc use the documentation remapping scope and cleanups --- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/doctest.rs | 16 ++++++++++++---- src/librustdoc/doctest/extracted.rs | 3 ++- src/librustdoc/html/render/context.rs | 8 ++++++-- src/librustdoc/passes/calculate_doc_coverage.rs | 6 ++---- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 393e56256f74c..c145929534d97 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -152,7 +152,7 @@ impl ExternalCrate { FileName::Real(ref p) => { match p .local_path() - .or(Some(p.path(RemapPathScopeComponents::MACRO))) + .or(Some(p.path(RemapPathScopeComponents::DOCUMENTATION))) .unwrap() .parent() { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 25868e24ce164..6cd7d2c628d58 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -957,8 +957,10 @@ impl ScrapedDocTest { if !item_path.is_empty() { item_path.push(' '); } - let name = - format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionally()); + let name = format!( + "{} - {item_path}(line {line})", + filename.display(RemapPathScopeComponents::DOCUMENTATION) + ); Self { filename, line, langstr, text, name, span, global_crate_attrs } } @@ -969,9 +971,12 @@ impl ScrapedDocTest { fn no_run(&self, opts: &RustdocOptions) -> bool { self.langstr.no_run || opts.no_run } + fn path(&self) -> PathBuf { match &self.filename { - FileName::Real(name) => name.path(RemapPathScopeComponents::DIAGNOSTICS).to_path_buf(), + FileName::Real(name) => { + name.path(RemapPathScopeComponents::DOCUMENTATION).to_path_buf() + } _ => PathBuf::from(r"doctest.rs"), } } @@ -1016,9 +1021,12 @@ impl CreateRunnableDocTests { fn add_test(&mut self, scraped_test: ScrapedDocTest, dcx: Option>) { // For example `module/file.rs` would become `module_file_rs` + // + // Note that we are kind-of extending the definition of the MACRO scope here, but + // after all `#[doc]` is kind-of a macro. let file = scraped_test .filename - .prefer_local_unconditionally() + .display(RemapPathScopeComponents::MACRO) .to_string_lossy() .chars() .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' }) diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs index 3d046ec1835d1..a3eb03f7c839a 100644 --- a/src/librustdoc/doctest/extracted.rs +++ b/src/librustdoc/doctest/extracted.rs @@ -3,6 +3,7 @@ //! This module contains the logic to extract doctests and output a JSON containing this //! information. +use rustc_span::RemapPathScopeComponents; use rustc_span::edition::Edition; use serde::Serialize; @@ -62,7 +63,7 @@ impl ExtractedDocTests { Some(&opts.crate_name), ); self.doctests.push(ExtractedDocTest { - file: filename.prefer_remapped_unconditionally().to_string(), + file: filename.display(RemapPathScopeComponents::DOCUMENTATION).to_string(), line, doctest_attributes: langstr.into(), doctest_code: match wrapped { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 4d9e352595a1a..b0ea8776425f5 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -367,7 +367,7 @@ impl<'tcx> Context<'tcx> { let file = match span.filename(self.sess()) { FileName::Real(ref path) => path .local_path() - .unwrap_or(path.path(RemapPathScopeComponents::MACRO)) + .unwrap_or(path.path(RemapPathScopeComponents::DOCUMENTATION)) .to_path_buf(), _ => return None, }; @@ -503,7 +503,11 @@ impl<'tcx> Context<'tcx> { let src_root = match krate.src(tcx) { FileName::Real(ref p) => { - match p.local_path().unwrap_or(p.path(RemapPathScopeComponents::MACRO)).parent() { + match p + .local_path() + .unwrap_or(p.path(RemapPathScopeComponents::DOCUMENTATION)) + .parent() + { Some(p) => p.to_path_buf(), None => PathBuf::new(), } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 2782baae5e209..77b3a2e9c9f2e 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -124,7 +124,7 @@ impl CoverageCalculator<'_, '_> { &self .items .iter() - .map(|(k, v)| (k.prefer_local_unconditionally().to_string(), v)) + .map(|(k, v)| (k.display(RemapPathScopeComponents::COVERAGE).to_string(), v)) .collect::>(), ) .expect("failed to convert JSON data to string") @@ -168,9 +168,7 @@ impl CoverageCalculator<'_, '_> { if let Some(percentage) = count.percentage() { print_table_record( &limit_filename_len( - file.display(RemapPathScopeComponents::DIAGNOSTICS) - .to_string_lossy() - .into(), + file.display(RemapPathScopeComponents::COVERAGE).to_string(), ), count, percentage, From 3d6a5b51581ddd3532603001064d76eaae749ee8 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 24 Jan 2026 12:43:23 +0100 Subject: [PATCH 05/12] Make sure the `documentation` scope doesn't imply other scopes --- tests/ui/errors/auxiliary/file-doc.rs | 13 ++++++++++++ tests/ui/errors/auxiliary/trait-doc.rs | 4 ++++ ...prefix-diagnostics.only-doc-in-deps.stderr | 20 +++++++++++++++++++ .../errors/remap-path-prefix-diagnostics.rs | 19 +++++++++++++----- ...prefix-diagnostics.with-doc-in-deps.stderr | 20 +++++++++++++++++++ ...h-prefix-macro.only-doc-in-deps.run.stdout | 3 +++ tests/ui/errors/remap-path-prefix-macro.rs | 11 ++++++++-- ...h-prefix-macro.with-doc-in-deps.run.stdout | 3 +++ 8 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 tests/ui/errors/auxiliary/file-doc.rs create mode 100644 tests/ui/errors/auxiliary/trait-doc.rs create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-macro.only-doc-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.with-doc-in-deps.run.stdout diff --git a/tests/ui/errors/auxiliary/file-doc.rs b/tests/ui/errors/auxiliary/file-doc.rs new file mode 100644 index 0000000000000..4e9733bd5a1c0 --- /dev/null +++ b/tests/ui/errors/auxiliary/file-doc.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: --remap-path-scope=documentation -Zunstable-options + +#[macro_export] +macro_rules! my_file { + () => { + file!() + }; +} + +pub fn file() -> &'static str { + file!() +} diff --git a/tests/ui/errors/auxiliary/trait-doc.rs b/tests/ui/errors/auxiliary/trait-doc.rs new file mode 100644 index 0000000000000..451437de5f119 --- /dev/null +++ b/tests/ui/errors/auxiliary/trait-doc.rs @@ -0,0 +1,4 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: --remap-path-scope=documentation -Zunstable-options + +pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr new file mode 100644 index 0000000000000..e1b93a1042f57 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-doc-in-deps.stderr @@ -0,0 +1,20 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ unsatisfied trait bound + | +help: the trait `std::fmt::Display` is not implemented for `A` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | struct A; + | ^^^^^^^^ +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-doc.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.rs b/tests/ui/errors/remap-path-prefix-diagnostics.rs index 54dbcfd64711e..8976106ab3472 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.rs +++ b/tests/ui/errors/remap-path-prefix-diagnostics.rs @@ -3,26 +3,30 @@ // We test different combinations with/without remap in deps, with/without remap in this // crate but always in deps and always here but never in deps. -//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps -//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps +//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps with-doc-in-deps +//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps only-doc-in-deps //@ revisions: not-diag-in-deps //@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-doc-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics //@[with-macro-in-deps] compile-flags: --remap-path-scope=macro //@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo +//@[with-doc-in-deps] compile-flags: --remap-path-scope=documentation -Zunstable-options //@[not-diag-in-deps] compile-flags: --remap-path-scope=diagnostics //@[with-diag-in-deps] aux-build:trait-diag.rs //@[with-macro-in-deps] aux-build:trait-macro.rs //@[with-debuginfo-in-deps] aux-build:trait-debuginfo.rs +//@[with-doc-in-deps] aux-build:trait-doc.rs //@[only-diag-in-deps] aux-build:trait-diag.rs //@[only-macro-in-deps] aux-build:trait-macro.rs //@[only-debuginfo-in-deps] aux-build:trait-debuginfo.rs +//@[only-doc-in-deps] aux-build:trait-doc.rs //@[not-diag-in-deps] aux-build:trait.rs // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically @@ -39,6 +43,9 @@ extern crate trait_macro as r#trait; #[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))] extern crate trait_debuginfo as r#trait; +#[cfg(any(with_doc_in_deps, only_doc_in_deps))] +extern crate trait_doc as r#trait; + #[cfg(not_diag_in_deps)] extern crate r#trait as r#trait; @@ -47,9 +54,11 @@ struct A; impl r#trait::Trait for A {} //[with-macro-in-deps]~^ ERROR `A` doesn't implement `std::fmt::Display` //[with-debuginfo-in-deps]~^^ ERROR `A` doesn't implement `std::fmt::Display` -//[only-diag-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display` -//[only-macro-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display` -//[only-debuginfo-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[with-doc-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-diag-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-macro-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-debuginfo-in-deps]~^^^^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-doc-in-deps]~^^^^^^^ ERROR `A` doesn't implement `std::fmt::Display` //[with-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display` //[not-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display` diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr new file mode 100644 index 0000000000000..e1b93a1042f57 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-doc-in-deps.stderr @@ -0,0 +1,20 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ unsatisfied trait bound + | +help: the trait `std::fmt::Display` is not implemented for `A` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | struct A; + | ^^^^^^^^ +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-doc.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-macro.only-doc-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-doc-in-deps.run.stdout new file mode 100644 index 0000000000000..0026efdb7e582 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.only-doc-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-doc.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.rs b/tests/ui/errors/remap-path-prefix-macro.rs index 1f895aeeb6b4d..89e2379b575c4 100644 --- a/tests/ui/errors/remap-path-prefix-macro.rs +++ b/tests/ui/errors/remap-path-prefix-macro.rs @@ -6,26 +6,30 @@ //@ run-pass //@ check-run-results -//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps -//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps +//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps with-doc-in-deps +//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps only-doc-in-deps //@ revisions: not-macro-in-deps //@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-doc-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics //@[with-macro-in-deps] compile-flags: --remap-path-scope=macro //@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo +//@[with-doc-in-deps] compile-flags: --remap-path-scope=documentation -Zunstable-options //@[not-macro-in-deps] compile-flags: --remap-path-scope=macro //@[with-diag-in-deps] aux-build:file-diag.rs //@[with-macro-in-deps] aux-build:file-macro.rs //@[with-debuginfo-in-deps] aux-build:file-debuginfo.rs +//@[with-doc-in-deps] aux-build:file-doc.rs //@[only-diag-in-deps] aux-build:file-diag.rs //@[only-macro-in-deps] aux-build:file-macro.rs //@[only-debuginfo-in-deps] aux-build:file-debuginfo.rs +//@[only-doc-in-deps] aux-build:file-doc.rs //@[not-macro-in-deps] aux-build:file.rs #[cfg(any(with_diag_in_deps, only_diag_in_deps))] @@ -37,6 +41,9 @@ extern crate file_macro as file; #[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))] extern crate file_debuginfo as file; +#[cfg(any(with_doc_in_deps, only_doc_in_deps))] +extern crate file_doc as file; + #[cfg(not_macro_in_deps)] extern crate file; diff --git a/tests/ui/errors/remap-path-prefix-macro.with-doc-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-doc-in-deps.run.stdout new file mode 100644 index 0000000000000..0026efdb7e582 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.with-doc-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-doc.rs +file!() = $DIR/remap-path-prefix-macro.rs From dd84a4fc0fa88f9cbd2d0cce804037a5492d23ad Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 24 Jan 2026 13:59:48 +0100 Subject: [PATCH 06/12] Add documentation for `--remap-path-prefix` and `doc` scope in rustdoc --- src/doc/rustdoc/src/unstable-features.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 08465ea541b80..ae007c4c13bb5 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -751,6 +751,22 @@ pass `--doctest-build-arg ARG` for each argument `ARG`. This flag enables the generation of toggles to expand macros in the HTML source code pages. +## `--remap-path-prefix`: Remap source code paths in output + +This flag is the equivalent flag from `rustc` `--remap-path-prefix`. + +it permits remapping source path prefixes in all output, including compiler diagnostics, +debug information, macro expansions, etc. It takes a value of the form `FROM=TO` +where a path prefix equal to `FROM` is rewritten to the value `TO`. + +### `documentation` scope + +`rustdoc` (and by extension `rustc`) have a special `documentation` remapping scope, it +permits remapping source paths that ends up in the generated documentation. + +Currently the scope can only be specified from `rustc`, due to the lack of an equivalent +`--remap-path-scope` flag in `rustc`. + ## `#[doc(cfg)]` and `#[doc(auto_cfg)]` This feature aims at providing rustdoc users the possibility to add visual markers to the rendered documentation to know under which conditions an item is available (currently possible through the following unstable feature: `doc_cfg`). From a72f68e80154a208b85a3b80cea744b84b7b5d18 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sat, 24 Jan 2026 20:05:01 +0100 Subject: [PATCH 07/12] Fix is_ascii performance on x86_64 with explicit SSE2 intrinsics Use explicit SSE2 intrinsics to avoid LLVM's broken AVX-512 auto-vectorization which generates ~31 kshiftrd instructions. Performance - AVX-512: 34-48x faster - SSE2: 1.5-2x faster Improves on earlier pr --- library/core/src/slice/ascii.rs | 61 +++++++++------------------ tests/assembly-llvm/slice-is-ascii.rs | 5 +++ 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 459c826f40646..de89d77e5e2ce 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -460,56 +460,37 @@ const fn is_ascii(s: &[u8]) -> bool { ) } -/// Chunk size for vectorized ASCII checking (two 16-byte SSE registers). +/// Chunk size for SSE2 vectorized ASCII checking (4x 16-byte loads). #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] -const CHUNK_SIZE: usize = 32; +const SSE2_CHUNK_SIZE: usize = 64; -/// SSE2 implementation using `_mm_movemask_epi8` (compiles to `pmovmskb`) to -/// avoid LLVM's broken AVX-512 auto-vectorization of counting loops. -/// -/// FIXME(llvm#176906): Remove this workaround once LLVM generates efficient code. #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] fn is_ascii_sse2(bytes: &[u8]) -> bool { use crate::arch::x86_64::{__m128i, _mm_loadu_si128, _mm_movemask_epi8, _mm_or_si128}; - let mut i = 0; - - while i + CHUNK_SIZE <= bytes.len() { - // SAFETY: We have verified that `i + CHUNK_SIZE <= bytes.len()`. - let ptr = unsafe { bytes.as_ptr().add(i) }; - - // Load two 16-byte chunks and combine them. - // SAFETY: We verified `i + 32 <= len`, so ptr is valid for 32 bytes. - // `_mm_loadu_si128` allows unaligned loads. - let chunk1 = unsafe { _mm_loadu_si128(ptr as *const __m128i) }; - // SAFETY: Same as above - ptr.add(16) is within the valid 32-byte range. - let chunk2 = unsafe { _mm_loadu_si128(ptr.add(16) as *const __m128i) }; - - // OR them together - if any byte has the high bit set, the result will too. - // SAFETY: SSE2 is guaranteed by the cfg predicate. - let combined = unsafe { _mm_or_si128(chunk1, chunk2) }; - - // Create a mask from the MSBs of each byte. - // If any byte is >= 128, its MSB is 1, so the mask will be non-zero. - // SAFETY: SSE2 is guaranteed by the cfg predicate. - let mask = unsafe { _mm_movemask_epi8(combined) }; - + let (chunks, rest) = bytes.as_chunks::(); + + for chunk in chunks { + let ptr = chunk.as_ptr(); + // SAFETY: chunk is 64 bytes. SSE2 is baseline on x86_64. + let mask = unsafe { + let a1 = _mm_loadu_si128(ptr as *const __m128i); + let a2 = _mm_loadu_si128(ptr.add(16) as *const __m128i); + let b1 = _mm_loadu_si128(ptr.add(32) as *const __m128i); + let b2 = _mm_loadu_si128(ptr.add(48) as *const __m128i); + // OR all chunks - if any byte has high bit set, combined will too. + let combined = _mm_or_si128(_mm_or_si128(a1, a2), _mm_or_si128(b1, b2)); + // Create a mask from the MSBs of each byte. + // If any byte is >= 128, its MSB is 1, so the mask will be non-zero. + _mm_movemask_epi8(combined) + }; if mask != 0 { return false; } - - i += CHUNK_SIZE; - } - - // Handle remaining bytes with simple loop - while i < bytes.len() { - if !bytes[i].is_ascii() { - return false; - } - i += 1; } - true + // Handle remaining bytes + rest.iter().all(|b| b.is_ascii()) } /// ASCII test optimized to use the `pmovmskb` instruction on `x86-64`. @@ -529,7 +510,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { is_ascii_simple(bytes) } else { // For small inputs, use usize-at-a-time processing to avoid SSE2 call overhead. - if bytes.len() < CHUNK_SIZE { + if bytes.len() < SSE2_CHUNK_SIZE { let chunks = bytes.chunks_exact(USIZE_SIZE); let remainder = chunks.remainder(); for chunk in chunks { diff --git a/tests/assembly-llvm/slice-is-ascii.rs b/tests/assembly-llvm/slice-is-ascii.rs index d01b321bf460a..3b782ab2cd827 100644 --- a/tests/assembly-llvm/slice-is-ascii.rs +++ b/tests/assembly-llvm/slice-is-ascii.rs @@ -22,6 +22,11 @@ // X86_64-LABEL: test_is_ascii // X86_64-NOT: kshiftrd // X86_64-NOT: kshiftrq +// Verify explicit SSE2/AVX intrinsics are used: +// - pmovmskb/vpmovmskb: efficient mask extraction from the MSBs +// - vpor/por: OR-combining of 4x 16-byte loads (2x unrolled, 64-byte chunks) +// X86_64: {{vpmovmskb|pmovmskb}} +// X86_64: {{vpor|por}} // LA64-LABEL: test_is_ascii // LA64: vmskltz.b From 9e80b1ba7e751a8e16ce2ef1286278b3e66f728b Mon Sep 17 00:00:00 2001 From: zakie Date: Sun, 25 Jan 2026 17:24:08 +0900 Subject: [PATCH 08/12] Fix broken WASIp1 reference link --- src/doc/rustc/src/platform-support/wasm32-wasip1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 958a34a86928c..eb74edda22de8 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -20,7 +20,7 @@ focused on the Component Model-based definition of WASI. At this point the `wasm32-wasip1` Rust target is intended for historical compatibility with [WASIp1] set of syscalls. -[WASIp1]: https://github.com/WebAssembly/WASI/tree/main/legacy/preview1 +[WASIp1]: https://github.com/WebAssembly/WASI/tree/wasi-0.1/preview1 [Component Model]: https://github.com/webassembly/component-model Today the `wasm32-wasip1` target will generate core WebAssembly modules From cbcd8694c6e549c658901f010644fddcb7ffbce8 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sun, 25 Jan 2026 09:44:04 +0100 Subject: [PATCH 09/12] Remove x86_64 assembly test for is_ascii The SSE2 helper function is not inlined across crate boundaries, so we cannot verify the codegen in an assembly test. The fix is still verified by the absence of performance regression. --- tests/assembly-llvm/slice-is-ascii.rs | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/tests/assembly-llvm/slice-is-ascii.rs b/tests/assembly-llvm/slice-is-ascii.rs index 3b782ab2cd827..00deb23e9a6cd 100644 --- a/tests/assembly-llvm/slice-is-ascii.rs +++ b/tests/assembly-llvm/slice-is-ascii.rs @@ -1,32 +1,12 @@ -//@ revisions: X86_64 LA64 +//@ revisions: LA64 //@ assembly-output: emit-asm //@ compile-flags: -C opt-level=3 // -//@ [X86_64] only-x86_64 -//@ [X86_64] compile-flags: -C target-cpu=znver4 -//@ [X86_64] compile-flags: -C llvm-args=-x86-asm-syntax=intel -// //@ [LA64] only-loongarch64 #![crate_type = "lib"] -/// Verify `is_ascii` generates efficient code on different architectures: -/// -/// - x86_64: Must NOT use `kshiftrd`/`kshiftrq` (broken AVX-512 auto-vectorization). -/// The fix uses explicit SSE2 intrinsics (`pmovmskb`/`vpmovmskb`). -/// See: https://github.com/llvm/llvm-project/issues/176906 -/// /// - loongarch64: Should use `vmskltz.b` instruction for the fast-path. -/// This architecture still relies on LLVM auto-vectorization. - -// X86_64-LABEL: test_is_ascii -// X86_64-NOT: kshiftrd -// X86_64-NOT: kshiftrq -// Verify explicit SSE2/AVX intrinsics are used: -// - pmovmskb/vpmovmskb: efficient mask extraction from the MSBs -// - vpor/por: OR-combining of 4x 16-byte loads (2x unrolled, 64-byte chunks) -// X86_64: {{vpmovmskb|pmovmskb}} -// X86_64: {{vpor|por}} // LA64-LABEL: test_is_ascii // LA64: vmskltz.b From 36fb9f08293b182ee213ed9d64d53da12387da4b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Jan 2026 16:12:13 +0100 Subject: [PATCH 10/12] Update `sysinfo` version to `0.38.0` --- Cargo.lock | 81 +++++++++++++++---- src/bootstrap/Cargo.lock | 142 +++++++++++++++++++++++++++------- src/bootstrap/Cargo.toml | 2 +- src/tools/opt-dist/Cargo.toml | 2 +- 4 files changed, 183 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1bc531ba916c0..41cce3d54ddbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -857,7 +857,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows", + "windows 0.61.3", ] [[package]] @@ -2038,7 +2038,7 @@ dependencies = [ "serde", "tempfile", "uuid", - "windows", + "windows 0.61.3", ] [[package]] @@ -3698,7 +3698,7 @@ dependencies = [ "thorin-dwp", "tracing", "wasm-encoder 0.219.2", - "windows", + "windows 0.61.3", ] [[package]] @@ -3756,7 +3756,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows", + "windows 0.61.3", ] [[package]] @@ -3822,7 +3822,7 @@ dependencies = [ "serde_json", "shlex", "tracing", - "windows", + "windows 0.61.3", ] [[package]] @@ -3873,7 +3873,7 @@ dependencies = [ "serde_json", "termize", "tracing", - "windows", + "windows 0.61.3", ] [[package]] @@ -4664,7 +4664,7 @@ dependencies = [ "rustc_target", "termize", "tracing", - "windows", + "windows 0.61.3", ] [[package]] @@ -5438,14 +5438,14 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.37.2" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" +checksum = "fe840c5b1afe259a5657392a4dbb74473a14c8db999c3ec2f4ae812e028a94da" dependencies = [ "libc", "objc2-core-foundation", "objc2-io-kit", - "windows", + "windows 0.62.2", ] [[package]] @@ -6398,11 +6398,23 @@ version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections", + "windows-collections 0.2.0", "windows-core 0.61.2", - "windows-future", + "windows-future 0.2.1", "windows-link 0.1.3", - "windows-numerics", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] @@ -6413,7 +6425,7 @@ checksum = "9b4e97b01190d32f268a2dfbd3f006f77840633746707fbe40bcee588108a231" dependencies = [ "serde", "serde_json", - "windows-threading", + "windows-threading 0.1.0", ] [[package]] @@ -6425,6 +6437,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + [[package]] name = "windows-core" version = "0.61.2" @@ -6459,7 +6480,18 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", ] [[package]] @@ -6506,6 +6538,16 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -6611,6 +6653,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 884f67e91e681..960f003992fb9 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ "tracing-chrome", "tracing-subscriber", "walkdir", - "windows", + "windows 0.61.1", "xz2", ] @@ -472,18 +472,18 @@ dependencies = [ [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags", ] [[package]] name = "objc2-io-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" dependencies = [ "libc", "objc2-core-foundation", @@ -743,16 +743,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cec4dc2d2e357ca1e610cfb07de2fa7a10fc3e9fe89f72545f3d244ea87753" +checksum = "fe840c5b1afe259a5657392a4dbb74473a14c8db999c3ec2f4ae812e028a94da" dependencies = [ "libc", "memchr", "ntapi", "objc2-core-foundation", "objc2-io-kit", - "windows", + "windows 0.62.2", ] [[package]] @@ -958,11 +958,23 @@ version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-link", - "windows-numerics", + "windows-collections 0.2.0", + "windows-core 0.61.0", + "windows-future 0.2.0", + "windows-link 0.1.1", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] @@ -971,7 +983,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.0", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", ] [[package]] @@ -982,9 +1003,22 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.1", + "windows-result 0.3.2", + "windows-strings 0.4.0", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -993,15 +1027,26 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.0", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1010,9 +1055,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1025,14 +1070,30 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.0", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", ] [[package]] @@ -1041,7 +1102,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-link", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -1050,7 +1120,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ - "windows-link", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -1103,6 +1182,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index e66c0576e9ee5..008e0d37642b7 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -57,7 +57,7 @@ walkdir = "2.4" xz2 = "0.1" # Dependencies needed by the build-metrics feature -sysinfo = { version = "0.37.0", default-features = false, optional = true, features = ["system"] } +sysinfo = { version = "0.38.0", default-features = false, optional = true, features = ["system"] } # Dependencies needed by the `tracing` feature chrono = { version = "0.4", default-features = false, optional = true, features = ["now", "std"] } diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index 66c19183f3433..9ca1729e2e8b5 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -10,7 +10,7 @@ log = "0.4" anyhow = "1" humantime = "2" humansize = "2" -sysinfo = { version = "0.37.0", default-features = false, features = ["disk"] } +sysinfo = { version = "0.38.0", default-features = false, features = ["disk"] } fs_extra = "1" camino = "1" tar = "0.4" From dbc870afec91308b2e6a6c6ba16e8f3bb085e338 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sun, 25 Jan 2026 20:03:32 +0100 Subject: [PATCH 11/12] Mark is_ascii_sse2 as #[inline] --- library/core/src/slice/ascii.rs | 1 + tests/assembly-llvm/slice-is-ascii.rs | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index de89d77e5e2ce..ae641871279b6 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -465,6 +465,7 @@ const fn is_ascii(s: &[u8]) -> bool { const SSE2_CHUNK_SIZE: usize = 64; #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[inline] fn is_ascii_sse2(bytes: &[u8]) -> bool { use crate::arch::x86_64::{__m128i, _mm_loadu_si128, _mm_movemask_epi8, _mm_or_si128}; diff --git a/tests/assembly-llvm/slice-is-ascii.rs b/tests/assembly-llvm/slice-is-ascii.rs index 00deb23e9a6cd..b9a5205054986 100644 --- a/tests/assembly-llvm/slice-is-ascii.rs +++ b/tests/assembly-llvm/slice-is-ascii.rs @@ -1,13 +1,28 @@ -//@ revisions: LA64 +//@ revisions: X86_64 LA64 //@ assembly-output: emit-asm //@ compile-flags: -C opt-level=3 // +//@ [X86_64] only-x86_64 +//@ [X86_64] compile-flags: -C target-cpu=znver4 +//@ [X86_64] compile-flags: -C llvm-args=-x86-asm-syntax=intel +// //@ [LA64] only-loongarch64 #![crate_type = "lib"] +/// Verify `is_ascii` generates efficient code on different architectures: +/// +/// - x86_64: Must NOT use `kshiftrd`/`kshiftrq` (broken AVX-512 auto-vectorization). +/// Good version uses explicit SSE2 intrinsics (`pmovmskb`/`vpmovmskb`). +/// /// - loongarch64: Should use `vmskltz.b` instruction for the fast-path. +// X86_64-LABEL: test_is_ascii +// X86_64-NOT: kshiftrd +// X86_64-NOT: kshiftrq +// X86_64: {{vpor|por}} +// X86_64: {{vpmovmskb|pmovmskb}} + // LA64-LABEL: test_is_ascii // LA64: vmskltz.b From 841d78181e9e8e93193e038614d5c0a04fcb6210 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 18 Jan 2026 18:29:13 +0800 Subject: [PATCH 12/12] compiletest: implied `needs-target-std` directive for `codegen` mode tests by default A `codegen-llvm` test (and other codegen test mode tests) will now by default have an implied `//@ needs-target-std` directive, *unless* the test explicitly has an `#![no_std]`/`#![no_core]` attribute which disables this implied behavior. - When a test has both `#![no_std]`/`#![no_core]` and `//@ needs-target-std`, the explicit `//@ needs-target-std` directive will cause the test to be ignored for targets that do not support std still. This is to make it easier to test out-of-tree targets / custom targets (and targets not tested in r-l/r CI) without requiring target maintainers to do a bunch of manual `//@ needs-target-std` busywork. Co-authored-by: Edoardo Marangoni --- .../rustc-dev-guide/src/tests/compiletest.md | 10 +- .../rustc-dev-guide/src/tests/directives.md | 2 + src/tools/compiletest/src/directives.rs | 15 ++- src/tools/compiletest/src/directives/file.rs | 19 +++- src/tools/compiletest/src/directives/tests.rs | 96 ++++++++++++++++++- 5 files changed, 137 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 91a09db7009bd..64276a9ea451a 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -311,14 +311,20 @@ For example, `./x test tests/debuginfo -- --debugger gdb` will only test GDB com ### Codegen tests -The tests in [`tests/codegen-llvm`] test LLVM code generation. They compile the test -with the `--emit=llvm-ir` flag to emit LLVM IR. They then run the LLVM +The tests in [`tests/codegen-llvm`] test LLVM code generation. They compile the +test with the `--emit=llvm-ir` flag to emit LLVM IR. They then run the LLVM [FileCheck] tool. The test is annotated with various `// CHECK` comments to check the generated code. See the [FileCheck] documentation for a tutorial and more information. See also the [assembly tests](#assembly-tests) for a similar set of tests. +By default, codegen tests will have `//@ needs-target-std` *implied* (that the +target needs to support std), *unless* the `#![no_std]`/`#![no_core]` attribute +was specified in the test source. You can override this behavior and explicitly +write `//@ needs-target-std` to only run the test when target supports std, even +if the test is `#![no_std]`/`#![no_core]`. + If you need to work with `#![no_std]` cross-compiling tests, consult the [`minicore` test auxiliary](./minicore.md) chapter. diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 81c421bc92c44..08371a779e117 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -200,6 +200,8 @@ The following directives will check rustc build settings and target settings: on `wasm32-unknown-unknown` target because the target does not support the `proc-macro` crate type. - `needs-target-std` — ignores if target platform does not have std support. + - See also [`#![no_std]`/`#![no_core]` and implied `needs-target-std` for + codegen tests](./compiletest.md#codegen-tests). - `ignore-backends` — ignores the listed backends, separated by whitespace characters. Please note that this directive can be overriden with the `--bypass-ignore-backends=[BACKEND]` command line diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 0263b91f50b80..462d9ae626b0a 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -206,7 +206,7 @@ pub(crate) struct TestProps { pub add_minicore: bool, /// Add these flags to the build of `minicore`. pub minicore_compile_flags: Vec, - /// Whether line annotatins are required for the given error kind. + /// Whether line annotations are required for the given error kind. pub dont_require_annotations: HashSet, /// Whether pretty printers should be disabled in gdb. pub disable_gdb_pretty_printers: bool, @@ -600,6 +600,19 @@ fn iter_directives( } } + // Note: affects all codegen test suites under test mode `codegen`, e.g. `codegen-llvm`. + // + // Codegen tests automatically receive implied `//@ needs-target-std`, unless + // `#![no_std]`/`#![no_core]` attribute was explicitly seen. The rationale is basically to avoid + // having to manually maintain a bunch of `//@ needs-target-std` directives esp. for targets + // tested/built out-of-tree. + if mode == TestMode::Codegen && !file_directives.has_explicit_no_std_core_attribute { + let implied_needs_target_std_line = + line_directive(testfile, LineNumber::ZERO, "//@ needs-target-std") + .expect("valid `needs-target-std` directive line"); + it(&implied_needs_target_std_line); + } + for directive_line in &file_directives.lines { it(directive_line); } diff --git a/src/tools/compiletest/src/directives/file.rs b/src/tools/compiletest/src/directives/file.rs index 57186faa56b87..bde935729121f 100644 --- a/src/tools/compiletest/src/directives/file.rs +++ b/src/tools/compiletest/src/directives/file.rs @@ -6,20 +6,37 @@ use crate::directives::line::{DirectiveLine, line_directive}; pub(crate) struct FileDirectives<'a> { pub(crate) path: &'a Utf8Path, pub(crate) lines: Vec>, + + /// Whether the test source file contains an explicit `#![no_std]`/`#![no_core]` attribute. + pub(crate) has_explicit_no_std_core_attribute: bool, } impl<'a> FileDirectives<'a> { pub(crate) fn from_file_contents(path: &'a Utf8Path, file_contents: &'a str) -> Self { let mut lines = vec![]; + let mut has_explicit_no_std_core_attribute = false; for (line_number, ln) in LineNumber::enumerate().zip(file_contents.lines()) { let ln = ln.trim(); + // Perform a naive check for lines starting with `#![no_std]`/`#![no_core]`, which + // suppresses the implied `//@ needs-target-std` in codegen tests. This ignores + // occurrences in ordinary comments. + // + // This check is imperfect in some edge cases, but we can generally trust our own test + // suite to not hit those edge cases (e.g. `#![no_std]`/`#![no_core]` in multi-line + // comments or string literals). Tests can write `//@ needs-target-std` manually if + // needed. + if ln.starts_with("#![no_std]") || ln.starts_with("#![no_core]") { + has_explicit_no_std_core_attribute = true; + continue; + } + if let Some(directive_line) = line_directive(path, line_number, ln) { lines.push(directive_line); } } - Self { path, lines } + Self { path, lines, has_explicit_no_std_core_attribute } } } diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 21d1940d56737..4cd75fcfa511a 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -105,6 +105,7 @@ fn test_parse_normalize_rule() { #[derive(Default)] struct ConfigBuilder { mode: Option, + suite: Option, channel: Option, edition: Option, host: Option, @@ -126,6 +127,11 @@ impl ConfigBuilder { self } + fn suite(&mut self, s: &str) -> &mut Self { + self.suite = Some(s.to_owned()); + self + } + fn channel(&mut self, s: &str) -> &mut Self { self.channel = Some(s.to_owned()); self @@ -196,7 +202,8 @@ impl ConfigBuilder { "compiletest", "--mode", self.mode.as_deref().unwrap_or("ui"), - "--suite=ui", + "--suite", + self.suite.as_deref().unwrap_or("ui"), "--compile-lib-path=", "--run-lib-path=", "--python=", @@ -1019,6 +1026,93 @@ fn test_needs_target_std() { assert!(!check_ignore(&config, "//@ needs-target-std")); } +#[test] +fn implied_needs_target_std() { + let config = cfg().mode("codegen").suite("codegen-llvm").target("x86_64-unknown-none").build(); + // Implied `needs-target-std` due to no `#![no_std]`/`#![no_core]`. + assert!(check_ignore(&config, "")); + assert!(check_ignore(&config, "//@ needs-target-std")); + assert!(!check_ignore(&config, "#![no_std]")); + assert!(!check_ignore(&config, "#![no_core]")); + // Make sure that `//@ needs-target-std` takes precedence. + assert!(check_ignore( + &config, + r#" + //@ needs-target-std + #![no_std] + "# + )); + assert!(check_ignore( + &config, + r#" + //@ needs-target-std + #![no_core] + "# + )); + + let config = + cfg().mode("codegen").suite("codegen-llvm").target("x86_64-unknown-linux-gnu").build(); + assert!(!check_ignore(&config, "")); + assert!(!check_ignore(&config, "//@ needs-target-std")); + assert!(!check_ignore(&config, "#![no_std]")); + assert!(!check_ignore(&config, "#![no_core]")); + assert!(!check_ignore( + &config, + r#" + //@ needs-target-std + #![no_std] + "# + )); + assert!(!check_ignore( + &config, + r#" + //@ needs-target-std + #![no_core] + "# + )); + + let config = cfg().mode("ui").suite("ui").target("x86_64-unknown-none").build(); + // The implied `//@ needs-target-std` is only applicable for mode=codegen tests. + assert!(!check_ignore(&config, "")); + assert!(check_ignore(&config, "//@ needs-target-std")); + assert!(!check_ignore(&config, "#![no_std]")); + assert!(!check_ignore(&config, "#![no_core]")); + assert!(check_ignore( + &config, + r#" + //@ needs-target-std + #![no_std] + "# + )); + assert!(check_ignore( + &config, + r#" + //@ needs-target-std + #![no_core] + "# + )); + + let config = cfg().mode("ui").suite("ui").target("x86_64-unknown-linux-gnu").build(); + assert!(!check_ignore(&config, "")); + assert!(!check_ignore(&config, "//@ needs-target-std")); + assert!(!check_ignore(&config, "#![no_std]")); + assert!(!check_ignore(&config, "#![no_core]")); + assert!(!check_ignore( + &config, + r#" + //@ needs-target-std + #![no_std] + "# + )); + assert!(!check_ignore( + &config, + r#" + //@ needs-target-std + #![no_core] + "# + )); +} + fn parse_edition_range(line: &str) -> Option { let config = cfg().build();