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