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` diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index f1864c736ed03..91a6ecf4d6bb9 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() { - 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. + 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)); + + 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 + } } + } else { + // 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 }); 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| { 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/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) +} 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