From 876f11bbaf8720b779c8d1e5e03b1f5fc68cb0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 5 Sep 2026 13:01:53 +0200 Subject: [PATCH 1/6] Do not execute `llvm-config` in the `FileCheck` step when cross-compiling --- src/bootstrap/src/core/build_steps/llvm.rs | 49 ++++++++++++---------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index f1864c736ed03..abd3465f67235 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -2231,30 +2231,37 @@ impl Step for FileCheck { }; // There is a LLVM config set, take filecheck from it - // Note: because `download-ci-llvm` currently overrides `llvm-config`, when the LLVM is - // downloaded, we go through this branch. Ideally, this should be changed so that - // `download-ci-llvm` doesn't override the config. - if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { - let llvm_bindir = command(s).arg("--bindir").run_capture_stdout(builder).stdout(); - let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", self.target)); - let filecheck = if filecheck.exists() { + if let Some(llvm_config) = target_config.and_then(|c| c.llvm_config.as_ref()) { + // We can only execute llvm-config if we're on the same host target + return if builder.is_host_target(self.target) { + let llvm_bindir = + command(llvm_config).arg("--bindir").run_capture_stdout(builder).stdout(); + let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", self.target)); + let filecheck = if filecheck.exists() { + filecheck + } else { + // On Fedora the system LLVM installs FileCheck in the + // llvm subdirectory of the libdir. + let llvm_libdir = + command(llvm_config).arg("--libdir").run_capture_stdout(builder).stdout(); + let lib_filecheck = Path::new(llvm_libdir.trim()) + .join("llvm") + .join(exe("FileCheck", self.target)); + if lib_filecheck.exists() { + lib_filecheck + } else { + // Return the most normal file name, even though + // it doesn't exist, so that any error message + // refers to that. + filecheck + } + }; filecheck } else { - // On Fedora the system LLVM installs FileCheck in the - // llvm subdirectory of the libdir. - let llvm_libdir = command(s).arg("--libdir").run_capture_stdout(builder).stdout(); - let lib_filecheck = - Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", self.target)); - if lib_filecheck.exists() { - lib_filecheck - } else { - // Return the most normal file name, even though - // it doesn't exist, so that any error message - // refers to that. - filecheck - } + // In other cases, just guess that Filecheck is available in the same directory + // as the llvm-config + llvm_config.parent().unwrap().join(exe("FileCheck", self.target)) }; - return filecheck; } // Here we take the filecheck from LLVM directly let llvm_output = builder.ensure(Llvm { target: self.target }); From d4e6b8f2460d08f8028c71e5383a6300eaec1a9f Mon Sep 17 00:00:00 2001 From: malezjaa Date: Sun, 6 Sep 2026 20:17:40 +0200 Subject: [PATCH 2/6] fix bare urls split text --- src/librustdoc/passes/lint/bare_urls.rs | 27 +++++++++++++++---------- tests/rustdoc-ui/lints/bare-urls.fixed | 4 ++++ tests/rustdoc-ui/lints/bare-urls.rs | 4 ++++ tests/rustdoc-ui/lints/bare-urls.stderr | 14 ++++++++++++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 0928980e390a8..287a1f50b5aa1 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -2,13 +2,14 @@ //! Suggests wrapping the link with angle brackets: `Go to .` to linkify it. use core::ops::Range; -use std::mem; use std::sync::LazyLock; use regex::Regex; use rustc_errors::{Applicability, DiagDecorator}; use rustc_hir::HirId; -use rustc_resolve::rustdoc::pulldown_cmark::{Event, Parser, Tag}; +use rustc_resolve::rustdoc::pulldown_cmark::{ + DefaultBrokenLinkCallback, Event, Tag, TextMergeWithOffset, +}; use rustc_resolve::rustdoc::source_span_for_markdown_range; use tracing::trace; @@ -55,21 +56,20 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & ); }; - let mut p = Parser::new_ext(dox, main_body_opts()).into_offset_iter(); + // pulldown-cmark can split a URL into multiple `Text` events while processing + // characters such as `_` according to CommonMark's emphasis rules. + // `TextMergeWithOffset` merges these events so we can check the complete URL. + let mut p = TextMergeWithOffset::::new_ext(dox, main_body_opts()); while let Some((event, range)) = p.next() { match event { Event::Text(s) => find_raw_urls(cx, dox, &s, range, &report_diag), // We don't want to check the text inside code blocks or links. Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => { + let end = tag.to_end(); for (event, _) in p.by_ref() { - match event { - Event::End(end) - if mem::discriminant(&end) == mem::discriminant(&tag.to_end()) => - { - break; - } - _ => {} + if matches!(event, Event::End(tag) if tag == end) { + break; } } } @@ -83,7 +83,12 @@ static URL_REGEX: LazyLock = LazyLock::new(|| { r"https?://", // url scheme r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains r"[a-zA-Z]{2,63}", // root domain - r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)", // optional query or url fragments + // Match URL characters and balanced parenthesized segments, without + // consuming a trailing `)` that belongs to the surrounding prose. + r"\b(?:", + r"[-a-zA-Z0-9@:%_\+.~#?&/=]", + r"|\([-a-zA-Z0-9@:%_\+.~#?&/=]*\)", + r")*", )) .expect("failed to build regex") }); diff --git a/tests/rustdoc-ui/lints/bare-urls.fixed b/tests/rustdoc-ui/lints/bare-urls.fixed index 996214b5ff14f..b18aae11c77cf 100644 --- a/tests/rustdoc-ui/lints/bare-urls.fixed +++ b/tests/rustdoc-ui/lints/bare-urls.fixed @@ -92,3 +92,7 @@ pub fn trailing_period() {} /// ] //~^ ERROR this URL is not a hyperlink pub fn lint_with_brackets() {} + +/// See +//~^ ERROR this URL is not a hyperlink +pub fn hippo() {} diff --git a/tests/rustdoc-ui/lints/bare-urls.rs b/tests/rustdoc-ui/lints/bare-urls.rs index 9b4fe68e00322..fb39ec6b6ccbd 100644 --- a/tests/rustdoc-ui/lints/bare-urls.rs +++ b/tests/rustdoc-ui/lints/bare-urls.rs @@ -92,3 +92,7 @@ pub fn trailing_period() {} /// https://bloob.blob] //~^ ERROR this URL is not a hyperlink pub fn lint_with_brackets() {} + +/// See https://en.wikipedia.org/wiki/Rust_(programming_language) +//~^ ERROR this URL is not a hyperlink +pub fn hippo() {} diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr index 05ddd2ed42ab1..a3a291e8e4bca 100644 --- a/tests/rustdoc-ui/lints/bare-urls.stderr +++ b/tests/rustdoc-ui/lints/bare-urls.stderr @@ -364,5 +364,17 @@ help: use an automatic link instead LL | /// ] | + + -error: aborting due to 30 previous errors +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:96:9 + | +LL | /// See https://en.wikipedia.org/wiki/Rust_(programming_language) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// See + | + + + +error: aborting due to 31 previous errors From cf7c0ffef791c6d9786a08449f697347ec3ae180 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 6 Sep 2026 22:06:44 +0100 Subject: [PATCH 3/6] std: fix set_permissions_nofollow on espidf and horizon read(true) was chained onto custom_flags(O_NOFOLLOW) inside a cfg block that excludes those two targets, so their OpenOptions had no access mode set and open() returned EINVAL before any chmod happened. Neither target has an fchmodat arm either, so set_permissions_nofollow could never succeed there. --- library/std/src/sys/fs/unix.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 5d5eae5b26a19..613397e6903c1 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1911,6 +1911,7 @@ pub fn set_perm_nofollow(p: &CStr, perm: FilePermissions) -> io::Result<()> { use crate::fs::{OpenOptions, Permissions}; let mut options = OpenOptions::new(); + options.read(true); // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. // Their filesystems do not have symbolic links, so no special handling is required. @@ -1920,7 +1921,7 @@ pub fn set_perm_nofollow(p: &CStr, perm: FilePermissions) -> io::Result<()> { use crate::os::unix::fs::OpenOptionsExt; #[cfg(target_os = "wasi")] use crate::os::wasi::fs::OpenOptionsExt; - options.read(true).custom_flags(libc::O_NOFOLLOW); + options.custom_flags(libc::O_NOFOLLOW); } // SAFETY: Since this function is called with `with_native_path` From ff721141e7cccf9aeb3bb7ccc49c58e981245b20 Mon Sep 17 00:00:00 2001 From: Daedalus <16168171+RedDaedalus@users.noreply.github.com> Date: Sun, 6 Sep 2026 15:43:33 -0600 Subject: [PATCH 4/6] remove outdated UnsafeCell raw_get comment --- library/core/src/cell.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index e8cd3a500084a..d332908954b8f 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2494,8 +2494,7 @@ impl UnsafeCell { #[rustc_diagnostic_item = "unsafe_cell_raw_get"] pub const fn raw_get(this: *const Self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of - // #[repr(transparent)]. This exploits std's special status, there is - // no guarantee for user code that this will work in future versions of the compiler! + // #[repr(transparent)]. this as *const T as *mut T } From 14989dc2c2d75acf0c09a38ffea2d099cb095876 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Sep 2026 20:11:57 +0200 Subject: [PATCH 5/6] add regression test for packus_epi16 issue --- tests/assembly-llvm/x86-vendor-intrinsics.rs | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/assembly-llvm/x86-vendor-intrinsics.rs diff --git a/tests/assembly-llvm/x86-vendor-intrinsics.rs b/tests/assembly-llvm/x86-vendor-intrinsics.rs new file mode 100644 index 0000000000000..b600b74c66ecd --- /dev/null +++ b/tests/assembly-llvm/x86-vendor-intrinsics.rs @@ -0,0 +1,21 @@ +// Output differs depending on ABI so we need to match the full target. +//@ only-x86_64-unknown-linux-gnu +//@ assembly-output: emit-asm +//@ compile-flags: -Ctarget-feature=-sse3 -C opt-level=3 + +// Regression test for various cases where we used to compile x86 vendor intrinsics in a suboptimal +// way. + +#![crate_type = "lib"] + +use std::arch::x86_64::*; + +// CHECK-LABEL: test_packus_epi16: +#[unsafe(no_mangle)] +#[target_feature(enable = "sse2")] +extern "C" fn test_packus_epi16(a: __m128i, b: __m128i) -> __m128i { + // CHECK: .cfi_startproc + // CHECK-NEXT: packuswb + // CHECK-NEXT: ret + _mm_packus_epi16(a, b) +} From a490ea63fa80ae94509ceff014ad0a8a82b65268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 5 Sep 2026 13:03:23 +0200 Subject: [PATCH 6/6] Allow overriding `llvm-filecheck` even if LLVM is otherwise downloaded or built --- src/bootstrap/src/core/build_steps/llvm.rs | 6 +++--- src/bootstrap/src/core/config/config.rs | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index abd3465f67235..91a6ecf4d6bb9 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -2237,7 +2237,8 @@ impl Step for FileCheck { let llvm_bindir = command(llvm_config).arg("--bindir").run_capture_stdout(builder).stdout(); let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", self.target)); - let filecheck = if filecheck.exists() { + + if filecheck.exists() { filecheck } else { // On Fedora the system LLVM installs FileCheck in the @@ -2255,8 +2256,7 @@ impl Step for FileCheck { // refers to that. filecheck } - }; - filecheck + } } else { // In other cases, just guess that Filecheck is available in the same directory // as the llvm-config diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index f87e0780ce49c..a513c45bce9b1 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1008,11 +1008,6 @@ impl Config { target.llvm_has_rust_patches = Some(patches); } if let Some(ref s) = target_llvm_filecheck { - if target_llvm_config.is_none() { - panic!( - "You must also configure `llvm-config` when setting `llvm-filecheck` for target {triple}", - ); - } target.llvm_filecheck = Some(src.join(s)); } target.llvm_libunwind = target_llvm_libunwind.as_ref().map(|v| {