Auto merge of #144658 - jhpratt:rollup-jdzhz27, r=jhpratt

Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#144034 (tests: Test line number in debuginfo for diverging function calls)
 - rust-lang/rust#144510 (Fix Ord, Eq and Hash implementation of panic::Location)
 - rust-lang/rust#144583 (Enable T-compiler backport nomination)
 - rust-lang/rust#144586 (Update wasi-sdk to 27.0 in CI)
 - rust-lang/rust#144605 (Resolve: cachify `ExternPreludeEntry.binding` through a `Cell`)
 - rust-lang/rust#144632 (Update some tests for LLVM 21)
 - rust-lang/rust#144639 (Update rustc-perf submodule)
 - rust-lang/rust#144640 (Add support for the m68k architecture in 'object_architecture')

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-07-29 23:53:04 +00:00
17 changed files with 235 additions and 55 deletions
@@ -984,18 +984,17 @@ fn build_reduced_graph_for_extern_crate(
// more details: https://github.com/rust-lang/rust/pull/111761
return;
}
let entry = self
.r
.extern_prelude
.entry(ident)
.or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
let entry = self.r.extern_prelude.entry(ident).or_insert(ExternPreludeEntry {
binding: Cell::new(None),
introduced_by_item: true,
});
if orig_name.is_some() {
entry.introduced_by_item = true;
}
// Binding from `extern crate` item in source code can replace
// a binding from `--extern` on command line here.
if !entry.is_import() {
entry.binding = Some(imported_binding)
entry.binding.set(Some(imported_binding));
} else if ident.name != kw::Underscore {
self.r.dcx().span_delayed_bug(
item.span,
+6 -6
View File
@@ -1009,13 +1009,13 @@ fn determined(&self) -> bool {
#[derive(Default, Clone)]
struct ExternPreludeEntry<'ra> {
binding: Option<NameBinding<'ra>>,
binding: Cell<Option<NameBinding<'ra>>>,
introduced_by_item: bool,
}
impl ExternPreludeEntry<'_> {
fn is_import(&self) -> bool {
self.binding.is_some_and(|binding| binding.is_import())
self.binding.get().is_some_and(|binding| binding.is_import())
}
}
@@ -2006,7 +2006,7 @@ fn record_use_inner(
// but not introduce it, as used if they are accessed from lexical scope.
if used == Used::Scope {
if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
if !entry.introduced_by_item && entry.binding == Some(used_binding) {
if !entry.introduced_by_item && entry.binding.get() == Some(used_binding) {
return;
}
}
@@ -2170,7 +2170,7 @@ fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBin
let norm_ident = ident.normalize_to_macros_2_0();
let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| {
Some(if let Some(binding) = entry.binding {
Some(if let Some(binding) = entry.binding.get() {
if finalize {
if !entry.is_import() {
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
@@ -2195,8 +2195,8 @@ fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBin
})
});
if let Some(entry) = self.extern_prelude.get_mut(&norm_ident) {
entry.binding = binding;
if let Some(entry) = self.extern_prelude.get(&norm_ident) {
entry.binding.set(binding);
}
binding
+1
View File
@@ -3598,6 +3598,7 @@ pub fn object_architecture(
),
"x86" => (Architecture::I386, None),
"s390x" => (Architecture::S390x, None),
"m68k" => (Architecture::M68k, None),
"mips" | "mips32r6" => (Architecture::Mips, None),
"mips64" | "mips64r6" => (
// While there are currently no builtin targets
+41 -1
View File
@@ -1,5 +1,7 @@
use crate::cmp::Ordering;
use crate::ffi::CStr;
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::marker::PhantomData;
use crate::ptr::NonNull;
@@ -32,7 +34,7 @@
/// Files are compared as strings, not `Path`, which could be unexpected.
/// See [`Location::file`]'s documentation for more discussion.
#[lang = "panic_location"]
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[derive(Copy, Clone)]
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct Location<'a> {
// A raw pointer is used rather than a reference because the pointer is valid for one more byte
@@ -44,6 +46,44 @@ pub struct Location<'a> {
_filename: PhantomData<&'a str>,
}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl PartialEq for Location<'_> {
fn eq(&self, other: &Self) -> bool {
// Compare col / line first as they're cheaper to compare and more likely to differ,
// while not impacting the result.
self.col == other.col && self.line == other.line && self.file() == other.file()
}
}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl Eq for Location<'_> {}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl Ord for Location<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.file()
.cmp(other.file())
.then_with(|| self.line.cmp(&other.line))
.then_with(|| self.col.cmp(&other.col))
}
}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl PartialOrd for Location<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl Hash for Location<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.file().hash(state);
self.line.hash(state);
self.col.hash(state);
}
}
#[stable(feature = "panic_hooks", since = "1.10.0")]
impl fmt::Debug for Location<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+41 -2
View File
@@ -3,6 +3,23 @@
// Note: Some of the following tests depend on the source location,
// so please be careful when editing this file.
mod file_a;
mod file_b;
mod file_c;
// A small shuffled set of locations for testing, along with their true order.
const LOCATIONS: [(usize, &'static Location<'_>); 9] = [
(7, file_c::two()),
(0, file_a::one()),
(3, file_b::one()),
(5, file_b::three()),
(8, file_c::three()),
(6, file_c::one()),
(2, file_a::three()),
(4, file_b::two()),
(1, file_a::two()),
];
#[test]
fn location_const_caller() {
const _CALLER_REFERENCE: &Location<'static> = Location::caller();
@@ -20,7 +37,7 @@ fn location_const_file() {
fn location_const_line() {
const CALLER: &Location<'static> = Location::caller();
const LINE: u32 = CALLER.line();
assert_eq!(LINE, 21);
assert_eq!(LINE, 38);
}
#[test]
@@ -34,6 +51,28 @@ fn location_const_column() {
fn location_debug() {
let f = format!("{:?}", Location::caller());
assert!(f.contains(&format!("{:?}", file!())));
assert!(f.contains("35"));
assert!(f.contains("52"));
assert!(f.contains("29"));
}
#[test]
fn location_eq() {
for (i, a) in LOCATIONS {
for (j, b) in LOCATIONS {
if i == j {
assert_eq!(a, b);
} else {
assert_ne!(a, b);
}
}
}
}
#[test]
fn location_ord() {
let mut locations = LOCATIONS.clone();
locations.sort_by_key(|(_o, l)| **l);
for (correct, (order, _l)) in locations.iter().enumerate() {
assert_eq!(correct, *order);
}
}
@@ -0,0 +1,15 @@
use core::panic::Location;
// Used for test super::location_{ord, eq}. Must be in a dedicated file.
pub const fn one() -> &'static Location<'static> {
Location::caller()
}
pub const fn two() -> &'static Location<'static> {
Location::caller()
}
pub const fn three() -> &'static Location<'static> {
Location::caller()
}
@@ -0,0 +1,15 @@
use core::panic::Location;
// Used for test super::location_{ord, eq}. Must be in a dedicated file.
pub const fn one() -> &'static Location<'static> {
Location::caller()
}
pub const fn two() -> &'static Location<'static> {
Location::caller()
}
pub const fn three() -> &'static Location<'static> {
Location::caller()
}
@@ -0,0 +1,11 @@
// Used for test super::location_{ord, eq}. Must be in a dedicated file.
// This is used for testing column ordering of Location, hence this ugly one-liner.
// We must fmt skip the entire containing module or else tidy will still complain.
#[rustfmt::skip]
mod no_fmt {
use core::panic::Location;
pub const fn one() -> &'static Location<'static> { Location::caller() } pub const fn two() -> &'static Location<'static> { Location::caller() } pub const fn three() -> &'static Location<'static> { Location::caller() }
}
pub use no_fmt::*;
@@ -81,9 +81,9 @@ RUN /tmp/build-fuchsia-toolchain.sh
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz | \
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/tmp/wasi-sdk-25.0-x86_64-linux
ENV WASI_SDK_PATH=/tmp/wasi-sdk-27.0-x86_64-linux
COPY scripts/freebsd-toolchain.sh /tmp/
RUN /tmp/freebsd-toolchain.sh i686
@@ -40,9 +40,9 @@ WORKDIR /
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz | \
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/wasi-sdk-25.0-x86_64-linux
ENV WASI_SDK_PATH=/wasi-sdk-27.0-x86_64-linux
ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
+24 -27
View File
@@ -167,7 +167,7 @@
("brotli-decompressor", "BSD-3-Clause/MIT"),
("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"),
("inferno", "CDDL-1.0"),
("ring", NON_STANDARD_LICENSE), // see EXCEPTIONS_NON_STANDARD_LICENSE_DEPS for more.
("option-ext", "MPL-2.0"),
("ryu", "Apache-2.0 OR BSL-1.0"),
("snap", "BSD-3-Clause"),
("subtle", "BSD-3-Clause"),
@@ -226,20 +226,6 @@
("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptable, but we use it under MIT OR Apache-2.0
];
/// Placeholder for non-standard license file.
const NON_STANDARD_LICENSE: &str = "NON_STANDARD_LICENSE";
/// These dependencies have non-standard licenses but are genenrally permitted.
const EXCEPTIONS_NON_STANDARD_LICENSE_DEPS: &[&str] = &[
// `ring` is included because it is an optional dependency of `hyper`,
// which is a training data in rustc-perf for optimized build.
// The license of it is generally `ISC AND MIT AND OpenSSL`,
// though the `package.license` field is not set.
//
// See https://github.com/briansmith/ring/issues/902
"ring",
];
const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!());
/// Crates rustc is allowed to depend on. Avoid adding to the list if possible.
@@ -599,7 +585,7 @@ pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) {
.other_options(vec!["--locked".to_owned()]);
let metadata = t!(cmd.exec());
check_license_exceptions(&metadata, exceptions, bad);
check_license_exceptions(&metadata, workspace, exceptions, bad);
if let Some((crates, permitted_deps)) = permitted_deps {
check_permitted_dependencies(&metadata, workspace, permitted_deps, crates, bad);
}
@@ -730,14 +716,19 @@ fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) {
/// Check that all licenses of tool dependencies are in the valid list in `LICENSES`.
///
/// Packages listed in `exceptions` are allowed for tools.
fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], bad: &mut bool) {
fn check_license_exceptions(
metadata: &Metadata,
workspace: &str,
exceptions: &[(&str, &str)],
bad: &mut bool,
) {
// Validate the EXCEPTIONS list hasn't changed.
for (name, license) in exceptions {
// Check that the package actually exists.
if !metadata.packages.iter().any(|p| *p.name == *name) {
tidy_error!(
bad,
"could not find exception package `{}`\n\
"could not find exception package `{}` in workspace `{workspace}`\n\
Remove from EXCEPTIONS list if it is no longer used.",
name
);
@@ -746,20 +737,17 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba
for pkg in metadata.packages.iter().filter(|p| *p.name == *name) {
match &pkg.license {
None => {
if *license == NON_STANDARD_LICENSE
&& EXCEPTIONS_NON_STANDARD_LICENSE_DEPS.contains(&pkg.name.as_str())
{
continue;
}
tidy_error!(
bad,
"dependency exception `{}` does not declare a license expression",
"dependency exception `{}` in workspace `{workspace}` does not declare a license expression",
pkg.id
);
}
Some(pkg_license) => {
if pkg_license.as_str() != *license {
println!("dependency exception `{name}` license has changed");
println!(
"dependency exception `{name}` license in workspace `{workspace}` has changed"
);
println!(" previously `{license}` now `{pkg_license}`");
println!(" update EXCEPTIONS for the new license");
*bad = true;
@@ -783,12 +771,21 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba
let license = match &pkg.license {
Some(license) => license,
None => {
tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id);
tidy_error!(
bad,
"dependency `{}` in workspace `{workspace}` does not define a license expression",
pkg.id
);
continue;
}
};
if !LICENSES.contains(&license.as_str()) {
tidy_error!(bad, "invalid license `{}` in `{}`", license, pkg.id);
tidy_error!(
bad,
"invalid license `{}` for package `{}` in workspace `{workspace}`",
license,
pkg.id
);
}
}
}
+5 -1
View File
@@ -1,6 +1,9 @@
//@ assembly-output: ptx-linker
//@ compile-flags: --crate-type cdylib -Z unstable-options -Clinker-flavor=llbc
//@ only-nvptx64
//@ revisions: LLVM20 LLVM21
//@ [LLVM21] min-llvm-version: 21
//@ [LLVM20] max-llvm-major-version: 20
#![feature(abi_ptx)]
#![no_std]
@@ -15,7 +18,8 @@
#[no_mangle]
pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
// CHECK: call.uni (retval0),
// CHECK-NEXT: [[IMPL_FN]]
// LLVM20-NEXT: [[IMPL_FN]]
// LLVM21-SAME: [[IMPL_FN]]
*b = deep::private::MyStruct::new(*a).square();
}
+3 -3
View File
@@ -334,9 +334,9 @@ pub fn return_f128(x: f128) -> f128 {
// linux-NEXT: .cfi_offset
// CHECK-NEXT: movl %esp, %ebp
// linux-NEXT: .cfi_def_cfa_register
// linux-NEXT: movaps 8(%ebp), %xmm0
// win-NEXT: movups 8(%ebp), %xmm0
// CHECK-NEXT: popl %ebp
// linux: movaps 8(%ebp), %xmm0
// win: movups 8(%ebp), %xmm0
// CHECK: popl %ebp
// linux-NEXT: .cfi_def_cfa
// CHECK-NEXT: retl
x
@@ -0,0 +1,38 @@
/// Make sure that line debuginfo is correct for diverging calls under certain
/// conditions. In particular we want to ensure that the line number is never
/// 0, but we check the absence of 0 by looking for the expected exact line
/// numbers. Regression test for <https://github.com/rust-lang/rust/issues/59558>.
//@ compile-flags: -g -Clto -Copt-level=0
//@ no-prefer-dynamic
// First find the scope of both diverge() calls, namely this main() function.
// CHECK-DAG: [[MAIN_SCOPE:![0-9]+]] = distinct !DISubprogram(name: "main", linkageName: {{.*}}diverging_function_call_debuginfo{{.*}}main{{.*}}
fn main() {
if True == False {
// unreachable
// Then find the DILocation with the correct line number for this call ...
// CHECK-DAG: [[UNREACHABLE_CALL_DBG:![0-9]+]] = !DILocation(line: [[@LINE+1]], {{.*}}scope: [[MAIN_SCOPE]]
diverge();
}
// ... and this call.
// CHECK-DAG: [[LAST_CALL_DBG:![0-9]+]] = !DILocation(line: [[@LINE+1]], {{.*}}scope: [[MAIN_SCOPE]]
diverge();
}
#[derive(PartialEq)]
pub enum MyBool {
True,
False,
}
use MyBool::*;
fn diverge() -> ! {
panic!();
}
// Finally make sure both DILocations belong to each the respective diverge() call.
// CHECK-DAG: call void {{.*}}diverging_function_call_debuginfo{{.*}}diverge{{.*}} !dbg [[LAST_CALL_DBG]]
// CHECK-DAG: call void {{.*}}diverging_function_call_debuginfo{{.*}}diverge{{.*}} !dbg [[UNREACHABLE_CALL_DBG]]
@@ -1,6 +1,9 @@
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
//@ min-llvm-version: 20
//@ only-64bit
//@ revisions: LLVM20 LLVM21
//@ [LLVM21] min-llvm-version: 21
//@ [LLVM20] max-llvm-major-version: 20
// The `derive(PartialEq)` on enums with field-less variants compares discriminants,
// so make sure we emit that in some reasonable way.
@@ -137,17 +140,20 @@ pub fn mid_nz32_eq_discr(a: Mid<NonZero<u32>>, b: Mid<NonZero<u32>>) -> bool {
pub fn mid_ac_eq_discr(a: Mid<AC>, b: Mid<AC>) -> bool {
// CHECK-LABEL: @mid_ac_eq_discr(
// CHECK: %[[A_REL_DISCR:.+]] = xor i8 %a, -128
// LLVM20: %[[A_REL_DISCR:.+]] = xor i8 %a, -128
// CHECK: %[[A_IS_NICHE:.+]] = icmp slt i8 %a, 0
// CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %a, -127
// CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]])
// CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1
// LLVM20: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1
// CHECK: %[[B_REL_DISCR:.+]] = xor i8 %b, -128
// LLVM20: %[[B_REL_DISCR:.+]] = xor i8 %b, -128
// CHECK: %[[B_IS_NICHE:.+]] = icmp slt i8 %b, 0
// CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %b, -127
// CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]])
// CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1
// LLVM20: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1
// LLVM21: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %a, i8 -127
// LLVM21: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %b, i8 -127
// CHECK: %[[R:.+]] = icmp eq i8 %[[A_DISCR]], %[[B_DISCR]]
// CHECK: ret i1 %[[R]]
+15
View File
@@ -50,6 +50,21 @@ remove_labels = ["S-waiting-on-author"]
# Those labels are added when PR author requests a review from an assignee
add_labels = ["S-waiting-on-review"]
# [backport.*] sections autonominate pull requests for a backport
# see: https://forge.rust-lang.org/triagebot/backport.html
[backport.t-compiler-beta-backport]
# The pull request MUST have one of these labels
required-pr-labels = ["T-compiler"]
# The regression MUST have this label
required-issue-label = "regression-from-stable-to-beta"
# if the above conditions matches, the PR will receive these labels
add-labels = ["beta-nominated"]
[backport.t-compiler-stable-backport]
required-pr-labels = ["T-compiler"]
required-issue-label = "regression-from-stable-to-stable"
add-labels = ["stable-nominated"]
# ------------------------------------------------------------------------------
# Ping groups