From 6d36c8a5fc4dd9ad3a4cf95ca31ecdc7f06bafc1 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 25 Dec 2025 10:51:54 +0000 Subject: [PATCH 01/81] Return ExitCode from rustc_driver::main This makes rustc simply return an exit code from main rather than calling `std::process::exit` with an exit code. This means that drops run normally and the process exits cleanly. Also instead of hard coding success and failure codes this uses `ExitCode::SUCCESS` and `ExitCode::FAILURE`, which in turn effectively uses `libc::EXIT_SUCCESS` and `libc::EXIT_FAILURE` (via std). These are `0` and `1` respectively for all currently supported host platforms so it doesn't actually change the exit code. --- compiler/rustc/src/main.rs | 4 +++- compiler/rustc_driver_impl/src/lib.rs | 12 ++++++------ src/librustdoc/lib.rs | 9 ++++----- src/tools/clippy/src/driver.rs | 26 ++++++++++++++------------ src/tools/rustdoc/main.rs | 4 +++- tests/ui-fulldeps/obtain-borrowck.rs | 8 ++++---- 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 89c61cdf00a5..30d64b05cfde 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -3,6 +3,8 @@ // Several crates are depended upon but unused so that they are present in the sysroot #![expect(unused_crate_dependencies)] +use std::process::ExitCode; + // A note about jemalloc: rustc uses jemalloc when built for CI and // distribution. The obvious way to do this is with the `#[global_allocator]` // mechanism. However, for complicated reasons (see @@ -38,6 +40,6 @@ #[cfg(feature = "jemalloc")] use tikv_jemalloc_sys as _; -fn main() { +fn main() -> ExitCode { rustc_driver::main() } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 38ee87601614..9ecb85548f22 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -20,7 +20,7 @@ use std::fs::{self, File}; use std::io::{self, IsTerminal, Read, Write}; use std::panic::{self, PanicHookInfo}; use std::path::{Path, PathBuf}; -use std::process::{self, Command, Stdio}; +use std::process::{Command, ExitCode, Stdio, Termination}; use std::sync::OnceLock; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Instant; @@ -1382,10 +1382,10 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> { /// Variant of `catch_fatal_errors` for the `interface::Result` return type /// that also computes the exit code. -pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 { +pub fn catch_with_exit_code(f: impl FnOnce() -> T) -> ExitCode { match catch_fatal_errors(f) { - Ok(()) => EXIT_SUCCESS, - _ => EXIT_FAILURE, + Ok(status) => status.report(), + _ => ExitCode::FAILURE, } } @@ -1670,7 +1670,7 @@ pub fn install_ctrlc_handler() { .expect("Unable to install ctrlc handler"); } -pub fn main() -> ! { +pub fn main() -> ExitCode { let start_time = Instant::now(); let start_rss = get_resident_set_size(); @@ -1690,5 +1690,5 @@ pub fn main() -> ! { print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format); } - process::exit(exit_code) + exit_code } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 137319ae0c06..21ac851e5486 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -71,7 +71,7 @@ extern crate tikv_jemalloc_sys as _; use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::path::Path; -use std::process; +use std::process::ExitCode; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::LOCAL_CRATE; @@ -126,7 +126,7 @@ mod visit; mod visit_ast; mod visit_lib; -pub fn main() { +pub fn main() -> ExitCode { let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::install_ice_hook( @@ -164,11 +164,10 @@ pub fn main() { Err(error) => early_dcx.early_fatal(error.to_string()), } - let exit_code = rustc_driver::catch_with_exit_code(|| { + rustc_driver::catch_with_exit_code(|| { let at_args = rustc_driver::args::raw_args(&early_dcx); main_args(&mut early_dcx, &at_args); - }); - process::exit(exit_code); + }) } fn init_logging(early_dcx: &EarlyDiagCtxt) { diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 7425da70df90..cf06f43e8d4a 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -32,7 +32,7 @@ use std::env; use std::fs::read_to_string; use std::io::Write as _; use std::path::Path; -use std::process::exit; +use std::process::ExitCode; /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`. @@ -182,15 +182,17 @@ impl rustc_driver::Callbacks for ClippyCallbacks { } } -fn display_help() { +fn display_help() -> ExitCode { if writeln!(&mut anstream::stdout().lock(), "{}", help_message()).is_err() { - exit(rustc_driver::EXIT_FAILURE); + ExitCode::FAILURE + } else { + ExitCode::SUCCESS } } const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml"; -pub fn main() { +pub fn main() -> ExitCode { let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::init_rustc_env_logger(&early_dcx); @@ -203,7 +205,7 @@ pub fn main() { dcx.handle().note(format!("Clippy version: {version_info}")); }); - exit(rustc_driver::catch_with_exit_code(move || { + rustc_driver::catch_with_exit_code(move || { let mut orig_args = rustc_driver::args::raw_args(&early_dcx); let has_sysroot_arg = |args: &mut [String]| -> bool { @@ -246,15 +248,15 @@ pub fn main() { pass_sysroot_env_if_given(&mut args, sys_root_env); rustc_driver::run_compiler(&args, &mut DefaultCallbacks); - return; + return ExitCode::SUCCESS; } if orig_args.iter().any(|a| a == "--version" || a == "-V") { let version_info = rustc_tools_util::get_version_info!(); - match writeln!(&mut anstream::stdout().lock(), "{version_info}") { - Ok(()) => exit(rustc_driver::EXIT_SUCCESS), - Err(_) => exit(rustc_driver::EXIT_FAILURE), + return match writeln!(&mut anstream::stdout().lock(), "{version_info}") { + Ok(()) => ExitCode::SUCCESS, + Err(_) => ExitCode::FAILURE, } } @@ -268,8 +270,7 @@ pub fn main() { } if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) { - display_help(); - exit(0); + return display_help(); } let mut args: Vec = orig_args.clone(); @@ -311,7 +312,8 @@ pub fn main() { } else { rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var }); } - })) + ExitCode::SUCCESS + }) } #[must_use] diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index d4099cafe5df..a35bcf9f547c 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -1,6 +1,8 @@ // We need this feature as it changes `dylib` linking behavior and allows us to link to `rustc_driver`. #![feature(rustc_private)] -fn main() { +use std::process::ExitCode; + +fn main() -> ExitCode { rustdoc::main() } diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs index a562d0ccd3df..603eadad25b7 100644 --- a/tests/ui-fulldeps/obtain-borrowck.rs +++ b/tests/ui-fulldeps/obtain-borrowck.rs @@ -28,6 +28,7 @@ extern crate rustc_session; use std::cell::RefCell; use std::collections::HashMap; +use std::process::ExitCode; use std::thread_local; use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions}; @@ -42,16 +43,15 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -fn main() { - let exit_code = rustc_driver::catch_with_exit_code(move || { +fn main() -> ExitCode { + rustc_driver::catch_with_exit_code(move || { let mut rustc_args: Vec<_> = std::env::args().collect(); // We must pass -Zpolonius so that the borrowck information is computed. rustc_args.push("-Zpolonius".to_owned()); let mut callbacks = CompilerCalls::default(); // Call the Rust compiler with our callbacks. rustc_driver::run_compiler(&rustc_args, &mut callbacks); - }); - std::process::exit(exit_code); + }) } #[derive(Default)] From 0c432af701682603f7e2863e339fb4222563ab6d Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 26 Dec 2025 18:44:02 +0000 Subject: [PATCH 02/81] Use ExitCode when returning from main in miri --- src/tools/miri/src/bin/miri.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 48f8e146a190..aa5e5d708da9 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -39,6 +39,7 @@ mod log; use std::env; use std::num::{NonZero, NonZeroI32}; use std::ops::Range; +use std::process::ExitCode; use std::rc::Rc; use std::str::FromStr; use std::sync::Once; @@ -404,7 +405,11 @@ fn run_compiler_and_exit( // Invoke compiler, catch any unwinding panics and handle return code. let exit_code = rustc_driver::catch_with_exit_code(move || rustc_driver::run_compiler(args, callbacks)); - exit(exit_code) + exit(if exit_code == ExitCode::SUCCESS { + rustc_driver::EXIT_SUCCESS + } else { + rustc_driver::EXIT_FAILURE + }) } /// Parses a comma separated list of `T` from the given string: @@ -434,7 +439,7 @@ fn parse_range(val: &str) -> Result, &'static str> { Ok(from..to) } -fn main() { +fn main() -> ExitCode { let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // Snapshot a copy of the environment before `rustc` starts messing with it. @@ -449,9 +454,7 @@ fn main() { if crate_kind == "host" { // For host crates like proc macros and build scripts, we are an entirely normal rustc. // These eventually produce actual binaries and never run in Miri. - match rustc_driver::main() { - // Empty match proves this function will never return. - } + return rustc_driver::main(); } else if crate_kind != "target" { panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}") }; From 91850e90de096eb37364358e8a4eb7e0b30284ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Wed, 28 Jan 2026 22:05:10 +0100 Subject: [PATCH 03/81] Avoid `unsafe fn` in aarch64, powerpc and s390x tests --- .../crates/core_arch/src/aarch64/neon/mod.rs | 264 ++++----- .../crates/core_arch/src/powerpc/altivec.rs | 528 ++++++++++-------- .../crates/core_arch/src/powerpc/vsx.rs | 34 +- .../crates/core_arch/src/s390x/vector.rs | 135 +++-- 4 files changed, 536 insertions(+), 425 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index b172b57f3254..bac45742393c 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -569,47 +569,46 @@ mod tests { use crate::core_arch::aarch64::test_support::*; use crate::core_arch::arm_shared::test_support::*; use crate::core_arch::{aarch64::neon::*, aarch64::*, simd::*}; - use std::mem::transmute; use stdarch_test::simd_test; #[simd_test(enable = "neon")] - unsafe fn test_vadd_f64() { - let a = 1.; - let b = 8.; - let e = 9.; - let r: f64 = transmute(vadd_f64(transmute(a), transmute(b))); + fn test_vadd_f64() { + let a = f64x1::from_array([1.]); + let b = f64x1::from_array([8.]); + let e = f64x1::from_array([9.]); + let r = f64x1::from(vadd_f64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddq_f64() { + fn test_vaddq_f64() { let a = f64x2::new(1., 2.); let b = f64x2::new(8., 7.); let e = f64x2::new(9., 9.); - let r: f64x2 = transmute(vaddq_f64(transmute(a), transmute(b))); + let r = f64x2::from(vaddq_f64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vadd_s64() { - let a = 1_i64; - let b = 8_i64; - let e = 9_i64; - let r: i64 = transmute(vadd_s64(transmute(a), transmute(b))); + fn test_vadd_s64() { + let a = i64x1::from_array([1]); + let b = i64x1::from_array([8]); + let e = i64x1::from_array([9]); + let r = i64x1::from(vadd_s64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vadd_u64() { - let a = 1_u64; - let b = 8_u64; - let e = 9_u64; - let r: u64 = transmute(vadd_u64(transmute(a), transmute(b))); + fn test_vadd_u64() { + let a = u64x1::from_array([1]); + let b = u64x1::from_array([8]); + let e = u64x1::from_array([9]); + let r = u64x1::from(vadd_u64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddd_s64() { + fn test_vaddd_s64() { let a = 1_i64; let b = 8_i64; let e = 9_i64; @@ -618,7 +617,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vaddd_u64() { + fn test_vaddd_u64() { let a = 1_u64; let b = 8_u64; let e = 9_u64; @@ -627,25 +626,25 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vext_p64() { - let a: i64x1 = i64x1::new(0); - let b: i64x1 = i64x1::new(1); - let e: i64x1 = i64x1::new(0); - let r: i64x1 = transmute(vext_p64::<0>(transmute(a), transmute(b))); + fn test_vext_p64() { + let a = u64x1::new(0); + let b = u64x1::new(1); + let e = u64x1::new(0); + let r = u64x1::from(vext_p64::<0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vext_f64() { - let a: f64x1 = f64x1::new(0.); - let b: f64x1 = f64x1::new(1.); - let e: f64x1 = f64x1::new(0.); - let r: f64x1 = transmute(vext_f64::<0>(transmute(a), transmute(b))); + fn test_vext_f64() { + let a = f64x1::new(0.); + let b = f64x1::new(1.); + let e = f64x1::new(0.); + let r = f64x1::from(vext_f64::<0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vshld_n_s64() { + fn test_vshld_n_s64() { let a: i64 = 1; let e: i64 = 4; let r: i64 = vshld_n_s64::<2>(a); @@ -653,7 +652,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vshld_n_u64() { + fn test_vshld_n_u64() { let a: u64 = 1; let e: u64 = 4; let r: u64 = vshld_n_u64::<2>(a); @@ -661,7 +660,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vshrd_n_s64() { + fn test_vshrd_n_s64() { let a: i64 = 4; let e: i64 = 1; let r: i64 = vshrd_n_s64::<2>(a); @@ -669,7 +668,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vshrd_n_u64() { + fn test_vshrd_n_u64() { let a: u64 = 4; let e: u64 = 1; let r: u64 = vshrd_n_u64::<2>(a); @@ -677,7 +676,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vsrad_n_s64() { + fn test_vsrad_n_s64() { let a: i64 = 1; let b: i64 = 4; let e: i64 = 2; @@ -686,7 +685,7 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vsrad_n_u64() { + fn test_vsrad_n_u64() { let a: u64 = 1; let b: u64 = 4; let e: u64 = 2; @@ -695,293 +694,300 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_f64() { + fn test_vdup_n_f64() { let a: f64 = 3.3; let e = f64x1::new(3.3); - let r: f64x1 = transmute(vdup_n_f64(a)); + let r = f64x1::from(vdup_n_f64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_p64() { + fn test_vdup_n_p64() { let a: u64 = 3; let e = u64x1::new(3); - let r: u64x1 = transmute(vdup_n_p64(a)); + let r = u64x1::from(vdup_n_p64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_f64() { + fn test_vdupq_n_f64() { let a: f64 = 3.3; let e = f64x2::new(3.3, 3.3); - let r: f64x2 = transmute(vdupq_n_f64(a)); + let r = f64x2::from(vdupq_n_f64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_p64() { + fn test_vdupq_n_p64() { let a: u64 = 3; let e = u64x2::new(3, 3); - let r: u64x2 = transmute(vdupq_n_p64(a)); + let r = u64x2::from(vdupq_n_p64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_p64() { + fn test_vmov_n_p64() { let a: u64 = 3; let e = u64x1::new(3); - let r: u64x1 = transmute(vmov_n_p64(a)); + let r = u64x1::from(vmov_n_p64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_f64() { + fn test_vmov_n_f64() { let a: f64 = 3.3; let e = f64x1::new(3.3); - let r: f64x1 = transmute(vmov_n_f64(a)); + let r = f64x1::from(vmov_n_f64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_p64() { + fn test_vmovq_n_p64() { let a: u64 = 3; let e = u64x2::new(3, 3); - let r: u64x2 = transmute(vmovq_n_p64(a)); + let r = u64x2::from(vmovq_n_p64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_f64() { + fn test_vmovq_n_f64() { let a: f64 = 3.3; let e = f64x2::new(3.3, 3.3); - let r: f64x2 = transmute(vmovq_n_f64(a)); + let r = f64x2::from(vmovq_n_f64(a)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_f64() { + fn test_vget_high_f64() { let a = f64x2::new(1.0, 2.0); let e = f64x1::new(2.0); - let r: f64x1 = transmute(vget_high_f64(transmute(a))); + let r = f64x1::from(vget_high_f64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_p64() { + fn test_vget_high_p64() { let a = u64x2::new(1, 2); let e = u64x1::new(2); - let r: u64x1 = transmute(vget_high_p64(transmute(a))); + let r = u64x1::from(vget_high_p64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_f64() { + fn test_vget_low_f64() { let a = f64x2::new(1.0, 2.0); let e = f64x1::new(1.0); - let r: f64x1 = transmute(vget_low_f64(transmute(a))); + let r = f64x1::from(vget_low_f64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_p64() { + fn test_vget_low_p64() { let a = u64x2::new(1, 2); let e = u64x1::new(1); - let r: u64x1 = transmute(vget_low_p64(transmute(a))); + let r = u64x1::from(vget_low_p64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_f64() { + fn test_vget_lane_f64() { let v = f64x1::new(1.0); - let r = vget_lane_f64::<0>(transmute(v)); + let r = vget_lane_f64::<0>(v.into()); assert_eq!(r, 1.0); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_f64() { + fn test_vgetq_lane_f64() { let v = f64x2::new(0.0, 1.0); - let r = vgetq_lane_f64::<1>(transmute(v)); + let r = vgetq_lane_f64::<1>(v.into()); assert_eq!(r, 1.0); - let r = vgetq_lane_f64::<0>(transmute(v)); + let r = vgetq_lane_f64::<0>(v.into()); assert_eq!(r, 0.0); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_lane_s64() { - let a: i64x1 = i64x1::new(1); - let b: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let e: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let r: i64x1 = transmute(vcopy_lane_s64::<0, 0>(transmute(a), transmute(b))); + fn test_vcopy_lane_s64() { + let a = i64x1::new(1); + let b = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let e = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let r = i64x1::from(vcopy_lane_s64::<0, 0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_lane_u64() { - let a: u64x1 = u64x1::new(1); - let b: u64x1 = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); - let e: u64x1 = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); - let r: u64x1 = transmute(vcopy_lane_u64::<0, 0>(transmute(a), transmute(b))); + fn test_vcopy_lane_u64() { + let a = u64x1::new(1); + let b = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); + let e = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); + let r = u64x1::from(vcopy_lane_u64::<0, 0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_lane_p64() { - let a: i64x1 = i64x1::new(1); - let b: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let e: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let r: i64x1 = transmute(vcopy_lane_p64::<0, 0>(transmute(a), transmute(b))); + fn test_vcopy_lane_p64() { + let a = u64x1::new(1); + let b = u64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let e = u64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let r = u64x1::from(vcopy_lane_p64::<0, 0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_lane_f64() { - let a: f64 = 1.; - let b: f64 = 0.; - let e: f64 = 0.; - let r: f64 = transmute(vcopy_lane_f64::<0, 0>(transmute(a), transmute(b))); + fn test_vcopy_lane_f64() { + let a = f64x1::from_array([1.]); + let b = f64x1::from_array([0.]); + let e = f64x1::from_array([0.]); + let r = f64x1::from(vcopy_lane_f64::<0, 0>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_laneq_s64() { - let a: i64x1 = i64x1::new(1); - let b: i64x2 = i64x2::new(0, 0x7F_FF_FF_FF_FF_FF_FF_FF); - let e: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let r: i64x1 = transmute(vcopy_laneq_s64::<0, 1>(transmute(a), transmute(b))); + fn test_vcopy_laneq_s64() { + let a = i64x1::new(1); + let b = i64x2::new(0, 0x7F_FF_FF_FF_FF_FF_FF_FF); + let e = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let r = i64x1::from(vcopy_laneq_s64::<0, 1>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_laneq_u64() { - let a: u64x1 = u64x1::new(1); - let b: u64x2 = u64x2::new(0, 0xFF_FF_FF_FF_FF_FF_FF_FF); - let e: u64x1 = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); - let r: u64x1 = transmute(vcopy_laneq_u64::<0, 1>(transmute(a), transmute(b))); + fn test_vcopy_laneq_u64() { + let a = u64x1::new(1); + let b = u64x2::new(0, 0xFF_FF_FF_FF_FF_FF_FF_FF); + let e = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF); + let r = u64x1::from(vcopy_laneq_u64::<0, 1>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_laneq_p64() { - let a: i64x1 = i64x1::new(1); - let b: i64x2 = i64x2::new(0, 0x7F_FF_FF_FF_FF_FF_FF_FF); - let e: i64x1 = i64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); - let r: i64x1 = transmute(vcopy_laneq_p64::<0, 1>(transmute(a), transmute(b))); + fn test_vcopy_laneq_p64() { + let a = u64x1::new(1); + let b = u64x2::new(0, 0x7F_FF_FF_FF_FF_FF_FF_FF); + let e = u64x1::new(0x7F_FF_FF_FF_FF_FF_FF_FF); + let r = u64x1::from(vcopy_laneq_p64::<0, 1>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vcopy_laneq_f64() { - let a: f64 = 1.; - let b: f64x2 = f64x2::new(0., 0.5); - let e: f64 = 0.5; - let r: f64 = transmute(vcopy_laneq_f64::<0, 1>(transmute(a), transmute(b))); + fn test_vcopy_laneq_f64() { + let a = f64x1::from_array([1.]); + let b = f64x2::from_array([0., 0.5]); + let e = f64x1::from_array([0.5]); + let r = f64x1::from(vcopy_laneq_f64::<0, 1>(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbsl_f64() { + fn test_vbsl_f64() { let a = u64x1::new(0x8000000000000000); let b = f64x1::new(-1.23f64); let c = f64x1::new(2.34f64); let e = f64x1::new(-2.34f64); - let r: f64x1 = transmute(vbsl_f64(transmute(a), transmute(b), transmute(c))); + let r = f64x1::from(vbsl_f64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_p64() { + fn test_vbsl_p64() { let a = u64x1::new(1); let b = u64x1::new(u64::MAX); let c = u64x1::new(u64::MIN); let e = u64x1::new(1); - let r: u64x1 = transmute(vbsl_p64(transmute(a), transmute(b), transmute(c))); + let r = u64x1::from(vbsl_p64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_f64() { + fn test_vbslq_f64() { let a = u64x2::new(1, 0x8000000000000000); let b = f64x2::new(f64::MAX, -1.23f64); let c = f64x2::new(f64::MIN, 2.34f64); let e = f64x2::new(f64::MIN, -2.34f64); - let r: f64x2 = transmute(vbslq_f64(transmute(a), transmute(b), transmute(c))); + let r = f64x2::from(vbslq_f64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_p64() { + fn test_vbslq_p64() { let a = u64x2::new(u64::MAX, 1); let b = u64x2::new(u64::MAX, u64::MAX); let c = u64x2::new(u64::MIN, u64::MIN); let e = u64x2::new(u64::MAX, 1); - let r: u64x2 = transmute(vbslq_p64(transmute(a), transmute(b), transmute(c))); + let r = u64x2::from(vbslq_p64(a.into(), b.into(), c.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vld1_f64() { + fn test_vld1_f64() { let a: [f64; 2] = [0., 1.]; let e = f64x1::new(1.); - let r: f64x1 = transmute(vld1_f64(a[1..].as_ptr())); + let r = unsafe { f64x1::from(vld1_f64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_f64() { + fn test_vld1q_f64() { let a: [f64; 3] = [0., 1., 2.]; let e = f64x2::new(1., 2.); - let r: f64x2 = transmute(vld1q_f64(a[1..].as_ptr())); + let r = unsafe { f64x2::from(vld1q_f64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_f64() { + fn test_vld1_dup_f64() { let a: [f64; 2] = [1., 42.]; let e = f64x1::new(42.); - let r: f64x1 = transmute(vld1_dup_f64(a[1..].as_ptr())); + let r = unsafe { f64x1::from(vld1_dup_f64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_f64() { + fn test_vld1q_dup_f64() { let elem: f64 = 42.; let e = f64x2::new(42., 42.); - let r: f64x2 = transmute(vld1q_dup_f64(&elem)); + let r = unsafe { f64x2::from(vld1q_dup_f64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_f64() { + fn test_vld1_lane_f64() { let a = f64x1::new(0.); let elem: f64 = 42.; let e = f64x1::new(42.); - let r: f64x1 = transmute(vld1_lane_f64::<0>(&elem, transmute(a))); + let r = unsafe { f64x1::from(vld1_lane_f64::<0>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_f64() { + fn test_vld1q_lane_f64() { let a = f64x2::new(0., 1.); let elem: f64 = 42.; let e = f64x2::new(0., 42.); - let r: f64x2 = transmute(vld1q_lane_f64::<1>(&elem, transmute(a))); + let r = unsafe { f64x2::from(vld1q_lane_f64::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vst1_f64() { + fn test_vst1_f64() { let mut vals = [0_f64; 2]; let a = f64x1::new(1.); - vst1_f64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_f64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0.); assert_eq!(vals[1], 1.); } #[simd_test(enable = "neon")] - unsafe fn test_vst1q_f64() { + fn test_vst1q_f64() { let mut vals = [0_f64; 3]; let a = f64x2::new(1., 2.); - vst1q_f64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_f64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0.); assert_eq!(vals[1], 1.); diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index fb1a9d8ed9e2..7786a6731b4c 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -47,6 +47,54 @@ types! { pub struct vector_float(4 x f32); } +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for vector_bool_char { + #[inline] + fn from(value: m8x16) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for m8x16 { + #[inline] + fn from(value: vector_bool_char) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for vector_bool_short { + #[inline] + fn from(value: m16x8) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for m16x8 { + #[inline] + fn from(value: vector_bool_short) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for vector_bool_int { + #[inline] + fn from(value: m32x4) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for m32x4 { + #[inline] + fn from(value: vector_bool_int) -> Self { + unsafe { transmute(value) } + } +} + #[allow(improper_ctypes)] unsafe extern "C" { #[link_name = "llvm.ppc.altivec.lvx"] @@ -4653,22 +4701,22 @@ mod tests { }; { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); + let b: s_t_l!($ty) = $ty::new($($b),+).into(); let d = $ty_out::new($($d),+); - let r : $ty_out = transmute($fn(a, b)); + let r = $ty_out::from(unsafe { $fn(a, b) }); assert_eq!(d, r); } }; { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); + let b: s_t_l!($ty) = $ty::new($($b),+).into(); - let r : $ty_out = transmute($fn(a, b)); + let r = $ty_out::from(unsafe { $fn(a, b) }); assert_eq!($d, r); } } @@ -4677,11 +4725,11 @@ mod tests { macro_rules! test_vec_1 { { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: vector_float = transmute(f32x4::new($($a),+)); + fn $name() { + let a = vector_float::from(f32x4::new($($a),+)); - let d: vector_float = transmute(f32x4::new($($d),+)); - let r = transmute(vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON))); + let d = vector_float::from(f32x4::new($($d),+)); + let r = m32x4::from(unsafe { vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON)) }); let e = m32x4::new(true, true, true, true); assert_eq!(e, r); } @@ -4691,18 +4739,18 @@ mod tests { }; { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); let d = $ty_out::new($($d),+); - let r : $ty_out = transmute($fn(a)); + let r = $ty_out::from(unsafe { $fn(a) }); assert_eq!(d, r); } } } #[simd_test(enable = "altivec")] - unsafe fn test_vec_ld() { + fn test_vec_ld() { let pat = [ u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), u8x16::new( @@ -4711,14 +4759,14 @@ mod tests { ]; for off in 0..16 { - let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off))); + let v = u8x16::from(unsafe { vec_ld(0, (pat.as_ptr() as *const u8).offset(off)) }); assert_eq!( v, u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) ); } for off in 16..32 { - let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off))); + let v = u8x16::from(unsafe { vec_ld(0, (pat.as_ptr() as *const u8).offset(off)) }); assert_eq!( v, u8x16::new( @@ -4729,7 +4777,7 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_xl() { + fn test_vec_xl() { let pat = [ u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), u8x16::new( @@ -4738,7 +4786,7 @@ mod tests { ]; for off in 0..16 { - let val: u8x16 = transmute(vec_xl(0, (pat.as_ptr() as *const u8).offset(off))); + let val = u8x16::from(unsafe { vec_xl(0, (pat.as_ptr() as *const u8).offset(off)) }); for i in 0..16 { let v = val.extract_dyn(i); assert_eq!(off as usize + i, v as usize); @@ -4747,14 +4795,16 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_xst() { - let v: vector_unsigned_char = transmute(u8x16::new( + fn test_vec_xst() { + let v = vector_unsigned_char::from(u8x16::new( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, )); for off in 0..16 { let mut buf = [0u8; 32]; - vec_xst(v, 0, (buf.as_mut_ptr() as *mut u8).offset(off)); + unsafe { + vec_xst(v, 0, (buf.as_mut_ptr() as *mut u8).offset(off)); + } for i in 0..16 { assert_eq!(i as u8, buf[off as usize..][i]); } @@ -4762,7 +4812,7 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_ldl() { + fn test_vec_ldl() { let pat = [ u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), u8x16::new( @@ -4771,14 +4821,14 @@ mod tests { ]; for off in 0..16 { - let v: u8x16 = transmute(vec_ldl(0, (pat.as_ptr() as *const u8).offset(off))); + let v = u8x16::from(unsafe { vec_ldl(0, (pat.as_ptr() as *const u8).offset(off)) }); assert_eq!( v, u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) ); } for off in 16..32 { - let v: u8x16 = transmute(vec_ldl(0, (pat.as_ptr() as *const u8).offset(off))); + let v = u8x16::from(unsafe { vec_ldl(0, (pat.as_ptr() as *const u8).offset(off)) }); assert_eq!( v, u8x16::new( @@ -4789,30 +4839,30 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_lde_u8() { + fn test_vec_lde_u8() { let pat = [u8x16::new( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, )]; for off in 0..16 { - let v: u8x16 = transmute(vec_lde(off, pat.as_ptr() as *const u8)); + let v = u8x16::from(unsafe { vec_lde(off, pat.as_ptr() as *const u8) }); assert_eq!(off as u8, v.extract_dyn(off as _)); } } #[simd_test(enable = "altivec")] - unsafe fn test_vec_lde_u16() { + fn test_vec_lde_u16() { let pat = [u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)]; for off in 0..8 { - let v: u16x8 = transmute(vec_lde(off * 2, pat.as_ptr() as *const u16)); + let v = u16x8::from(unsafe { vec_lde(off * 2, pat.as_ptr() as *const u16) }); assert_eq!(off as u16, v.extract_dyn(off as _)); } } #[simd_test(enable = "altivec")] - unsafe fn test_vec_lde_u32() { + fn test_vec_lde_u32() { let pat = [u32x4::new(0, 1, 2, 3)]; for off in 0..4 { - let v: u32x4 = transmute(vec_lde(off * 4, pat.as_ptr() as *const u32)); + let v = u32x4::from(unsafe { vec_lde(off * 4, pat.as_ptr() as *const u32) }); assert_eq!(off as u32, v.extract_dyn(off as _)); } } @@ -5818,9 +5868,9 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_cmpb() { - let a: vector_float = transmute(f32x4::new(0.1, 0.5, 0.6, 0.9)); - let b: vector_float = transmute(f32x4::new(-0.1, 0.5, -0.6, 0.9)); + fn test_vec_cmpb() { + let a = vector_float::from(f32x4::new(0.1, 0.5, 0.6, 0.9)); + let b = vector_float::from(f32x4::new(-0.1, 0.5, -0.6, 0.9)); let d = i32x4::new( -0b10000000000000000000000000000000, 0, @@ -5828,15 +5878,15 @@ mod tests { 0, ); - assert_eq!(d, transmute(vec_cmpb(a, b))); + assert_eq!(d, i32x4::from(unsafe { vec_cmpb(a, b) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_ceil() { - let a: vector_float = transmute(f32x4::new(0.1, 0.5, 0.6, 0.9)); + fn test_vec_ceil() { + let a = vector_float::from(f32x4::new(0.1, 0.5, 0.6, 0.9)); let d = f32x4::new(1.0, 1.0, 1.0, 1.0); - assert_eq!(d, transmute(vec_ceil(a))); + assert_eq!(d, f32x4::from(unsafe { vec_ceil(a) })); } test_vec_2! { test_vec_andc, vec_andc, i32x4, @@ -5926,11 +5976,11 @@ mod tests { macro_rules! test_vec_abs { { $name: ident, $ty: ident, $a: expr, $d: expr } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a = vec_splats($a); - let a: s_t_l!($ty) = vec_abs(a); + fn $name() { + let a = unsafe { vec_splats($a) }; + let a: s_t_l!($ty) = unsafe { vec_abs(a) }; let d = $ty::splat($d); - assert_eq!(d, transmute(a)); + assert_eq!(d, $ty::from(a)); } } } @@ -5943,11 +5993,11 @@ mod tests { macro_rules! test_vec_abss { { $name: ident, $ty: ident, $a: expr, $d: expr } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a = vec_splats($a); - let a: s_t_l!($ty) = vec_abss(a); + fn $name() { + let a = unsafe { vec_splats($a) }; + let a: s_t_l!($ty) = unsafe { vec_abss(a) }; let d = $ty::splat($d); - assert_eq!(d, transmute(a)); + assert_eq!(d, $ty::from(a)); } } } @@ -5959,10 +6009,10 @@ mod tests { macro_rules! test_vec_splats { { $name: ident, $ty: ident, $a: expr } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = vec_splats($a); + fn $name() { + let a: s_t_l!($ty) = unsafe { vec_splats($a) }; let d = $ty::splat($a); - assert_eq!(d, transmute(a)); + assert_eq!(d, $ty::from(a)); } } } @@ -5978,10 +6028,10 @@ mod tests { macro_rules! test_vec_splat { { $name: ident, $fun: ident, $ty: ident, $a: expr, $b: expr} => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a = $fun::<$a>(); + fn $name() { + let a = unsafe { $fun::<$a>() }; let d = $ty::splat($b); - assert_eq!(d, transmute(a)); + assert_eq!(d, $ty::from(a)); } } } @@ -6073,12 +6123,12 @@ mod tests { macro_rules! test_vec_min { { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); + let b: s_t_l!($ty) = $ty::new($($b),+).into(); let d = $ty::new($($d),+); - let r : $ty = transmute(vec_min(a, b)); + let r = $ty::from(unsafe { vec_min(a, b) }); assert_eq!(d, r); } } @@ -6117,12 +6167,12 @@ mod tests { macro_rules! test_vec_max { { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); + let b: s_t_l!($ty) = $ty::new($($b),+).into(); let d = $ty::new($($d),+); - let r : $ty = transmute(vec_max(a, b)); + let r = $ty::from(unsafe { vec_max(a, b) }); assert_eq!(d, r); } } @@ -6163,13 +6213,13 @@ mod tests { $shorttype:ident, $longtype:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: $longtype = transmute($shorttype::new($($a),+)); - let b: $longtype = transmute($shorttype::new($($b),+)); - let c: vector_unsigned_char = transmute(u8x16::new($($c),+)); + fn $name() { + let a = $longtype::from($shorttype::new($($a),+)); + let b = $longtype::from($shorttype::new($($b),+)); + let c = vector_unsigned_char::from(u8x16::new($($c),+)); let d = $shorttype::new($($d),+); - let r: $shorttype = transmute(vec_perm(a, b, c)); + let r = $shorttype::from(unsafe { vec_perm(a, b, c) }); assert_eq!(d, r); } } @@ -6249,8 +6299,8 @@ mod tests { [0.0, 1.0, 1.0, 1.1]} #[simd_test(enable = "altivec")] - unsafe fn test_vec_madds() { - let a: vector_signed_short = transmute(i16x8::new( + fn test_vec_madds() { + let a = vector_signed_short::from(i16x8::new( 0 * 256, 1 * 256, 2 * 256, @@ -6260,19 +6310,19 @@ mod tests { 6 * 256, 7 * 256, )); - let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); + let b = vector_signed_short::from(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_signed_short::from(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); let d = i16x8::new(0, 3, 6, 9, 12, 15, 18, 21); - assert_eq!(d, transmute(vec_madds(a, b, c))); + assert_eq!(d, i16x8::from(unsafe { vec_madds(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_madd_float() { - let a: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); - let b: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); - let c: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); + fn test_vec_madd_float() { + let a = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); + let b = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); + let c = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); let d = f32x4::new( 0.1 * 0.1 + 0.1, 0.2 * 0.2 + 0.2, @@ -6280,26 +6330,26 @@ mod tests { 0.4 * 0.4 + 0.4, ); - assert_eq!(d, transmute(vec_madd(a, b, c))); + assert_eq!(d, f32x4::from(unsafe { vec_madd(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_nmsub_float() { - let a: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); - let b: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); - let c: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4)); + fn test_vec_nmsub_float() { + let a = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); + let b = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); + let c = vector_float::from(f32x4::new(0.1, 0.2, 0.3, 0.4)); let d = f32x4::new( -(0.1 * 0.1 - 0.1), -(0.2 * 0.2 - 0.2), -(0.3 * 0.3 - 0.3), -(0.4 * 0.4 - 0.4), ); - assert_eq!(d, transmute(vec_nmsub(a, b, c))); + assert_eq!(d, f32x4::from(unsafe { vec_nmsub(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mradds() { - let a: vector_signed_short = transmute(i16x8::new( + fn test_vec_mradds() { + let a = vector_signed_short::from(i16x8::new( 0 * 256, 1 * 256, 2 * 256, @@ -6309,25 +6359,25 @@ mod tests { 6 * 256, 7 * 256, )); - let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, i16::MAX - 1)); + let b = vector_signed_short::from(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_signed_short::from(i16x8::new(0, 1, 2, 3, 4, 5, 6, i16::MAX - 1)); let d = i16x8::new(0, 3, 6, 9, 12, 15, 18, i16::MAX); - assert_eq!(d, transmute(vec_mradds(a, b, c))); + assert_eq!(d, i16x8::from(unsafe { vec_mradds(a, b, c) })); } macro_rules! test_vec_mladd { {$name:ident, $sa:ident, $la:ident, $sbc:ident, $lbc:ident, $sd:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => { #[simd_test(enable = "altivec")] - unsafe fn $name() { - let a: $la = transmute($sa::new($($a),+)); - let b: $lbc = transmute($sbc::new($($b),+)); - let c = transmute($sbc::new($($c),+)); + fn $name() { + let a = $la::from($sa::new($($a),+)); + let b = $lbc::from($sbc::new($($b),+)); + let c = $sbc::new($($c),+).into(); let d = $sd::new($($d),+); - assert_eq!(d, transmute(vec_mladd(a, b, c))); + assert_eq!(d, $sd::from(unsafe { vec_mladd(a, b, c) })); } } } @@ -6335,24 +6385,24 @@ mod tests { test_vec_mladd! { test_vec_mladd_u16x8_u16x8, u16x8, vector_unsigned_short, u16x8, vector_unsigned_short, u16x8, [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56] } - test_vec_mladd! { test_vec_mladd_u16x8_i16x8, u16x8, vector_unsigned_short, i16x8, vector_unsigned_short, i16x8, + test_vec_mladd! { test_vec_mladd_u16x8_i16x8, u16x8, vector_unsigned_short, i16x8, vector_signed_short, i16x8, [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56] } test_vec_mladd! { test_vec_mladd_i16x8_u16x8, i16x8, vector_signed_short, u16x8, vector_unsigned_short, i16x8, [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56] } - test_vec_mladd! { test_vec_mladd_i16x8_i16x8, i16x8, vector_signed_short, i16x8, vector_unsigned_short, i16x8, + test_vec_mladd! { test_vec_mladd_i16x8_i16x8, i16x8, vector_signed_short, i16x8, vector_signed_short, i16x8, [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56] } #[simd_test(enable = "altivec")] - unsafe fn test_vec_msum_unsigned_char() { - let a: vector_unsigned_char = - transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); - let b: vector_unsigned_char = transmute(u8x16::new( + fn test_vec_msum_unsigned_char() { + let a = + vector_unsigned_char::from(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); + let b = vector_unsigned_char::from(u8x16::new( 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, )); - let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3)); + let c = vector_unsigned_int::from(u32x4::new(0, 1, 2, 3)); let d = u32x4::new( (0 + 1 + 2 + 3) * 255 + 0, (4 + 5 + 6 + 7) * 255 + 1, @@ -6360,17 +6410,17 @@ mod tests { (4 + 5 + 6 + 7) * 255 + 3, ); - assert_eq!(d, transmute(vec_msum(a, b, c))); + assert_eq!(d, u32x4::from(unsafe { vec_msum(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_msum_signed_char() { - let a: vector_signed_char = transmute(i8x16::new( + fn test_vec_msum_signed_char() { + let a = vector_signed_char::from(i8x16::new( 0, -1, 2, -3, 1, -1, 1, -1, 0, 1, 2, 3, 4, -5, -6, -7, )); - let b: vector_unsigned_char = - transmute(i8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); - let c: vector_signed_int = transmute(u32x4::new(0, 1, 2, 3)); + let b = + vector_unsigned_char::from(u8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); + let c = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new( (0 - 1 + 2 - 3) + 0, (0) + 1, @@ -6378,11 +6428,12 @@ mod tests { (4 - 5 - 6 - 7) + 3, ); - assert_eq!(d, transmute(vec_msum(a, b, c))); + assert_eq!(d, i32x4::from(unsafe { vec_msum(a, b, c) })); } + #[simd_test(enable = "altivec")] - unsafe fn test_vec_msum_unsigned_short() { - let a: vector_unsigned_short = transmute(u16x8::new( + fn test_vec_msum_unsigned_short() { + let a = vector_unsigned_short::from(u16x8::new( 0 * 256, 1 * 256, 2 * 256, @@ -6392,9 +6443,8 @@ mod tests { 6 * 256, 7 * 256, )); - let b: vector_unsigned_short = - transmute(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3)); + let b = vector_unsigned_short::from(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_unsigned_int::from(u32x4::new(0, 1, 2, 3)); let d = u32x4::new( (0 + 1) * 256 * 256 + 0, (2 + 3) * 256 * 256 + 1, @@ -6402,12 +6452,12 @@ mod tests { (6 + 7) * 256 * 256 + 3, ); - assert_eq!(d, transmute(vec_msum(a, b, c))); + assert_eq!(d, u32x4::from(unsafe { vec_msum(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_msum_signed_short() { - let a: vector_signed_short = transmute(i16x8::new( + fn test_vec_msum_signed_short() { + let a = vector_signed_short::from(i16x8::new( 0 * 256, -1 * 256, 2 * 256, @@ -6417,8 +6467,8 @@ mod tests { 6 * 256, -7 * 256, )); - let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); + let b = vector_signed_short::from(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new( (0 - 1) * 256 * 256 + 0, (2 - 3) * 256 * 256 + 1, @@ -6426,12 +6476,12 @@ mod tests { (6 - 7) * 256 * 256 + 3, ); - assert_eq!(d, transmute(vec_msum(a, b, c))); + assert_eq!(d, i32x4::from(unsafe { vec_msum(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_msums_unsigned() { - let a: vector_unsigned_short = transmute(u16x8::new( + fn test_vec_msums_unsigned() { + let a = vector_unsigned_short::from(u16x8::new( 0 * 256, 1 * 256, 2 * 256, @@ -6441,9 +6491,8 @@ mod tests { 6 * 256, 7 * 256, )); - let b: vector_unsigned_short = - transmute(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3)); + let b = vector_unsigned_short::from(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_unsigned_int::from(u32x4::new(0, 1, 2, 3)); let d = u32x4::new( (0 + 1) * 256 * 256 + 0, (2 + 3) * 256 * 256 + 1, @@ -6451,12 +6500,12 @@ mod tests { (6 + 7) * 256 * 256 + 3, ); - assert_eq!(d, transmute(vec_msums(a, b, c))); + assert_eq!(d, u32x4::from(unsafe { vec_msums(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_msums_signed() { - let a: vector_signed_short = transmute(i16x8::new( + fn test_vec_msums_signed() { + let a = vector_signed_short::from(i16x8::new( 0 * 256, -1 * 256, 2 * 256, @@ -6466,8 +6515,8 @@ mod tests { 6 * 256, -7 * 256, )); - let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); - let c: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); + let b = vector_signed_short::from(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256)); + let c = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new( (0 - 1) * 256 * 256 + 0, (2 - 3) * 256 * 256 + 1, @@ -6475,23 +6524,23 @@ mod tests { (6 - 7) * 256 * 256 + 3, ); - assert_eq!(d, transmute(vec_msums(a, b, c))); + assert_eq!(d, i32x4::from(unsafe { vec_msums(a, b, c) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_sum2s() { - let a: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); - let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); + fn test_vec_sum2s() { + let a = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); + let b = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new(0, 0 + 1 + 1, 0, 2 + 3 + 3); - assert_eq!(d, transmute(vec_sum2s(a, b))); + assert_eq!(d, i32x4::from(unsafe { vec_sum2s(a, b) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_sum4s_unsigned_char() { - let a: vector_unsigned_char = - transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); - let b: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3)); + fn test_vec_sum4s_unsigned_char() { + let a = + vector_unsigned_char::from(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); + let b = vector_unsigned_int::from(u32x4::new(0, 1, 2, 3)); let d = u32x4::new( 0 + 1 + 2 + 3 + 0, 4 + 5 + 6 + 7 + 1, @@ -6499,13 +6548,13 @@ mod tests { 4 + 5 + 6 + 7 + 3, ); - assert_eq!(d, transmute(vec_sum4s(a, b))); + assert_eq!(d, u32x4::from(unsafe { vec_sum4s(a, b) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_sum4s_signed_char() { - let a: vector_signed_char = - transmute(i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); - let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); + fn test_vec_sum4s_signed_char() { + let a = + vector_signed_char::from(i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); + let b = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new( 0 + 1 + 2 + 3 + 0, 4 + 5 + 6 + 7 + 1, @@ -6513,109 +6562,110 @@ mod tests { 4 + 5 + 6 + 7 + 3, ); - assert_eq!(d, transmute(vec_sum4s(a, b))); + assert_eq!(d, i32x4::from(unsafe { vec_sum4s(a, b) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_sum4s_signed_short() { - let a: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); - let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3)); + fn test_vec_sum4s_signed_short() { + let a = vector_signed_short::from(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); + let b = vector_signed_int::from(i32x4::new(0, 1, 2, 3)); let d = i32x4::new(0 + 1 + 0, 2 + 3 + 1, 4 + 5 + 2, 6 + 7 + 3); - assert_eq!(d, transmute(vec_sum4s(a, b))); + assert_eq!(d, i32x4::from(unsafe { vec_sum4s(a, b) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mule_unsigned_char() { - let a: vector_unsigned_char = - transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); + fn test_vec_mule_unsigned_char() { + let a = + vector_unsigned_char::from(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); let d = u16x8::new(0 * 0, 2 * 2, 4 * 4, 6 * 6, 0 * 0, 2 * 2, 4 * 4, 6 * 6); - assert_eq!(d, transmute(vec_mule(a, a))); + assert_eq!(d, u16x8::from(unsafe { vec_mule(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mule_signed_char() { - let a: vector_signed_char = transmute(i8x16::new( + fn test_vec_mule_signed_char() { + let a = vector_signed_char::from(i8x16::new( 0, 1, -2, 3, -4, 5, -6, 7, 0, 1, 2, 3, 4, 5, 6, 7, )); let d = i16x8::new(0 * 0, 2 * 2, 4 * 4, 6 * 6, 0 * 0, 2 * 2, 4 * 4, 6 * 6); - assert_eq!(d, transmute(vec_mule(a, a))); + assert_eq!(d, i16x8::from(unsafe { vec_mule(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mule_unsigned_short() { - let a: vector_unsigned_short = transmute(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); + fn test_vec_mule_unsigned_short() { + let a = vector_unsigned_short::from(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); let d = u32x4::new(0 * 0, 2 * 2, 4 * 4, 6 * 6); - assert_eq!(d, transmute(vec_mule(a, a))); + assert_eq!(d, u32x4::from(unsafe { vec_mule(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mule_signed_short() { - let a: vector_signed_short = transmute(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7)); + fn test_vec_mule_signed_short() { + let a = vector_signed_short::from(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7)); let d = i32x4::new(0 * 0, 2 * 2, 4 * 4, 6 * 6); - assert_eq!(d, transmute(vec_mule(a, a))); + assert_eq!(d, i32x4::from(unsafe { vec_mule(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mulo_unsigned_char() { - let a: vector_unsigned_char = - transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); + fn test_vec_mulo_unsigned_char() { + let a = + vector_unsigned_char::from(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7)); let d = u16x8::new(1 * 1, 3 * 3, 5 * 5, 7 * 7, 1 * 1, 3 * 3, 5 * 5, 7 * 7); - assert_eq!(d, transmute(vec_mulo(a, a))); + assert_eq!(d, u16x8::from(unsafe { vec_mulo(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mulo_signed_char() { - let a: vector_signed_char = transmute(i8x16::new( + fn test_vec_mulo_signed_char() { + let a = vector_signed_char::from(i8x16::new( 0, 1, -2, 3, -4, 5, -6, 7, 0, 1, 2, 3, 4, 5, 6, 7, )); let d = i16x8::new(1 * 1, 3 * 3, 5 * 5, 7 * 7, 1 * 1, 3 * 3, 5 * 5, 7 * 7); - assert_eq!(d, transmute(vec_mulo(a, a))); + assert_eq!(d, i16x8::from(unsafe { vec_mulo(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mulo_unsigned_short() { - let a: vector_unsigned_short = transmute(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); + fn test_vec_mulo_unsigned_short() { + let a = vector_unsigned_short::from(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)); let d = u32x4::new(1 * 1, 3 * 3, 5 * 5, 7 * 7); - assert_eq!(d, transmute(vec_mulo(a, a))); + assert_eq!(d, u32x4::from(unsafe { vec_mulo(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn test_vec_mulo_signed_short() { - let a: vector_signed_short = transmute(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7)); + fn test_vec_mulo_signed_short() { + let a = vector_signed_short::from(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7)); let d = i32x4::new(1 * 1, 3 * 3, 5 * 5, 7 * 7); - assert_eq!(d, transmute(vec_mulo(a, a))); + assert_eq!(d, i32x4::from(unsafe { vec_mulo(a, a) })); } #[simd_test(enable = "altivec")] - unsafe fn vec_add_i32x4_i32x4() { + fn vec_add_i32x4_i32x4() { let x = i32x4::new(1, 2, 3, 4); let y = i32x4::new(4, 3, 2, 1); - let x: vector_signed_int = transmute(x); - let y: vector_signed_int = transmute(y); - let z = vec_add(x, y); - assert_eq!(i32x4::splat(5), transmute(z)); + let x = vector_signed_int::from(x); + let y = vector_signed_int::from(y); + let z = unsafe { vec_add(x, y) }; + assert_eq!(i32x4::splat(5), i32x4::from(z)); } #[simd_test(enable = "altivec")] - unsafe fn vec_ctf_u32() { - let v: vector_unsigned_int = transmute(u32x4::new(u32::MIN, u32::MAX, u32::MAX, 42)); - let v2 = vec_ctf::<1, _>(v); - let r2: vector_float = transmute(f32x4::new(0.0, 2147483600.0, 2147483600.0, 21.0)); - let v4 = vec_ctf::<2, _>(v); - let r4: vector_float = transmute(f32x4::new(0.0, 1073741800.0, 1073741800.0, 10.5)); - let v8 = vec_ctf::<3, _>(v); - let r8: vector_float = transmute(f32x4::new(0.0, 536870900.0, 536870900.0, 5.25)); + fn vec_ctf_u32() { + let v = vector_unsigned_int::from(u32x4::new(u32::MIN, u32::MAX, u32::MAX, 42)); + let v2 = unsafe { vec_ctf::<1, _>(v) }; + let r2 = vector_float::from(f32x4::new(0.0, 2147483600.0, 2147483600.0, 21.0)); + let v4 = unsafe { vec_ctf::<2, _>(v) }; + let r4 = vector_float::from(f32x4::new(0.0, 1073741800.0, 1073741800.0, 10.5)); + let v8 = unsafe { vec_ctf::<3, _>(v) }; + let r8 = vector_float::from(f32x4::new(0.0, 536870900.0, 536870900.0, 5.25)); let check = |a, b| { - let r = transmute(vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON))); + let r = + m32x4::from(unsafe { vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON)) }); let e = m32x4::new(true, true, true, true); assert_eq!(e, r); }; @@ -6626,26 +6676,32 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_ctu() { + fn test_vec_ctu() { let v = u32x4::new(u32::MIN, u32::MAX, u32::MAX, 42); - let v2: u32x4 = transmute(vec_ctu::<1>(transmute(f32x4::new( - 0.0, - 2147483600.0, - 2147483600.0, - 21.0, - )))); - let v4: u32x4 = transmute(vec_ctu::<2>(transmute(f32x4::new( - 0.0, - 1073741800.0, - 1073741800.0, - 10.5, - )))); - let v8: u32x4 = transmute(vec_ctu::<3>(transmute(f32x4::new( - 0.0, - 536870900.0, - 536870900.0, - 5.25, - )))); + let v2 = u32x4::from(unsafe { + vec_ctu::<1>(vector_float::from(f32x4::new( + 0.0, + 2147483600.0, + 2147483600.0, + 21.0, + ))) + }); + let v4 = u32x4::from(unsafe { + vec_ctu::<2>(vector_float::from(f32x4::new( + 0.0, + 1073741800.0, + 1073741800.0, + 10.5, + ))) + }); + let v8 = u32x4::from(unsafe { + vec_ctu::<3>(vector_float::from(f32x4::new( + 0.0, + 536870900.0, + 536870900.0, + 5.25, + ))) + }); assert_eq!(v2, v); assert_eq!(v4, v); @@ -6653,18 +6709,18 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn vec_ctf_i32() { - let v: vector_signed_int = transmute(i32x4::new(i32::MIN, i32::MAX, i32::MAX - 42, 42)); - let v2 = vec_ctf::<1, _>(v); - let r2: vector_float = - transmute(f32x4::new(-1073741800.0, 1073741800.0, 1073741800.0, 21.0)); - let v4 = vec_ctf::<2, _>(v); - let r4: vector_float = transmute(f32x4::new(-536870900.0, 536870900.0, 536870900.0, 10.5)); - let v8 = vec_ctf::<3, _>(v); - let r8: vector_float = transmute(f32x4::new(-268435460.0, 268435460.0, 268435460.0, 5.25)); + fn vec_ctf_i32() { + let v = vector_signed_int::from(i32x4::new(i32::MIN, i32::MAX, i32::MAX - 42, 42)); + let v2 = unsafe { vec_ctf::<1, _>(v) }; + let r2 = vector_float::from(f32x4::new(-1073741800.0, 1073741800.0, 1073741800.0, 21.0)); + let v4 = unsafe { vec_ctf::<2, _>(v) }; + let r4 = vector_float::from(f32x4::new(-536870900.0, 536870900.0, 536870900.0, 10.5)); + let v8 = unsafe { vec_ctf::<3, _>(v) }; + let r8 = vector_float::from(f32x4::new(-268435460.0, 268435460.0, 268435460.0, 5.25)); let check = |a, b| { - let r = transmute(vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON))); + let r = + m32x4::from(unsafe { vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON)) }); println!("{:?} {:?}", a, b); let e = m32x4::new(true, true, true, true); assert_eq!(e, r); @@ -6676,26 +6732,32 @@ mod tests { } #[simd_test(enable = "altivec")] - unsafe fn test_vec_cts() { + fn test_vec_cts() { let v = i32x4::new(i32::MIN, i32::MAX, i32::MAX, 42); - let v2: i32x4 = transmute(vec_cts::<1>(transmute(f32x4::new( - -1073741800.0, - 1073741800.0, - 1073741800.0, - 21.0, - )))); - let v4: i32x4 = transmute(vec_cts::<2>(transmute(f32x4::new( - -536870900.0, - 536870900.0, - 536870900.0, - 10.5, - )))); - let v8: i32x4 = transmute(vec_cts::<3>(transmute(f32x4::new( - -268435460.0, - 268435460.0, - 268435460.0, - 5.25, - )))); + let v2 = i32x4::from(unsafe { + vec_cts::<1>(transmute(f32x4::new( + -1073741800.0, + 1073741800.0, + 1073741800.0, + 21.0, + ))) + }); + let v4 = i32x4::from(unsafe { + vec_cts::<2>(transmute(f32x4::new( + -536870900.0, + 536870900.0, + 536870900.0, + 10.5, + ))) + }); + let v8 = i32x4::from(unsafe { + vec_cts::<3>(transmute(f32x4::new( + -268435460.0, + 268435460.0, + 268435460.0, + 5.25, + ))) + }); assert_eq!(v2, v); assert_eq!(v4, v); diff --git a/library/stdarch/crates/core_arch/src/powerpc/vsx.rs b/library/stdarch/crates/core_arch/src/powerpc/vsx.rs index ca9fcaabe8b2..0aac23617340 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/vsx.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/vsx.rs @@ -9,6 +9,7 @@ #![allow(non_camel_case_types)] use crate::core_arch::powerpc::*; +use crate::core_arch::simd::*; #[cfg(test)] use stdarch_test::assert_instr; @@ -34,6 +35,22 @@ types! { // pub struct vector_unsigned___int128 = i128x1; } +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for vector_bool_long { + #[inline] + fn from(value: m64x2) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +impl From for m64x2 { + #[inline] + fn from(value: vector_bool_long) -> Self { + unsafe { transmute(value) } + } +} + #[allow(improper_ctypes)] unsafe extern "C" { #[link_name = "llvm.ppc.altivec.vperm"] @@ -46,7 +63,6 @@ unsafe extern "C" { mod sealed { use super::*; - use crate::core_arch::simd::*; #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub trait VectorPermDI { @@ -221,14 +237,16 @@ mod tests { macro_rules! test_vec_xxpermdi { {$name:ident, $shorttype:ident, $longtype:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => { #[simd_test(enable = "vsx")] - unsafe fn $name() { - let a: $longtype = transmute($shorttype::new($($a),+, $($b),+)); - let b = transmute($shorttype::new($($c),+, $($d),+)); + fn $name() { + let a = $longtype::from($shorttype::new($($a),+, $($b),+)); + let b = $longtype::from($shorttype::new($($c),+, $($d),+)); - assert_eq!($shorttype::new($($a),+, $($c),+), transmute(vec_xxpermdi::<_, 0>(a, b))); - assert_eq!($shorttype::new($($b),+, $($c),+), transmute(vec_xxpermdi::<_, 1>(a, b))); - assert_eq!($shorttype::new($($a),+, $($d),+), transmute(vec_xxpermdi::<_, 2>(a, b))); - assert_eq!($shorttype::new($($b),+, $($d),+), transmute(vec_xxpermdi::<_, 3>(a, b))); + unsafe { + assert_eq!($shorttype::new($($a),+, $($c),+), $shorttype::from(vec_xxpermdi::<_, 0>(a, b))); + assert_eq!($shorttype::new($($b),+, $($c),+), $shorttype::from(vec_xxpermdi::<_, 1>(a, b))); + assert_eq!($shorttype::new($($a),+, $($d),+), $shorttype::from(vec_xxpermdi::<_, 2>(a, b))); + assert_eq!($shorttype::new($($b),+, $($d),+), $shorttype::from(vec_xxpermdi::<_, 3>(a, b))); + } } } } diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index e1f841030c00..346cd674df66 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -51,6 +51,54 @@ types! { pub struct vector_double(2 x f64); } +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for vector_bool_char { + #[inline] + fn from(value: m8x16) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for m8x16 { + #[inline] + fn from(value: vector_bool_char) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for vector_bool_short { + #[inline] + fn from(value: m16x8) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for m16x8 { + #[inline] + fn from(value: vector_bool_short) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for vector_bool_int { + #[inline] + fn from(value: m32x4) -> Self { + unsafe { transmute(value) } + } +} + +#[unstable(feature = "stdarch_s390x", issue = "135681")] +impl From for m32x4 { + #[inline] + fn from(value: vector_bool_int) -> Self { + unsafe { transmute(value) } + } +} + #[repr(C, packed)] struct PackedTuple { x: T, @@ -6051,27 +6099,16 @@ mod tests { } macro_rules! test_vec_1 { - { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => { - #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: vector_float = transmute(f32x4::new($($a),+)); - - let d: vector_float = transmute(f32x4::new($($d),+)); - let r = transmute(vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON))); - let e = m32x4::new(true, true, true, true); - assert_eq!(e, r); - } - }; { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($d:expr),+] } => { test_vec_1! { $name, $fn, $ty -> $ty, [$($a),+], [$($d),+] } }; { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); + fn $name() { + let a: s_t_l!($ty) = $ty::new($($a),+).into(); let d = $ty_out::new($($d),+); - let r : $ty_out = transmute($fn(a)); + let r = $ty_out::from(unsafe { $fn(a) }); assert_eq!(d, r); } } @@ -6086,35 +6123,23 @@ mod tests { }; { $name: ident, $fn:ident, $ty1: ident, $ty2: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: s_t_l!($ty1) = transmute($ty1::new($($a),+)); - let b: s_t_l!($ty2) = transmute($ty2::new($($b),+)); + fn $name() { + let a: s_t_l!($ty1) = $ty1::new($($a),+).into(); + let b: s_t_l!($ty2) = $ty2::new($($b),+).into(); let d = $ty_out::new($($d),+); - let r : $ty_out = transmute($fn(a, b)); + let r = $ty_out::from(unsafe { $fn(a, b) }); assert_eq!(d, r); } }; - { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => { - #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); - - let r : $ty_out = transmute($fn(a, b)); - assert_eq!($d, r); - } - } } #[simd_test(enable = "vector")] - unsafe fn vec_add_i32x4_i32x4() { - let x = i32x4::new(1, 2, 3, 4); - let y = i32x4::new(4, 3, 2, 1); - let x: vector_signed_int = transmute(x); - let y: vector_signed_int = transmute(y); - let z = vec_add(x, y); - assert_eq!(i32x4::splat(5), transmute(z)); + fn vec_add_i32x4_i32x4() { + let x = vector_signed_int::from(i32x4::new(1, 2, 3, 4)); + let y = vector_signed_int::from(i32x4::new(4, 3, 2, 1)); + let z = unsafe { vec_add(x, y) }; + assert_eq!(i32x4::splat(5), i32x4::from(z)); } macro_rules! test_vec_sub { @@ -6232,11 +6257,11 @@ mod tests { macro_rules! test_vec_abs { { $name: ident, $ty: ident, $a: expr, $d: expr } => { #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: s_t_l!($ty) = vec_splats($a); - let a: s_t_l!($ty) = vec_abs(a); + fn $name() { + let a: s_t_l!($ty) = unsafe { vec_splats($a) }; + let a: s_t_l!($ty) = unsafe { vec_abs(a) }; let d = $ty::splat($d); - assert_eq!(d, transmute(a)); + assert_eq!(d, $ty::from(a)); } } } @@ -6386,7 +6411,7 @@ mod tests { [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], [4, 2, 1, 8] } - test_vec_2! { test_vec_sral_pos, vec_sral, u32x4, u8x16 -> i32x4, + test_vec_2! { test_vec_sral_pos, vec_sral, u32x4, u8x16 -> u32x4, [0b1000, 0b1000, 0b1000, 0b1000], [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], [4, 2, 1, 8] } @@ -6423,13 +6448,13 @@ mod tests { $shorttype:ident, $longtype:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => { #[simd_test(enable = "vector")] - unsafe fn $name() { - let a: $longtype = transmute($shorttype::new($($a),+)); - let b: $longtype = transmute($shorttype::new($($b),+)); - let c: vector_unsigned_char = transmute(u8x16::new($($c),+)); + fn $name() { + let a = $longtype::from($shorttype::new($($a),+)); + let b = $longtype::from($shorttype::new($($b),+)); + let c = vector_unsigned_char::from(u8x16::new($($c),+)); let d = $shorttype::new($($d),+); - let r: $shorttype = transmute(vec_perm(a, b, c)); + let r = $shorttype::from(unsafe { vec_perm(a, b, c) }); assert_eq!(d, r); } } @@ -6512,46 +6537,46 @@ mod tests { [core::f32::consts::PI, 1.0, 25.0, 2.0], [core::f32::consts::PI.sqrt(), 1.0, 5.0, core::f32::consts::SQRT_2] } - test_vec_2! { test_vec_find_any_eq, vec_find_any_eq, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_eq, vec_find_any_eq, i32x4, i32x4 -> i32x4, [1, -2, 3, -4], [-5, 3, -7, 8], - [0, 0, 0xFFFFFFFF, 0] + [0, 0, !0, 0] } - test_vec_2! { test_vec_find_any_ne, vec_find_any_ne, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_ne, vec_find_any_ne, i32x4, i32x4 -> i32x4, [1, -2, 3, -4], [-5, 3, -7, 8], - [0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF] + [!0, !0, 0, !0] } - test_vec_2! { test_vec_find_any_eq_idx_1, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_eq_idx_1, vec_find_any_eq_idx, i32x4, i32x4 -> i32x4, [1, 2, 3, 4], [5, 3, 7, 8], [0, 8, 0, 0] } - test_vec_2! { test_vec_find_any_eq_idx_2, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_eq_idx_2, vec_find_any_eq_idx, i32x4, i32x4 -> i32x4, [1, 2, 3, 4], [5, 6, 7, 8], [0, 16, 0, 0] } - test_vec_2! { test_vec_find_any_ne_idx_1, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_ne_idx_1, vec_find_any_ne_idx, i32x4, i32x4 -> i32x4, [1, 2, 3, 4], [1, 5, 3, 4], [0, 4, 0, 0] } - test_vec_2! { test_vec_find_any_ne_idx_2, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_ne_idx_2, vec_find_any_ne_idx, i32x4, i32x4 -> i32x4, [1, 2, 3, 4], [1, 2, 3, 4], [0, 16, 0, 0] } - test_vec_2! { test_vec_find_any_eq_or_0_idx_1, vec_find_any_eq_or_0_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_eq_or_0_idx_1, vec_find_any_eq_or_0_idx, i32x4, i32x4 -> i32x4, [1, 2, 0, 4], [5, 6, 7, 8], [0, 8, 0, 0] } - test_vec_2! { test_vec_find_any_ne_or_0_idx_1, vec_find_any_ne_or_0_idx, i32x4, i32x4 -> u32x4, + test_vec_2! { test_vec_find_any_ne_or_0_idx_1, vec_find_any_ne_or_0_idx, i32x4, i32x4 -> i32x4, [1, 2, 0, 4], [1, 2, 3, 4], [0, 8, 0, 0] From e164dca633aa9dcc6f7929ac69be4f16e30d7ddd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Jan 2026 10:34:44 +0100 Subject: [PATCH 04/81] Don't expect specific instructions for _mm256_set_pd/_mm_set_ps These don't correspond to specific instructions and will produce different instructions on x86/x86_64 based on ABI details. --- library/stdarch/crates/core_arch/src/x86/avx.rs | 1 - library/stdarch/crates/core_arch/src/x86/sse.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index 7b4b210bacf4..74fc2db13dcd 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -2426,7 +2426,6 @@ pub const fn _mm256_setzero_si256() -> __m256i { #[inline] #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. -#[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_set_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index b83274e60e72..2c4439a3f3a5 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -968,7 +968,7 @@ pub const fn _mm_set_ps1(a: f32) -> __m128 { /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_ps) #[inline] #[target_feature(enable = "sse")] -#[cfg_attr(test, assert_instr(unpcklps))] +// This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_set_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { From 293b61e4440234fddee48dba109d61d86f327b5c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Jan 2026 11:07:06 +0100 Subject: [PATCH 05/81] Ignore non-yml files in generator Otherwise this picks up vim .swp files. --- library/stdarch/crates/stdarch-gen-arm/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/stdarch/crates/stdarch-gen-arm/src/main.rs b/library/stdarch/crates/stdarch-gen-arm/src/main.rs index 9bf7d0981deb..e14e2782485b 100644 --- a/library/stdarch/crates/stdarch-gen-arm/src/main.rs +++ b/library/stdarch/crates/stdarch-gen-arm/src/main.rs @@ -139,6 +139,7 @@ fn parse_args() -> Vec<(PathBuf, Option)> { .into_iter() .filter_map(Result::ok) .filter(|f| f.file_type().is_file()) + .filter(|f| f.file_name().to_string_lossy().ends_with(".yml")) .map(|f| (f.into_path(), out_dir.clone())) .collect() } From f5d594a309d31c83d55fd67d3178429c70b75d95 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Jan 2026 11:21:11 +0100 Subject: [PATCH 06/81] Change lanes vcopy_lane tests to avoid zip2 --- .../core_arch/src/aarch64/neon/generated.rs | 78 +++++++++---------- .../spec/neon/aarch64.spec.yml | 8 +- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 9507b71106dd..3d5d07ac1b4e 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -4092,7 +4092,7 @@ pub fn vcmlaq_rot90_laneq_f32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_f32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_f32( @@ -4113,7 +4113,7 @@ pub fn vcopy_lane_f32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t { @@ -4137,7 +4137,7 @@ pub fn vcopy_lane_s8(a: int8x8_t, b: int8x8_ #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t { @@ -4157,7 +4157,7 @@ pub fn vcopy_lane_s16(a: int16x4_t, b: int16 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t { @@ -4175,7 +4175,7 @@ pub fn vcopy_lane_s32(a: int32x2_t, b: int32 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t { @@ -4199,7 +4199,7 @@ pub fn vcopy_lane_u8(a: uint8x8_t, b: uint8x #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_u16( @@ -4222,7 +4222,7 @@ pub fn vcopy_lane_u16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_u32( @@ -4243,7 +4243,7 @@ pub fn vcopy_lane_u32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t { @@ -4267,7 +4267,7 @@ pub fn vcopy_lane_p8(a: poly8x8_t, b: poly8x #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_lane_p16( @@ -4290,7 +4290,7 @@ pub fn vcopy_lane_p16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_f32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_f32( @@ -4312,7 +4312,7 @@ pub fn vcopy_laneq_f32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_s8(a: int8x8_t, b: int8x16_t) -> int8x8_t { @@ -4338,7 +4338,7 @@ pub fn vcopy_laneq_s8(a: int8x8_t, b: int8x1 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_s16( @@ -4362,7 +4362,7 @@ pub fn vcopy_laneq_s16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_s32( @@ -4384,7 +4384,7 @@ pub fn vcopy_laneq_s32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_u8( @@ -4413,7 +4413,7 @@ pub fn vcopy_laneq_u8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_u16( @@ -4437,7 +4437,7 @@ pub fn vcopy_laneq_u16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_u32( @@ -4459,7 +4459,7 @@ pub fn vcopy_laneq_u32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_p8( @@ -4488,7 +4488,7 @@ pub fn vcopy_laneq_p8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopy_laneq_p16( @@ -4624,7 +4624,7 @@ pub fn vcopyq_lane_p64( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_s8(a: int8x16_t, b: int8x8_t) -> int8x16_t { @@ -4994,7 +4994,7 @@ pub fn vcopyq_lane_s8(a: int8x16_t, b: int8x #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_s16( @@ -5022,7 +5022,7 @@ pub fn vcopyq_lane_s16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_s32( @@ -5046,7 +5046,7 @@ pub fn vcopyq_lane_s32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_u8( @@ -5419,7 +5419,7 @@ pub fn vcopyq_lane_u8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_u16( @@ -5447,7 +5447,7 @@ pub fn vcopyq_lane_u16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_u32( @@ -5471,7 +5471,7 @@ pub fn vcopyq_lane_u32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_p8( @@ -5844,7 +5844,7 @@ pub fn vcopyq_lane_p8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_lane_p16( @@ -5872,7 +5872,7 @@ pub fn vcopyq_lane_p16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_f32( @@ -5895,7 +5895,7 @@ pub fn vcopyq_laneq_f32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f64)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_f64( @@ -5916,7 +5916,7 @@ pub fn vcopyq_laneq_f64( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_s8( @@ -6287,7 +6287,7 @@ pub fn vcopyq_laneq_s8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_s16( @@ -6314,7 +6314,7 @@ pub fn vcopyq_laneq_s16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_s32( @@ -6337,7 +6337,7 @@ pub fn vcopyq_laneq_s32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s64)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_s64( @@ -6358,7 +6358,7 @@ pub fn vcopyq_laneq_s64( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_u8( @@ -6729,7 +6729,7 @@ pub fn vcopyq_laneq_u8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_u16( @@ -6756,7 +6756,7 @@ pub fn vcopyq_laneq_u16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u32)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_u32( @@ -6779,7 +6779,7 @@ pub fn vcopyq_laneq_u32( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u64)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_u64( @@ -6800,7 +6800,7 @@ pub fn vcopyq_laneq_u64( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p8)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_p8( @@ -7171,7 +7171,7 @@ pub fn vcopyq_laneq_p8( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p16)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_p16( @@ -7198,7 +7198,7 @@ pub fn vcopyq_laneq_p16( #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p64)"] #[inline(always)] #[target_feature(enable = "neon")] -#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))] +#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 0))] #[rustc_legacy_const_generics(1, 3)] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vcopyq_laneq_p64( diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index a9bc377924dd..a099c2c8d694 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -8958,7 +8958,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"] return_type: "{neon_type[2]}" attr: - - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 1']]}]] + - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['1', '3']] - FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']] static_defs: ['const LANE1: i32, const LANE2: i32'] @@ -8983,7 +8983,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"] return_type: "{neon_type[2]}" attr: - - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 1']]}]] + - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['1', '3']] - FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']] static_defs: ['const LANE1: i32, const LANE2: i32'] @@ -9008,7 +9008,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"] return_type: "{neon_type[2]}" attr: - - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 1']]}]] + - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['1', '3']] - FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']] static_defs: ['const LANE1: i32, const LANE2: i32'] @@ -9037,7 +9037,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"] return_type: "{neon_type[2]}" attr: - - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 1']]}]] + - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [mov, 'LANE1 = 0', 'LANE2 = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['1', '3']] - FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']] static_defs: ['const LANE1: i32, const LANE2: i32'] From b500dd3f6b5af7e198a8a307d9eadcd8891dad26 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Jan 2026 11:28:32 +0100 Subject: [PATCH 07/81] Adjust expected output for vrfin It actually generates vrfin now --- library/stdarch/crates/core_arch/src/powerpc/altivec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index fb1a9d8ed9e2..0e238c532553 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -3249,7 +3249,7 @@ mod sealed { unsafe fn vec_round(self) -> Self; } - test_impl! { vec_vrfin(a: vector_float) -> vector_float [vrfin, xvrspic] } + test_impl! { vec_vrfin(a: vector_float) -> vector_float [vrfin, vrfin] } #[unstable(feature = "stdarch_powerpc", issue = "111145")] impl VectorRound for vector_float { From 9ea3034b584962c763d970d49b897e69dadf1061 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 31 Jan 2026 17:15:16 +0100 Subject: [PATCH 08/81] powerpc: implement `vnmsubfp` using `intrinsics::simd` --- .../stdarch/crates/core_arch/src/powerpc/altivec.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index fb1a9d8ed9e2..9d54abc5833b 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -129,8 +129,6 @@ unsafe extern "C" { b: vector_signed_short, c: vector_signed_int, ) -> vector_signed_int; - #[link_name = "llvm.ppc.altivec.vnmsubfp"] - fn vnmsubfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float; #[link_name = "llvm.ppc.altivec.vsum2sws"] fn vsum2sws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int; #[link_name = "llvm.ppc.altivec.vsum4ubs"] @@ -1881,9 +1879,9 @@ mod sealed { #[inline] #[target_feature(enable = "altivec")] - #[cfg_attr(test, assert_instr(vnmsubfp))] - unsafe fn vec_vnmsubfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float { - vnmsubfp(a, b, c) + #[cfg_attr(test, assert_instr(xvnmsubasp))] + pub unsafe fn vec_vnmsubfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float { + simd_neg(simd_fma(a, b, simd_neg(c))) } #[inline] @@ -4281,7 +4279,7 @@ pub unsafe fn vec_madd(a: vector_float, b: vector_float, c: vector_float) -> vec #[target_feature(enable = "altivec")] #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub unsafe fn vec_nmsub(a: vector_float, b: vector_float, c: vector_float) -> vector_float { - vnmsubfp(a, b, c) + sealed::vec_vnmsubfp(a, b, c) } /// Vector Select From ebc618aab5f6476b215f2b908cbf919765534f6d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 31 Jan 2026 18:47:56 +0100 Subject: [PATCH 09/81] wasm: use `intrinsics::simd` for the narrow functions --- .../crates/core_arch/src/wasm32/simd128.rs | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs index c864d6a516e0..e1a375496590 100644 --- a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs +++ b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs @@ -86,10 +86,6 @@ unsafe extern "unadjusted" { fn llvm_i8x16_all_true(x: simd::i8x16) -> i32; #[link_name = "llvm.wasm.bitmask.v16i8"] fn llvm_bitmask_i8x16(a: simd::i8x16) -> i32; - #[link_name = "llvm.wasm.narrow.signed.v16i8.v8i16"] - fn llvm_narrow_i8x16_s(a: simd::i16x8, b: simd::i16x8) -> simd::i8x16; - #[link_name = "llvm.wasm.narrow.unsigned.v16i8.v8i16"] - fn llvm_narrow_i8x16_u(a: simd::i16x8, b: simd::i16x8) -> simd::i8x16; #[link_name = "llvm.wasm.avgr.unsigned.v16i8"] fn llvm_avgr_u_i8x16(a: simd::i8x16, b: simd::i8x16) -> simd::i8x16; @@ -103,10 +99,6 @@ unsafe extern "unadjusted" { fn llvm_i16x8_all_true(x: simd::i16x8) -> i32; #[link_name = "llvm.wasm.bitmask.v8i16"] fn llvm_bitmask_i16x8(a: simd::i16x8) -> i32; - #[link_name = "llvm.wasm.narrow.signed.v8i16.v4i32"] - fn llvm_narrow_i16x8_s(a: simd::i32x4, b: simd::i32x4) -> simd::i16x8; - #[link_name = "llvm.wasm.narrow.unsigned.v8i16.v4i32"] - fn llvm_narrow_i16x8_u(a: simd::i32x4, b: simd::i32x4) -> simd::i16x8; #[link_name = "llvm.wasm.avgr.unsigned.v8i16"] fn llvm_avgr_u_i16x8(a: simd::i16x8, b: simd::i16x8) -> simd::i16x8; @@ -2281,7 +2273,23 @@ pub use i8x16_bitmask as u8x16_bitmask; #[doc(alias("i8x16.narrow_i16x8_s"))] #[stable(feature = "wasm_simd", since = "1.54.0")] pub fn i8x16_narrow_i16x8(a: v128, b: v128) -> v128 { - unsafe { llvm_narrow_i8x16_s(a.as_i16x8(), b.as_i16x8()).v128() } + unsafe { + let v: simd::i16x16 = simd_shuffle!( + a.as_i16x8(), + b.as_i16x8(), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + ); + + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let v = simd_select(simd_gt::<_, simd::i16x16>(v, max), max, v); + let v = simd_select(simd_lt::<_, simd::i16x16>(v, min), min, v); + + let v: simd::i8x16 = simd_cast(v); + + v.v128() + } } /// Converts two input vectors into a smaller lane vector by narrowing each @@ -2295,7 +2303,23 @@ pub fn i8x16_narrow_i16x8(a: v128, b: v128) -> v128 { #[doc(alias("i8x16.narrow_i16x8_u"))] #[stable(feature = "wasm_simd", since = "1.54.0")] pub fn u8x16_narrow_i16x8(a: v128, b: v128) -> v128 { - unsafe { llvm_narrow_i8x16_u(a.as_i16x8(), b.as_i16x8()).v128() } + unsafe { + let v: simd::i16x16 = simd_shuffle!( + a.as_i16x8(), + b.as_i16x8(), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + ); + + let max = simd_splat(i16::from(u8::MAX)); + let min = simd_splat(i16::from(u8::MIN)); + + let v = simd_select(simd_gt::<_, simd::i16x16>(v, max), max, v); + let v = simd_select(simd_lt::<_, simd::i16x16>(v, min), min, v); + + let v: simd::u8x16 = simd_cast(v); + + v.v128() + } } /// Shifts each lane to the left by the specified number of bits. @@ -2593,7 +2617,19 @@ pub use i16x8_bitmask as u16x8_bitmask; #[doc(alias("i16x8.narrow_i32x4_s"))] #[stable(feature = "wasm_simd", since = "1.54.0")] pub fn i16x8_narrow_i32x4(a: v128, b: v128) -> v128 { - unsafe { llvm_narrow_i16x8_s(a.as_i32x4(), b.as_i32x4()).v128() } + unsafe { + let v: simd::i32x8 = simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]); + + let max = simd_splat(i32::from(i16::MAX)); + let min = simd_splat(i32::from(i16::MIN)); + + let v = simd_select(simd_gt::<_, simd::i32x8>(v, max), max, v); + let v = simd_select(simd_lt::<_, simd::i32x8>(v, min), min, v); + + let v: simd::i16x8 = simd_cast(v); + + v.v128() + } } /// Converts two input vectors into a smaller lane vector by narrowing each @@ -2607,7 +2643,19 @@ pub fn i16x8_narrow_i32x4(a: v128, b: v128) -> v128 { #[doc(alias("i16x8.narrow_i32x4_u"))] #[stable(feature = "wasm_simd", since = "1.54.0")] pub fn u16x8_narrow_i32x4(a: v128, b: v128) -> v128 { - unsafe { llvm_narrow_i16x8_u(a.as_i32x4(), b.as_i32x4()).v128() } + unsafe { + let v: simd::i32x8 = simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]); + + let max = simd_splat(i32::from(u16::MAX)); + let min = simd_splat(i32::from(u16::MIN)); + + let v = simd_select(simd_gt::<_, simd::i32x8>(v, max), max, v); + let v = simd_select(simd_lt::<_, simd::i32x8>(v, min), min, v); + + let v: simd::u16x8 = simd_cast(v); + + v.v128() + } } /// Converts low half of the smaller lane vector to a larger lane From e40ae4fe2c8f0b08265d0a40a59a55f46c65e865 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 31 Jan 2026 22:11:50 +0100 Subject: [PATCH 10/81] x86: use `intrinsics::simd` for `hadds`/`hsubs` --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 36 +++++++++++++++---- .../stdarch/crates/core_arch/src/x86/ssse3.rs | 22 +++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 6a39a0aaf8fe..83aef753c9d9 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -991,7 +991,21 @@ pub const fn _mm256_hadd_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vphaddsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_hadds_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(phaddsw(a.as_i16x16(), b.as_i16x16())) } + let a = a.as_i16x16(); + let b = b.as_i16x16(); + unsafe { + let even: i16x16 = simd_shuffle!( + a, + b, + [0, 2, 4, 6, 16, 18, 20, 22, 8, 10, 12, 14, 24, 26, 28, 30] + ); + let odd: i16x16 = simd_shuffle!( + a, + b, + [1, 3, 5, 7, 17, 19, 21, 23, 9, 11, 13, 15, 25, 27, 29, 31] + ); + simd_saturating_add(even, odd).as_m256i() + } } /// Horizontally subtract adjacent pairs of 16-bit integers in `a` and `b`. @@ -1047,7 +1061,21 @@ pub const fn _mm256_hsub_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vphsubsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_hsubs_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(phsubsw(a.as_i16x16(), b.as_i16x16())) } + let a = a.as_i16x16(); + let b = b.as_i16x16(); + unsafe { + let even: i16x16 = simd_shuffle!( + a, + b, + [0, 2, 4, 6, 16, 18, 20, 22, 8, 10, 12, 14, 24, 26, 28, 30] + ); + let odd: i16x16 = simd_shuffle!( + a, + b, + [1, 3, 5, 7, 17, 19, 21, 23, 9, 11, 13, 15, 25, 27, 29, 31] + ); + simd_saturating_sub(even, odd).as_m256i() + } } /// Returns values from `slice` at offsets determined by `offsets * scale`, @@ -3791,10 +3819,6 @@ pub const fn _mm256_extract_epi16(a: __m256i) -> i32 { #[allow(improper_ctypes)] unsafe extern "C" { - #[link_name = "llvm.x86.avx2.phadd.sw"] - fn phaddsw(a: i16x16, b: i16x16) -> i16x16; - #[link_name = "llvm.x86.avx2.phsub.sw"] - fn phsubsw(a: i16x16, b: i16x16) -> i16x16; #[link_name = "llvm.x86.avx2.pmadd.wd"] fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; #[link_name = "llvm.x86.avx2.pmadd.ub.sw"] diff --git a/library/stdarch/crates/core_arch/src/x86/ssse3.rs b/library/stdarch/crates/core_arch/src/x86/ssse3.rs index 4426a3274c38..1d7a97944a37 100644 --- a/library/stdarch/crates/core_arch/src/x86/ssse3.rs +++ b/library/stdarch/crates/core_arch/src/x86/ssse3.rs @@ -188,7 +188,13 @@ pub const fn _mm_hadd_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(phaddsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_hadds_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(phaddsw128(a.as_i16x8(), b.as_i16x8())) } + let a = a.as_i16x8(); + let b = b.as_i16x8(); + unsafe { + let even: i16x8 = simd_shuffle!(a, b, [0, 2, 4, 6, 8, 10, 12, 14]); + let odd: i16x8 = simd_shuffle!(a, b, [1, 3, 5, 7, 9, 11, 13, 15]); + simd_saturating_add(even, odd).as_m128i() + } } /// Horizontally adds the adjacent pairs of values contained in 2 packed @@ -240,7 +246,13 @@ pub const fn _mm_hsub_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(phsubsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_hsubs_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(phsubsw128(a.as_i16x8(), b.as_i16x8())) } + let a = a.as_i16x8(); + let b = b.as_i16x8(); + unsafe { + let even: i16x8 = simd_shuffle!(a, b, [0, 2, 4, 6, 8, 10, 12, 14]); + let odd: i16x8 = simd_shuffle!(a, b, [1, 3, 5, 7, 9, 11, 13, 15]); + simd_saturating_sub(even, odd).as_m128i() + } } /// Horizontally subtract the adjacent pairs of values contained in 2 @@ -337,12 +349,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.ssse3.pshuf.b.128"] fn pshufb128(a: u8x16, b: u8x16) -> u8x16; - #[link_name = "llvm.x86.ssse3.phadd.sw.128"] - fn phaddsw128(a: i16x8, b: i16x8) -> i16x8; - - #[link_name = "llvm.x86.ssse3.phsub.sw.128"] - fn phsubsw128(a: i16x8, b: i16x8) -> i16x8; - #[link_name = "llvm.x86.ssse3.pmadd.ub.sw.128"] fn pmaddubsw128(a: u8x16, b: i8x16) -> i16x8; From 24a28332582ac25470c20079f0fdacf2c2e1b871 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 30 Jan 2026 20:22:18 +0100 Subject: [PATCH 11/81] test the `vld1*` functions --- .../crates/core_arch/src/aarch64/neon/mod.rs | 864 ++++++++++++++++++ 1 file changed, 864 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index bac45742393c..feaf94a7f9e0 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -993,6 +993,870 @@ mod tests { assert_eq!(vals[1], 1.); assert_eq!(vals[2], 2.); } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1_f16_x2() { + let vals: [f16; 8] = crate::array::from_fn(|i| i as f16); + let a: float16x4x2_t = transmute(vals); + let mut tmp = [0_f16; 8]; + vst1_f16_x2(tmp.as_mut_ptr().cast(), a); + let r: float16x4x2_t = vld1_f16_x2(tmp.as_ptr().cast()); + let out: [f16; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1_f16_x3() { + let vals: [f16; 12] = crate::array::from_fn(|i| i as f16); + let a: float16x4x3_t = transmute(vals); + let mut tmp = [0_f16; 12]; + vst1_f16_x3(tmp.as_mut_ptr().cast(), a); + let r: float16x4x3_t = vld1_f16_x3(tmp.as_ptr().cast()); + let out: [f16; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1_f16_x4() { + let vals: [f16; 16] = crate::array::from_fn(|i| i as f16); + let a: float16x4x4_t = transmute(vals); + let mut tmp = [0_f16; 16]; + vst1_f16_x4(tmp.as_mut_ptr().cast(), a); + let r: float16x4x4_t = vld1_f16_x4(tmp.as_ptr().cast()); + let out: [f16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1q_f16_x2() { + let vals: [f16; 16] = crate::array::from_fn(|i| i as f16); + let a: float16x8x2_t = transmute(vals); + let mut tmp = [0_f16; 16]; + vst1q_f16_x2(tmp.as_mut_ptr().cast(), a); + let r: float16x8x2_t = vld1q_f16_x2(tmp.as_ptr().cast()); + let out: [f16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1q_f16_x3() { + let vals: [f16; 24] = crate::array::from_fn(|i| i as f16); + let a: float16x8x3_t = transmute(vals); + let mut tmp = [0_f16; 24]; + vst1q_f16_x3(tmp.as_mut_ptr().cast(), a); + let r: float16x8x3_t = vld1q_f16_x3(tmp.as_ptr().cast()); + let out: [f16; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn test_vld1q_f16_x4() { + let vals: [f16; 32] = crate::array::from_fn(|i| i as f16); + let a: float16x8x4_t = transmute(vals); + let mut tmp = [0_f16; 32]; + vst1q_f16_x4(tmp.as_mut_ptr().cast(), a); + let r: float16x8x4_t = vld1q_f16_x4(tmp.as_ptr().cast()); + let out: [f16; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_f32_x2() { + let vals: [f32; 4] = crate::array::from_fn(|i| i as f32); + let a: float32x2x2_t = transmute(vals); + let mut tmp = [0_f32; 4]; + vst1_f32_x2(tmp.as_mut_ptr().cast(), a); + let r: float32x2x2_t = vld1_f32_x2(tmp.as_ptr().cast()); + let out: [f32; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_f32_x3() { + let vals: [f32; 6] = crate::array::from_fn(|i| i as f32); + let a: float32x2x3_t = transmute(vals); + let mut tmp = [0_f32; 6]; + vst1_f32_x3(tmp.as_mut_ptr().cast(), a); + let r: float32x2x3_t = vld1_f32_x3(tmp.as_ptr().cast()); + let out: [f32; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_f32_x4() { + let vals: [f32; 8] = crate::array::from_fn(|i| i as f32); + let a: float32x2x4_t = transmute(vals); + let mut tmp = [0_f32; 8]; + vst1_f32_x4(tmp.as_mut_ptr().cast(), a); + let r: float32x2x4_t = vld1_f32_x4(tmp.as_ptr().cast()); + let out: [f32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_f32_x2() { + let vals: [f32; 8] = crate::array::from_fn(|i| i as f32); + let a: float32x4x2_t = transmute(vals); + let mut tmp = [0_f32; 8]; + vst1q_f32_x2(tmp.as_mut_ptr().cast(), a); + let r: float32x4x2_t = vld1q_f32_x2(tmp.as_ptr().cast()); + let out: [f32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_f32_x3() { + let vals: [f32; 12] = crate::array::from_fn(|i| i as f32); + let a: float32x4x3_t = transmute(vals); + let mut tmp = [0_f32; 12]; + vst1q_f32_x3(tmp.as_mut_ptr().cast(), a); + let r: float32x4x3_t = vld1q_f32_x3(tmp.as_ptr().cast()); + let out: [f32; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_f32_x4() { + let vals: [f32; 16] = crate::array::from_fn(|i| i as f32); + let a: float32x4x4_t = transmute(vals); + let mut tmp = [0_f32; 16]; + vst1q_f32_x4(tmp.as_mut_ptr().cast(), a); + let r: float32x4x4_t = vld1q_f32_x4(tmp.as_ptr().cast()); + let out: [f32; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1_p64_x2() { + let vals: [p64; 2] = crate::array::from_fn(|i| i as p64); + let a: poly64x1x2_t = transmute(vals); + let mut tmp = [0 as p64; 2]; + vst1_p64_x2(tmp.as_mut_ptr().cast(), a); + let r: poly64x1x2_t = vld1_p64_x2(tmp.as_ptr().cast()); + let out: [p64; 2] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1_p64_x3() { + let vals: [p64; 3] = crate::array::from_fn(|i| i as p64); + let a: poly64x1x3_t = transmute(vals); + let mut tmp = [0 as p64; 3]; + vst1_p64_x3(tmp.as_mut_ptr().cast(), a); + let r: poly64x1x3_t = vld1_p64_x3(tmp.as_ptr().cast()); + let out: [p64; 3] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1_p64_x4() { + let vals: [p64; 4] = crate::array::from_fn(|i| i as p64); + let a: poly64x1x4_t = transmute(vals); + let mut tmp = [0 as p64; 4]; + vst1_p64_x4(tmp.as_mut_ptr().cast(), a); + let r: poly64x1x4_t = vld1_p64_x4(tmp.as_ptr().cast()); + let out: [p64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1q_p64_x2() { + let vals: [p64; 4] = crate::array::from_fn(|i| i as p64); + let a: poly64x2x2_t = transmute(vals); + let mut tmp = [0 as p64; 4]; + vst1q_p64_x2(tmp.as_mut_ptr().cast(), a); + let r: poly64x2x2_t = vld1q_p64_x2(tmp.as_ptr().cast()); + let out: [p64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1q_p64_x3() { + let vals: [p64; 6] = crate::array::from_fn(|i| i as p64); + let a: poly64x2x3_t = transmute(vals); + let mut tmp = [0 as p64; 6]; + vst1q_p64_x3(tmp.as_mut_ptr().cast(), a); + let r: poly64x2x3_t = vld1q_p64_x3(tmp.as_ptr().cast()); + let out: [p64; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon,aes")] + unsafe fn test_vld1q_p64_x4() { + let vals: [p64; 8] = crate::array::from_fn(|i| i as p64); + let a: poly64x2x4_t = transmute(vals); + let mut tmp = [0 as p64; 8]; + vst1q_p64_x4(tmp.as_mut_ptr().cast(), a); + let r: poly64x2x4_t = vld1q_p64_x4(tmp.as_ptr().cast()); + let out: [p64; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s8_x2() { + let vals: [i8; 16] = crate::array::from_fn(|i| i as i8); + let a: int8x8x2_t = transmute(vals); + let mut tmp = [0_i8; 16]; + vst1_s8_x2(tmp.as_mut_ptr().cast(), a); + let r: int8x8x2_t = vld1_s8_x2(tmp.as_ptr().cast()); + let out: [i8; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s8_x3() { + let vals: [i8; 24] = crate::array::from_fn(|i| i as i8); + let a: int8x8x3_t = transmute(vals); + let mut tmp = [0_i8; 24]; + vst1_s8_x3(tmp.as_mut_ptr().cast(), a); + let r: int8x8x3_t = vld1_s8_x3(tmp.as_ptr().cast()); + let out: [i8; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s8_x4() { + let vals: [i8; 32] = crate::array::from_fn(|i| i as i8); + let a: int8x8x4_t = transmute(vals); + let mut tmp = [0_i8; 32]; + vst1_s8_x4(tmp.as_mut_ptr().cast(), a); + let r: int8x8x4_t = vld1_s8_x4(tmp.as_ptr().cast()); + let out: [i8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s8_x2() { + let vals: [i8; 32] = crate::array::from_fn(|i| i as i8); + let a: int8x16x2_t = transmute(vals); + let mut tmp = [0_i8; 32]; + vst1q_s8_x2(tmp.as_mut_ptr().cast(), a); + let r: int8x16x2_t = vld1q_s8_x2(tmp.as_ptr().cast()); + let out: [i8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s8_x3() { + let vals: [i8; 48] = crate::array::from_fn(|i| i as i8); + let a: int8x16x3_t = transmute(vals); + let mut tmp = [0_i8; 48]; + vst1q_s8_x3(tmp.as_mut_ptr().cast(), a); + let r: int8x16x3_t = vld1q_s8_x3(tmp.as_ptr().cast()); + let out: [i8; 48] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s8_x4() { + let vals: [i8; 64] = crate::array::from_fn(|i| i as i8); + let a: int8x16x4_t = transmute(vals); + let mut tmp = [0_i8; 64]; + vst1q_s8_x4(tmp.as_mut_ptr().cast(), a); + let r: int8x16x4_t = vld1q_s8_x4(tmp.as_ptr().cast()); + let out: [i8; 64] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s16_x2() { + let vals: [i16; 8] = crate::array::from_fn(|i| i as i16); + let a: int16x4x2_t = transmute(vals); + let mut tmp = [0_i16; 8]; + vst1_s16_x2(tmp.as_mut_ptr().cast(), a); + let r: int16x4x2_t = vld1_s16_x2(tmp.as_ptr().cast()); + let out: [i16; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s16_x3() { + let vals: [i16; 12] = crate::array::from_fn(|i| i as i16); + let a: int16x4x3_t = transmute(vals); + let mut tmp = [0_i16; 12]; + vst1_s16_x3(tmp.as_mut_ptr().cast(), a); + let r: int16x4x3_t = vld1_s16_x3(tmp.as_ptr().cast()); + let out: [i16; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s16_x4() { + let vals: [i16; 16] = crate::array::from_fn(|i| i as i16); + let a: int16x4x4_t = transmute(vals); + let mut tmp = [0_i16; 16]; + vst1_s16_x4(tmp.as_mut_ptr().cast(), a); + let r: int16x4x4_t = vld1_s16_x4(tmp.as_ptr().cast()); + let out: [i16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s16_x2() { + let vals: [i16; 16] = crate::array::from_fn(|i| i as i16); + let a: int16x8x2_t = transmute(vals); + let mut tmp = [0_i16; 16]; + vst1q_s16_x2(tmp.as_mut_ptr().cast(), a); + let r: int16x8x2_t = vld1q_s16_x2(tmp.as_ptr().cast()); + let out: [i16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s16_x3() { + let vals: [i16; 24] = crate::array::from_fn(|i| i as i16); + let a: int16x8x3_t = transmute(vals); + let mut tmp = [0_i16; 24]; + vst1q_s16_x3(tmp.as_mut_ptr().cast(), a); + let r: int16x8x3_t = vld1q_s16_x3(tmp.as_ptr().cast()); + let out: [i16; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s16_x4() { + let vals: [i16; 32] = crate::array::from_fn(|i| i as i16); + let a: int16x8x4_t = transmute(vals); + let mut tmp = [0_i16; 32]; + vst1q_s16_x4(tmp.as_mut_ptr().cast(), a); + let r: int16x8x4_t = vld1q_s16_x4(tmp.as_ptr().cast()); + let out: [i16; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s32_x2() { + let vals: [i32; 4] = crate::array::from_fn(|i| i as i32); + let a: int32x2x2_t = transmute(vals); + let mut tmp = [0_i32; 4]; + vst1_s32_x2(tmp.as_mut_ptr().cast(), a); + let r: int32x2x2_t = vld1_s32_x2(tmp.as_ptr().cast()); + let out: [i32; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s32_x3() { + let vals: [i32; 6] = crate::array::from_fn(|i| i as i32); + let a: int32x2x3_t = transmute(vals); + let mut tmp = [0_i32; 6]; + vst1_s32_x3(tmp.as_mut_ptr().cast(), a); + let r: int32x2x3_t = vld1_s32_x3(tmp.as_ptr().cast()); + let out: [i32; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s32_x4() { + let vals: [i32; 8] = crate::array::from_fn(|i| i as i32); + let a: int32x2x4_t = transmute(vals); + let mut tmp = [0_i32; 8]; + vst1_s32_x4(tmp.as_mut_ptr().cast(), a); + let r: int32x2x4_t = vld1_s32_x4(tmp.as_ptr().cast()); + let out: [i32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s32_x2() { + let vals: [i32; 8] = crate::array::from_fn(|i| i as i32); + let a: int32x4x2_t = transmute(vals); + let mut tmp = [0_i32; 8]; + vst1q_s32_x2(tmp.as_mut_ptr().cast(), a); + let r: int32x4x2_t = vld1q_s32_x2(tmp.as_ptr().cast()); + let out: [i32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s32_x3() { + let vals: [i32; 12] = crate::array::from_fn(|i| i as i32); + let a: int32x4x3_t = transmute(vals); + let mut tmp = [0_i32; 12]; + vst1q_s32_x3(tmp.as_mut_ptr().cast(), a); + let r: int32x4x3_t = vld1q_s32_x3(tmp.as_ptr().cast()); + let out: [i32; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s32_x4() { + let vals: [i32; 16] = crate::array::from_fn(|i| i as i32); + let a: int32x4x4_t = transmute(vals); + let mut tmp = [0_i32; 16]; + vst1q_s32_x4(tmp.as_mut_ptr().cast(), a); + let r: int32x4x4_t = vld1q_s32_x4(tmp.as_ptr().cast()); + let out: [i32; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s64_x2() { + let vals: [i64; 2] = crate::array::from_fn(|i| i as i64); + let a: int64x1x2_t = transmute(vals); + let mut tmp = [0_i64; 2]; + vst1_s64_x2(tmp.as_mut_ptr().cast(), a); + let r: int64x1x2_t = vld1_s64_x2(tmp.as_ptr().cast()); + let out: [i64; 2] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s64_x3() { + let vals: [i64; 3] = crate::array::from_fn(|i| i as i64); + let a: int64x1x3_t = transmute(vals); + let mut tmp = [0_i64; 3]; + vst1_s64_x3(tmp.as_mut_ptr().cast(), a); + let r: int64x1x3_t = vld1_s64_x3(tmp.as_ptr().cast()); + let out: [i64; 3] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_s64_x4() { + let vals: [i64; 4] = crate::array::from_fn(|i| i as i64); + let a: int64x1x4_t = transmute(vals); + let mut tmp = [0_i64; 4]; + vst1_s64_x4(tmp.as_mut_ptr().cast(), a); + let r: int64x1x4_t = vld1_s64_x4(tmp.as_ptr().cast()); + let out: [i64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s64_x2() { + let vals: [i64; 4] = crate::array::from_fn(|i| i as i64); + let a: int64x2x2_t = transmute(vals); + let mut tmp = [0_i64; 4]; + vst1q_s64_x2(tmp.as_mut_ptr().cast(), a); + let r: int64x2x2_t = vld1q_s64_x2(tmp.as_ptr().cast()); + let out: [i64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s64_x3() { + let vals: [i64; 6] = crate::array::from_fn(|i| i as i64); + let a: int64x2x3_t = transmute(vals); + let mut tmp = [0_i64; 6]; + vst1q_s64_x3(tmp.as_mut_ptr().cast(), a); + let r: int64x2x3_t = vld1q_s64_x3(tmp.as_ptr().cast()); + let out: [i64; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_s64_x4() { + let vals: [i64; 8] = crate::array::from_fn(|i| i as i64); + let a: int64x2x4_t = transmute(vals); + let mut tmp = [0_i64; 8]; + vst1q_s64_x4(tmp.as_mut_ptr().cast(), a); + let r: int64x2x4_t = vld1q_s64_x4(tmp.as_ptr().cast()); + let out: [i64; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u8_x2() { + let vals: [u8; 16] = crate::array::from_fn(|i| i as u8); + let a: uint8x8x2_t = transmute(vals); + let mut tmp = [0_u8; 16]; + vst1_u8_x2(tmp.as_mut_ptr().cast(), a); + let r: uint8x8x2_t = vld1_u8_x2(tmp.as_ptr().cast()); + let out: [u8; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u8_x3() { + let vals: [u8; 24] = crate::array::from_fn(|i| i as u8); + let a: uint8x8x3_t = transmute(vals); + let mut tmp = [0_u8; 24]; + vst1_u8_x3(tmp.as_mut_ptr().cast(), a); + let r: uint8x8x3_t = vld1_u8_x3(tmp.as_ptr().cast()); + let out: [u8; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u8_x4() { + let vals: [u8; 32] = crate::array::from_fn(|i| i as u8); + let a: uint8x8x4_t = transmute(vals); + let mut tmp = [0_u8; 32]; + vst1_u8_x4(tmp.as_mut_ptr().cast(), a); + let r: uint8x8x4_t = vld1_u8_x4(tmp.as_ptr().cast()); + let out: [u8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u8_x2() { + let vals: [u8; 32] = crate::array::from_fn(|i| i as u8); + let a: uint8x16x2_t = transmute(vals); + let mut tmp = [0_u8; 32]; + vst1q_u8_x2(tmp.as_mut_ptr().cast(), a); + let r: uint8x16x2_t = vld1q_u8_x2(tmp.as_ptr().cast()); + let out: [u8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u8_x3() { + let vals: [u8; 48] = crate::array::from_fn(|i| i as u8); + let a: uint8x16x3_t = transmute(vals); + let mut tmp = [0_u8; 48]; + vst1q_u8_x3(tmp.as_mut_ptr().cast(), a); + let r: uint8x16x3_t = vld1q_u8_x3(tmp.as_ptr().cast()); + let out: [u8; 48] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u8_x4() { + let vals: [u8; 64] = crate::array::from_fn(|i| i as u8); + let a: uint8x16x4_t = transmute(vals); + let mut tmp = [0_u8; 64]; + vst1q_u8_x4(tmp.as_mut_ptr().cast(), a); + let r: uint8x16x4_t = vld1q_u8_x4(tmp.as_ptr().cast()); + let out: [u8; 64] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u16_x2() { + let vals: [u16; 8] = crate::array::from_fn(|i| i as u16); + let a: uint16x4x2_t = transmute(vals); + let mut tmp = [0_u16; 8]; + vst1_u16_x2(tmp.as_mut_ptr().cast(), a); + let r: uint16x4x2_t = vld1_u16_x2(tmp.as_ptr().cast()); + let out: [u16; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u16_x3() { + let vals: [u16; 12] = crate::array::from_fn(|i| i as u16); + let a: uint16x4x3_t = transmute(vals); + let mut tmp = [0_u16; 12]; + vst1_u16_x3(tmp.as_mut_ptr().cast(), a); + let r: uint16x4x3_t = vld1_u16_x3(tmp.as_ptr().cast()); + let out: [u16; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u16_x4() { + let vals: [u16; 16] = crate::array::from_fn(|i| i as u16); + let a: uint16x4x4_t = transmute(vals); + let mut tmp = [0_u16; 16]; + vst1_u16_x4(tmp.as_mut_ptr().cast(), a); + let r: uint16x4x4_t = vld1_u16_x4(tmp.as_ptr().cast()); + let out: [u16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u16_x2() { + let vals: [u16; 16] = crate::array::from_fn(|i| i as u16); + let a: uint16x8x2_t = transmute(vals); + let mut tmp = [0_u16; 16]; + vst1q_u16_x2(tmp.as_mut_ptr().cast(), a); + let r: uint16x8x2_t = vld1q_u16_x2(tmp.as_ptr().cast()); + let out: [u16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u16_x3() { + let vals: [u16; 24] = crate::array::from_fn(|i| i as u16); + let a: uint16x8x3_t = transmute(vals); + let mut tmp = [0_u16; 24]; + vst1q_u16_x3(tmp.as_mut_ptr().cast(), a); + let r: uint16x8x3_t = vld1q_u16_x3(tmp.as_ptr().cast()); + let out: [u16; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u16_x4() { + let vals: [u16; 32] = crate::array::from_fn(|i| i as u16); + let a: uint16x8x4_t = transmute(vals); + let mut tmp = [0_u16; 32]; + vst1q_u16_x4(tmp.as_mut_ptr().cast(), a); + let r: uint16x8x4_t = vld1q_u16_x4(tmp.as_ptr().cast()); + let out: [u16; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u32_x2() { + let vals: [u32; 4] = crate::array::from_fn(|i| i as u32); + let a: uint32x2x2_t = transmute(vals); + let mut tmp = [0_u32; 4]; + vst1_u32_x2(tmp.as_mut_ptr().cast(), a); + let r: uint32x2x2_t = vld1_u32_x2(tmp.as_ptr().cast()); + let out: [u32; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u32_x3() { + let vals: [u32; 6] = crate::array::from_fn(|i| i as u32); + let a: uint32x2x3_t = transmute(vals); + let mut tmp = [0_u32; 6]; + vst1_u32_x3(tmp.as_mut_ptr().cast(), a); + let r: uint32x2x3_t = vld1_u32_x3(tmp.as_ptr().cast()); + let out: [u32; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u32_x4() { + let vals: [u32; 8] = crate::array::from_fn(|i| i as u32); + let a: uint32x2x4_t = transmute(vals); + let mut tmp = [0_u32; 8]; + vst1_u32_x4(tmp.as_mut_ptr().cast(), a); + let r: uint32x2x4_t = vld1_u32_x4(tmp.as_ptr().cast()); + let out: [u32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u32_x2() { + let vals: [u32; 8] = crate::array::from_fn(|i| i as u32); + let a: uint32x4x2_t = transmute(vals); + let mut tmp = [0_u32; 8]; + vst1q_u32_x2(tmp.as_mut_ptr().cast(), a); + let r: uint32x4x2_t = vld1q_u32_x2(tmp.as_ptr().cast()); + let out: [u32; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u32_x3() { + let vals: [u32; 12] = crate::array::from_fn(|i| i as u32); + let a: uint32x4x3_t = transmute(vals); + let mut tmp = [0_u32; 12]; + vst1q_u32_x3(tmp.as_mut_ptr().cast(), a); + let r: uint32x4x3_t = vld1q_u32_x3(tmp.as_ptr().cast()); + let out: [u32; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u32_x4() { + let vals: [u32; 16] = crate::array::from_fn(|i| i as u32); + let a: uint32x4x4_t = transmute(vals); + let mut tmp = [0_u32; 16]; + vst1q_u32_x4(tmp.as_mut_ptr().cast(), a); + let r: uint32x4x4_t = vld1q_u32_x4(tmp.as_ptr().cast()); + let out: [u32; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u64_x2() { + let vals: [u64; 2] = crate::array::from_fn(|i| i as u64); + let a: uint64x1x2_t = transmute(vals); + let mut tmp = [0_u64; 2]; + vst1_u64_x2(tmp.as_mut_ptr().cast(), a); + let r: uint64x1x2_t = vld1_u64_x2(tmp.as_ptr().cast()); + let out: [u64; 2] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u64_x3() { + let vals: [u64; 3] = crate::array::from_fn(|i| i as u64); + let a: uint64x1x3_t = transmute(vals); + let mut tmp = [0_u64; 3]; + vst1_u64_x3(tmp.as_mut_ptr().cast(), a); + let r: uint64x1x3_t = vld1_u64_x3(tmp.as_ptr().cast()); + let out: [u64; 3] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_u64_x4() { + let vals: [u64; 4] = crate::array::from_fn(|i| i as u64); + let a: uint64x1x4_t = transmute(vals); + let mut tmp = [0_u64; 4]; + vst1_u64_x4(tmp.as_mut_ptr().cast(), a); + let r: uint64x1x4_t = vld1_u64_x4(tmp.as_ptr().cast()); + let out: [u64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u64_x2() { + let vals: [u64; 4] = crate::array::from_fn(|i| i as u64); + let a: uint64x2x2_t = transmute(vals); + let mut tmp = [0_u64; 4]; + vst1q_u64_x2(tmp.as_mut_ptr().cast(), a); + let r: uint64x2x2_t = vld1q_u64_x2(tmp.as_ptr().cast()); + let out: [u64; 4] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u64_x3() { + let vals: [u64; 6] = crate::array::from_fn(|i| i as u64); + let a: uint64x2x3_t = transmute(vals); + let mut tmp = [0_u64; 6]; + vst1q_u64_x3(tmp.as_mut_ptr().cast(), a); + let r: uint64x2x3_t = vld1q_u64_x3(tmp.as_ptr().cast()); + let out: [u64; 6] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_u64_x4() { + let vals: [u64; 8] = crate::array::from_fn(|i| i as u64); + let a: uint64x2x4_t = transmute(vals); + let mut tmp = [0_u64; 8]; + vst1q_u64_x4(tmp.as_mut_ptr().cast(), a); + let r: uint64x2x4_t = vld1q_u64_x4(tmp.as_ptr().cast()); + let out: [u64; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p8_x2() { + let vals: [p8; 16] = crate::array::from_fn(|i| i as p8); + let a: poly8x8x2_t = transmute(vals); + let mut tmp = [0 as p8; 16]; + vst1_p8_x2(tmp.as_mut_ptr().cast(), a); + let r: poly8x8x2_t = vld1_p8_x2(tmp.as_ptr().cast()); + let out: [p8; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p8_x3() { + let vals: [p8; 24] = crate::array::from_fn(|i| i as p8); + let a: poly8x8x3_t = transmute(vals); + let mut tmp = [0 as p8; 24]; + vst1_p8_x3(tmp.as_mut_ptr().cast(), a); + let r: poly8x8x3_t = vld1_p8_x3(tmp.as_ptr().cast()); + let out: [p8; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p8_x4() { + let vals: [p8; 32] = crate::array::from_fn(|i| i as p8); + let a: poly8x8x4_t = transmute(vals); + let mut tmp = [0 as p8; 32]; + vst1_p8_x4(tmp.as_mut_ptr().cast(), a); + let r: poly8x8x4_t = vld1_p8_x4(tmp.as_ptr().cast()); + let out: [p8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p8_x2() { + let vals: [p8; 32] = crate::array::from_fn(|i| i as p8); + let a: poly8x16x2_t = transmute(vals); + let mut tmp = [0 as p8; 32]; + vst1q_p8_x2(tmp.as_mut_ptr().cast(), a); + let r: poly8x16x2_t = vld1q_p8_x2(tmp.as_ptr().cast()); + let out: [p8; 32] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p8_x3() { + let vals: [p8; 48] = crate::array::from_fn(|i| i as p8); + let a: poly8x16x3_t = transmute(vals); + let mut tmp = [0 as p8; 48]; + vst1q_p8_x3(tmp.as_mut_ptr().cast(), a); + let r: poly8x16x3_t = vld1q_p8_x3(tmp.as_ptr().cast()); + let out: [p8; 48] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p8_x4() { + let vals: [p8; 64] = crate::array::from_fn(|i| i as p8); + let a: poly8x16x4_t = transmute(vals); + let mut tmp = [0 as p8; 64]; + vst1q_p8_x4(tmp.as_mut_ptr().cast(), a); + let r: poly8x16x4_t = vld1q_p8_x4(tmp.as_ptr().cast()); + let out: [p8; 64] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p16_x2() { + let vals: [p16; 8] = crate::array::from_fn(|i| i as p16); + let a: poly16x4x2_t = transmute(vals); + let mut tmp = [0 as p16; 8]; + vst1_p16_x2(tmp.as_mut_ptr().cast(), a); + let r: poly16x4x2_t = vld1_p16_x2(tmp.as_ptr().cast()); + let out: [p16; 8] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p16_x3() { + let vals: [p16; 12] = crate::array::from_fn(|i| i as p16); + let a: poly16x4x3_t = transmute(vals); + let mut tmp = [0 as p16; 12]; + vst1_p16_x3(tmp.as_mut_ptr().cast(), a); + let r: poly16x4x3_t = vld1_p16_x3(tmp.as_ptr().cast()); + let out: [p16; 12] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1_p16_x4() { + let vals: [p16; 16] = crate::array::from_fn(|i| i as p16); + let a: poly16x4x4_t = transmute(vals); + let mut tmp = [0 as p16; 16]; + vst1_p16_x4(tmp.as_mut_ptr().cast(), a); + let r: poly16x4x4_t = vld1_p16_x4(tmp.as_ptr().cast()); + let out: [p16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p16_x2() { + let vals: [p16; 16] = crate::array::from_fn(|i| i as p16); + let a: poly16x8x2_t = transmute(vals); + let mut tmp = [0 as p16; 16]; + vst1q_p16_x2(tmp.as_mut_ptr().cast(), a); + let r: poly16x8x2_t = vld1q_p16_x2(tmp.as_ptr().cast()); + let out: [p16; 16] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p16_x3() { + let vals: [p16; 24] = crate::array::from_fn(|i| i as p16); + let a: poly16x8x3_t = transmute(vals); + let mut tmp = [0 as p16; 24]; + vst1q_p16_x3(tmp.as_mut_ptr().cast(), a); + let r: poly16x8x3_t = vld1q_p16_x3(tmp.as_ptr().cast()); + let out: [p16; 24] = transmute(r); + assert_eq!(out, vals); + } + + #[simd_test(enable = "neon")] + unsafe fn test_vld1q_p16_x4() { + let vals: [p16; 32] = crate::array::from_fn(|i| i as p16); + let a: poly16x8x4_t = transmute(vals); + let mut tmp = [0 as p16; 32]; + vst1q_p16_x4(tmp.as_mut_ptr().cast(), a); + let r: poly16x8x4_t = vld1q_p16_x4(tmp.as_ptr().cast()); + let out: [p16; 32] = transmute(r); + assert_eq!(out, vals); + } } #[cfg(test)] From a208e6c8874c471ffa1a3d96fc7dd8913798f4c9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 30 Jan 2026 21:35:56 +0100 Subject: [PATCH 12/81] maybe fix aarch64be unsigned vector tuple loads --- .../src/arm_shared/neon/generated.rs | 1152 ----------------- .../spec/neon/arm_shared.spec.yml | 2 + 2 files changed, 2 insertions(+), 1152 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 3b67208182cb..2f52e3b52b07 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -17067,7 +17067,6 @@ pub unsafe fn vld1_p64_x4(a: *const p64) -> poly64x1x4_t { #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon,aes")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] @@ -17087,38 +17086,10 @@ pub unsafe fn vld1q_p64_x2(a: *const p64) -> poly64x2x2_t { transmute(vld1q_s64_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon,aes")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p64_x2(a: *const p64) -> poly64x2x2_t { - let mut ret_val: poly64x2x2_t = transmute(vld1q_s64_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon,aes")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] @@ -17138,39 +17109,10 @@ pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t { transmute(vld1q_s64_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon,aes")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t { - let mut ret_val: poly64x2x3_t = transmute(vld1q_s64_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon,aes")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] @@ -17189,35 +17131,6 @@ pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t { pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t { transmute(vld1q_s64_x4(transmute(a))) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon,aes")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t { - let mut ret_val: poly64x2x4_t = transmute(vld1q_s64_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [1, 0]) }; - ret_val -} #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8)"] #[doc = "## Safety"] @@ -18071,7 +17984,6 @@ pub unsafe fn vld1q_s64_x4(a: *const i64) -> int64x2x4_t { #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18091,38 +18003,10 @@ pub unsafe fn vld1_u8_x2(a: *const u8) -> uint8x8x2_t { transmute(vld1_s8_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u8_x2(a: *const u8) -> uint8x8x2_t { - let mut ret_val: uint8x8x2_t = transmute(vld1_s8_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18142,39 +18026,10 @@ pub unsafe fn vld1_u8_x3(a: *const u8) -> uint8x8x3_t { transmute(vld1_s8_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u8_x3(a: *const u8) -> uint8x8x3_t { - let mut ret_val: uint8x8x3_t = transmute(vld1_s8_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18194,40 +18049,10 @@ pub unsafe fn vld1_u8_x4(a: *const u8) -> uint8x8x4_t { transmute(vld1_s8_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u8_x4(a: *const u8) -> uint8x8x4_t { - let mut ret_val: uint8x8x4_t = transmute(vld1_s8_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18247,50 +18072,10 @@ pub unsafe fn vld1q_u8_x2(a: *const u8) -> uint8x16x2_t { transmute(vld1q_s8_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u8_x2(a: *const u8) -> uint8x16x2_t { - let mut ret_val: uint8x16x2_t = transmute(vld1q_s8_x2(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18310,57 +18095,10 @@ pub unsafe fn vld1q_u8_x3(a: *const u8) -> uint8x16x3_t { transmute(vld1q_s8_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u8_x3(a: *const u8) -> uint8x16x3_t { - let mut ret_val: uint8x16x3_t = transmute(vld1q_s8_x3(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.2 = unsafe { - simd_shuffle!( - ret_val.2, - ret_val.2, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18380,64 +18118,10 @@ pub unsafe fn vld1q_u8_x4(a: *const u8) -> uint8x16x4_t { transmute(vld1q_s8_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u8_x4(a: *const u8) -> uint8x16x4_t { - let mut ret_val: uint8x16x4_t = transmute(vld1q_s8_x4(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.2 = unsafe { - simd_shuffle!( - ret_val.2, - ret_val.2, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.3 = unsafe { - simd_shuffle!( - ret_val.3, - ret_val.3, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18457,38 +18141,10 @@ pub unsafe fn vld1_u16_x2(a: *const u16) -> uint16x4x2_t { transmute(vld1_s16_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u16_x2(a: *const u16) -> uint16x4x2_t { - let mut ret_val: uint16x4x2_t = transmute(vld1_s16_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18508,39 +18164,10 @@ pub unsafe fn vld1_u16_x3(a: *const u16) -> uint16x4x3_t { transmute(vld1_s16_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u16_x3(a: *const u16) -> uint16x4x3_t { - let mut ret_val: uint16x4x3_t = transmute(vld1_s16_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18560,40 +18187,10 @@ pub unsafe fn vld1_u16_x4(a: *const u16) -> uint16x4x4_t { transmute(vld1_s16_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u16_x4(a: *const u16) -> uint16x4x4_t { - let mut ret_val: uint16x4x4_t = transmute(vld1_s16_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18613,38 +18210,10 @@ pub unsafe fn vld1q_u16_x2(a: *const u16) -> uint16x8x2_t { transmute(vld1q_s16_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u16_x2(a: *const u16) -> uint16x8x2_t { - let mut ret_val: uint16x8x2_t = transmute(vld1q_s16_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18664,39 +18233,10 @@ pub unsafe fn vld1q_u16_x3(a: *const u16) -> uint16x8x3_t { transmute(vld1q_s16_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u16_x3(a: *const u16) -> uint16x8x3_t { - let mut ret_val: uint16x8x3_t = transmute(vld1q_s16_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18716,40 +18256,10 @@ pub unsafe fn vld1q_u16_x4(a: *const u16) -> uint16x8x4_t { transmute(vld1q_s16_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u16_x4(a: *const u16) -> uint16x8x4_t { - let mut ret_val: uint16x8x4_t = transmute(vld1q_s16_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18769,38 +18279,10 @@ pub unsafe fn vld1_u32_x2(a: *const u32) -> uint32x2x2_t { transmute(vld1_s32_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u32_x2(a: *const u32) -> uint32x2x2_t { - let mut ret_val: uint32x2x2_t = transmute(vld1_s32_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18820,39 +18302,10 @@ pub unsafe fn vld1_u32_x3(a: *const u32) -> uint32x2x3_t { transmute(vld1_s32_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u32_x3(a: *const u32) -> uint32x2x3_t { - let mut ret_val: uint32x2x3_t = transmute(vld1_s32_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18872,40 +18325,10 @@ pub unsafe fn vld1_u32_x4(a: *const u32) -> uint32x2x4_t { transmute(vld1_s32_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_u32_x4(a: *const u32) -> uint32x2x4_t { - let mut ret_val: uint32x2x4_t = transmute(vld1_s32_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18925,38 +18348,10 @@ pub unsafe fn vld1q_u32_x2(a: *const u32) -> uint32x4x2_t { transmute(vld1q_s32_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u32_x2(a: *const u32) -> uint32x4x2_t { - let mut ret_val: uint32x4x2_t = transmute(vld1q_s32_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -18976,39 +18371,10 @@ pub unsafe fn vld1q_u32_x3(a: *const u32) -> uint32x4x3_t { transmute(vld1q_s32_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u32_x3(a: *const u32) -> uint32x4x3_t { - let mut ret_val: uint32x4x3_t = transmute(vld1q_s32_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19028,35 +18394,6 @@ pub unsafe fn vld1q_u32_x4(a: *const u32) -> uint32x4x4_t { transmute(vld1q_s32_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u32_x4(a: *const u32) -> uint32x4x4_t { - let mut ret_val: uint32x4x4_t = transmute(vld1q_s32_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] @@ -19130,7 +18467,6 @@ pub unsafe fn vld1_u64_x4(a: *const u64) -> uint64x1x4_t { #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19150,38 +18486,10 @@ pub unsafe fn vld1q_u64_x2(a: *const u64) -> uint64x2x2_t { transmute(vld1q_s64_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u64_x2(a: *const u64) -> uint64x2x2_t { - let mut ret_val: uint64x2x2_t = transmute(vld1q_s64_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19201,39 +18509,10 @@ pub unsafe fn vld1q_u64_x3(a: *const u64) -> uint64x2x3_t { transmute(vld1q_s64_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u64_x3(a: *const u64) -> uint64x2x3_t { - let mut ret_val: uint64x2x3_t = transmute(vld1q_s64_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19253,40 +18532,10 @@ pub unsafe fn vld1q_u64_x4(a: *const u64) -> uint64x2x4_t { transmute(vld1q_s64_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_u64_x4(a: *const u64) -> uint64x2x4_t { - let mut ret_val: uint64x2x4_t = transmute(vld1q_s64_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19306,38 +18555,10 @@ pub unsafe fn vld1_p8_x2(a: *const p8) -> poly8x8x2_t { transmute(vld1_s8_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p8_x2(a: *const p8) -> poly8x8x2_t { - let mut ret_val: poly8x8x2_t = transmute(vld1_s8_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19357,39 +18578,10 @@ pub unsafe fn vld1_p8_x3(a: *const p8) -> poly8x8x3_t { transmute(vld1_s8_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p8_x3(a: *const p8) -> poly8x8x3_t { - let mut ret_val: poly8x8x3_t = transmute(vld1_s8_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19409,40 +18601,10 @@ pub unsafe fn vld1_p8_x4(a: *const p8) -> poly8x8x4_t { transmute(vld1_s8_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p8_x4(a: *const p8) -> poly8x8x4_t { - let mut ret_val: poly8x8x4_t = transmute(vld1_s8_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19462,50 +18624,10 @@ pub unsafe fn vld1q_p8_x2(a: *const p8) -> poly8x16x2_t { transmute(vld1q_s8_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p8_x2(a: *const p8) -> poly8x16x2_t { - let mut ret_val: poly8x16x2_t = transmute(vld1q_s8_x2(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19525,57 +18647,10 @@ pub unsafe fn vld1q_p8_x3(a: *const p8) -> poly8x16x3_t { transmute(vld1q_s8_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p8_x3(a: *const p8) -> poly8x16x3_t { - let mut ret_val: poly8x16x3_t = transmute(vld1q_s8_x3(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.2 = unsafe { - simd_shuffle!( - ret_val.2, - ret_val.2, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19595,64 +18670,10 @@ pub unsafe fn vld1q_p8_x4(a: *const p8) -> poly8x16x4_t { transmute(vld1q_s8_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p8_x4(a: *const p8) -> poly8x16x4_t { - let mut ret_val: poly8x16x4_t = transmute(vld1q_s8_x4(transmute(a))); - ret_val.0 = unsafe { - simd_shuffle!( - ret_val.0, - ret_val.0, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.1 = unsafe { - simd_shuffle!( - ret_val.1, - ret_val.1, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.2 = unsafe { - simd_shuffle!( - ret_val.2, - ret_val.2, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val.3 = unsafe { - simd_shuffle!( - ret_val.3, - ret_val.3, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) - }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19672,38 +18693,10 @@ pub unsafe fn vld1_p16_x2(a: *const p16) -> poly16x4x2_t { transmute(vld1_s16_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p16_x2(a: *const p16) -> poly16x4x2_t { - let mut ret_val: poly16x4x2_t = transmute(vld1_s16_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19723,39 +18716,10 @@ pub unsafe fn vld1_p16_x3(a: *const p16) -> poly16x4x3_t { transmute(vld1_s16_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p16_x3(a: *const p16) -> poly16x4x3_t { - let mut ret_val: poly16x4x3_t = transmute(vld1_s16_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19775,40 +18739,10 @@ pub unsafe fn vld1_p16_x4(a: *const p16) -> poly16x4x4_t { transmute(vld1_s16_x4(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1_p16_x4(a: *const p16) -> poly16x4x4_t { - let mut ret_val: poly16x4x4_t = transmute(vld1_s16_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x2)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19828,38 +18762,10 @@ pub unsafe fn vld1q_p16_x2(a: *const p16) -> poly16x8x2_t { transmute(vld1q_s16_x2(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x2)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p16_x2(a: *const p16) -> poly16x8x2_t { - let mut ret_val: poly16x8x2_t = transmute(vld1q_s16_x2(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x3)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19879,39 +18785,10 @@ pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t { transmute(vld1q_s16_x3(transmute(a))) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x3)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t { - let mut ret_val: poly16x8x3_t = transmute(vld1q_s16_x3(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x4)"] #[doc = "## Safety"] #[doc = " * Neon intrinsic unsafe"] #[inline(always)] -#[cfg(target_endian = "little")] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] @@ -19930,35 +18807,6 @@ pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t { pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t { transmute(vld1q_s16_x4(transmute(a))) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x4)"] -#[doc = "## Safety"] -#[doc = " * Neon intrinsic unsafe"] -#[inline(always)] -#[cfg(target_endian = "big")] -#[target_feature(enable = "neon")] -#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] -#[cfg_attr( - all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), - assert_instr(ld1) -)] -#[cfg_attr( - not(target_arch = "arm"), - stable(feature = "neon_intrinsics", since = "1.59.0") -)] -#[cfg_attr( - target_arch = "arm", - unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") -)] -pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t { - let mut ret_val: poly16x8x4_t = transmute(vld1q_s16_x4(transmute(a))); - ret_val.0 = unsafe { simd_shuffle!(ret_val.0, ret_val.0, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.1 = unsafe { simd_shuffle!(ret_val.1, ret_val.1, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.2 = unsafe { simd_shuffle!(ret_val.2, ret_val.2, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) }; - ret_val -} #[inline(always)] #[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 52748a4cc056..3ec7ba8814e5 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -2681,6 +2681,7 @@ intrinsics: - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1]]}]] - *neon-not-arm-stable - *neon-cfg-arm-unstable + big_endian_inverse: false safety: unsafe: [neon] types: @@ -2740,6 +2741,7 @@ intrinsics: - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1]]}]] - *neon-not-arm-stable - *neon-cfg-arm-unstable + big_endian_inverse: false safety: unsafe: [neon] types: From 0306275849b28f23ebf9d7883317937c9aac0991 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 1 Feb 2026 13:50:20 +0100 Subject: [PATCH 13/81] use macro for wide store/load roundtrip tests --- .../crates/core_arch/src/aarch64/neon/mod.rs | 636 +++--------------- 1 file changed, 90 insertions(+), 546 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index feaf94a7f9e0..ee27bef9738c 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -994,868 +994,412 @@ mod tests { assert_eq!(vals[2], 2.); } + macro_rules! wide_store_load_roundtrip { + ($elem_ty:ty, $len:expr, $vec_ty:ty, $store:expr, $load:expr) => { + let vals: [$elem_ty; $len] = crate::array::from_fn(|i| i as $elem_ty); + let a: $vec_ty = transmute(vals); + let mut tmp = [0 as $elem_ty; $len]; + $store(tmp.as_mut_ptr().cast(), a); + let r: $vec_ty = $load(tmp.as_ptr().cast()); + let out: [$elem_ty; $len] = transmute(r); + assert_eq!(out, vals); + }; + } + #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1_f16_x2() { - let vals: [f16; 8] = crate::array::from_fn(|i| i as f16); - let a: float16x4x2_t = transmute(vals); - let mut tmp = [0_f16; 8]; - vst1_f16_x2(tmp.as_mut_ptr().cast(), a); - let r: float16x4x2_t = vld1_f16_x2(tmp.as_ptr().cast()); - let out: [f16; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 8, float16x4x2_t, vst1_f16_x2, vld1_f16_x2); } #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1_f16_x3() { - let vals: [f16; 12] = crate::array::from_fn(|i| i as f16); - let a: float16x4x3_t = transmute(vals); - let mut tmp = [0_f16; 12]; - vst1_f16_x3(tmp.as_mut_ptr().cast(), a); - let r: float16x4x3_t = vld1_f16_x3(tmp.as_ptr().cast()); - let out: [f16; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 12, float16x4x3_t, vst1_f16_x3, vld1_f16_x3); } #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1_f16_x4() { - let vals: [f16; 16] = crate::array::from_fn(|i| i as f16); - let a: float16x4x4_t = transmute(vals); - let mut tmp = [0_f16; 16]; - vst1_f16_x4(tmp.as_mut_ptr().cast(), a); - let r: float16x4x4_t = vld1_f16_x4(tmp.as_ptr().cast()); - let out: [f16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 16, float16x4x4_t, vst1_f16_x4, vld1_f16_x4); } #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1q_f16_x2() { - let vals: [f16; 16] = crate::array::from_fn(|i| i as f16); - let a: float16x8x2_t = transmute(vals); - let mut tmp = [0_f16; 16]; - vst1q_f16_x2(tmp.as_mut_ptr().cast(), a); - let r: float16x8x2_t = vld1q_f16_x2(tmp.as_ptr().cast()); - let out: [f16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 16, float16x8x2_t, vst1q_f16_x2, vld1q_f16_x2); } #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1q_f16_x3() { - let vals: [f16; 24] = crate::array::from_fn(|i| i as f16); - let a: float16x8x3_t = transmute(vals); - let mut tmp = [0_f16; 24]; - vst1q_f16_x3(tmp.as_mut_ptr().cast(), a); - let r: float16x8x3_t = vld1q_f16_x3(tmp.as_ptr().cast()); - let out: [f16; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 24, float16x8x3_t, vst1q_f16_x3, vld1q_f16_x3); } #[simd_test(enable = "neon,fp16")] #[cfg(not(target_arch = "arm64ec"))] unsafe fn test_vld1q_f16_x4() { - let vals: [f16; 32] = crate::array::from_fn(|i| i as f16); - let a: float16x8x4_t = transmute(vals); - let mut tmp = [0_f16; 32]; - vst1q_f16_x4(tmp.as_mut_ptr().cast(), a); - let r: float16x8x4_t = vld1q_f16_x4(tmp.as_ptr().cast()); - let out: [f16; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f16, 32, float16x8x4_t, vst1q_f16_x4, vld1q_f16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_f32_x2() { - let vals: [f32; 4] = crate::array::from_fn(|i| i as f32); - let a: float32x2x2_t = transmute(vals); - let mut tmp = [0_f32; 4]; - vst1_f32_x2(tmp.as_mut_ptr().cast(), a); - let r: float32x2x2_t = vld1_f32_x2(tmp.as_ptr().cast()); - let out: [f32; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 4, float32x2x2_t, vst1_f32_x2, vld1_f32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_f32_x3() { - let vals: [f32; 6] = crate::array::from_fn(|i| i as f32); - let a: float32x2x3_t = transmute(vals); - let mut tmp = [0_f32; 6]; - vst1_f32_x3(tmp.as_mut_ptr().cast(), a); - let r: float32x2x3_t = vld1_f32_x3(tmp.as_ptr().cast()); - let out: [f32; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 6, float32x2x3_t, vst1_f32_x3, vld1_f32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_f32_x4() { - let vals: [f32; 8] = crate::array::from_fn(|i| i as f32); - let a: float32x2x4_t = transmute(vals); - let mut tmp = [0_f32; 8]; - vst1_f32_x4(tmp.as_mut_ptr().cast(), a); - let r: float32x2x4_t = vld1_f32_x4(tmp.as_ptr().cast()); - let out: [f32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 8, float32x2x4_t, vst1_f32_x4, vld1_f32_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_f32_x2() { - let vals: [f32; 8] = crate::array::from_fn(|i| i as f32); - let a: float32x4x2_t = transmute(vals); - let mut tmp = [0_f32; 8]; - vst1q_f32_x2(tmp.as_mut_ptr().cast(), a); - let r: float32x4x2_t = vld1q_f32_x2(tmp.as_ptr().cast()); - let out: [f32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 8, float32x4x2_t, vst1q_f32_x2, vld1q_f32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_f32_x3() { - let vals: [f32; 12] = crate::array::from_fn(|i| i as f32); - let a: float32x4x3_t = transmute(vals); - let mut tmp = [0_f32; 12]; - vst1q_f32_x3(tmp.as_mut_ptr().cast(), a); - let r: float32x4x3_t = vld1q_f32_x3(tmp.as_ptr().cast()); - let out: [f32; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 12, float32x4x3_t, vst1q_f32_x3, vld1q_f32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_f32_x4() { - let vals: [f32; 16] = crate::array::from_fn(|i| i as f32); - let a: float32x4x4_t = transmute(vals); - let mut tmp = [0_f32; 16]; - vst1q_f32_x4(tmp.as_mut_ptr().cast(), a); - let r: float32x4x4_t = vld1q_f32_x4(tmp.as_ptr().cast()); - let out: [f32; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(f32, 16, float32x4x4_t, vst1q_f32_x4, vld1q_f32_x4); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1_p64_x2() { - let vals: [p64; 2] = crate::array::from_fn(|i| i as p64); - let a: poly64x1x2_t = transmute(vals); - let mut tmp = [0 as p64; 2]; - vst1_p64_x2(tmp.as_mut_ptr().cast(), a); - let r: poly64x1x2_t = vld1_p64_x2(tmp.as_ptr().cast()); - let out: [p64; 2] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 2, poly64x1x2_t, vst1_p64_x2, vld1_p64_x2); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1_p64_x3() { - let vals: [p64; 3] = crate::array::from_fn(|i| i as p64); - let a: poly64x1x3_t = transmute(vals); - let mut tmp = [0 as p64; 3]; - vst1_p64_x3(tmp.as_mut_ptr().cast(), a); - let r: poly64x1x3_t = vld1_p64_x3(tmp.as_ptr().cast()); - let out: [p64; 3] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 3, poly64x1x3_t, vst1_p64_x3, vld1_p64_x3); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1_p64_x4() { - let vals: [p64; 4] = crate::array::from_fn(|i| i as p64); - let a: poly64x1x4_t = transmute(vals); - let mut tmp = [0 as p64; 4]; - vst1_p64_x4(tmp.as_mut_ptr().cast(), a); - let r: poly64x1x4_t = vld1_p64_x4(tmp.as_ptr().cast()); - let out: [p64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 4, poly64x1x4_t, vst1_p64_x4, vld1_p64_x4); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1q_p64_x2() { - let vals: [p64; 4] = crate::array::from_fn(|i| i as p64); - let a: poly64x2x2_t = transmute(vals); - let mut tmp = [0 as p64; 4]; - vst1q_p64_x2(tmp.as_mut_ptr().cast(), a); - let r: poly64x2x2_t = vld1q_p64_x2(tmp.as_ptr().cast()); - let out: [p64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 4, poly64x2x2_t, vst1q_p64_x2, vld1q_p64_x2); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1q_p64_x3() { - let vals: [p64; 6] = crate::array::from_fn(|i| i as p64); - let a: poly64x2x3_t = transmute(vals); - let mut tmp = [0 as p64; 6]; - vst1q_p64_x3(tmp.as_mut_ptr().cast(), a); - let r: poly64x2x3_t = vld1q_p64_x3(tmp.as_ptr().cast()); - let out: [p64; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 6, poly64x2x3_t, vst1q_p64_x3, vld1q_p64_x3); } #[simd_test(enable = "neon,aes")] unsafe fn test_vld1q_p64_x4() { - let vals: [p64; 8] = crate::array::from_fn(|i| i as p64); - let a: poly64x2x4_t = transmute(vals); - let mut tmp = [0 as p64; 8]; - vst1q_p64_x4(tmp.as_mut_ptr().cast(), a); - let r: poly64x2x4_t = vld1q_p64_x4(tmp.as_ptr().cast()); - let out: [p64; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p64, 8, poly64x2x4_t, vst1q_p64_x4, vld1q_p64_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s8_x2() { - let vals: [i8; 16] = crate::array::from_fn(|i| i as i8); - let a: int8x8x2_t = transmute(vals); - let mut tmp = [0_i8; 16]; - vst1_s8_x2(tmp.as_mut_ptr().cast(), a); - let r: int8x8x2_t = vld1_s8_x2(tmp.as_ptr().cast()); - let out: [i8; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 16, int8x8x2_t, vst1_s8_x2, vld1_s8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s8_x3() { - let vals: [i8; 24] = crate::array::from_fn(|i| i as i8); - let a: int8x8x3_t = transmute(vals); - let mut tmp = [0_i8; 24]; - vst1_s8_x3(tmp.as_mut_ptr().cast(), a); - let r: int8x8x3_t = vld1_s8_x3(tmp.as_ptr().cast()); - let out: [i8; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 24, int8x8x3_t, vst1_s8_x3, vld1_s8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s8_x4() { - let vals: [i8; 32] = crate::array::from_fn(|i| i as i8); - let a: int8x8x4_t = transmute(vals); - let mut tmp = [0_i8; 32]; - vst1_s8_x4(tmp.as_mut_ptr().cast(), a); - let r: int8x8x4_t = vld1_s8_x4(tmp.as_ptr().cast()); - let out: [i8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 32, int8x8x4_t, vst1_s8_x4, vld1_s8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s8_x2() { - let vals: [i8; 32] = crate::array::from_fn(|i| i as i8); - let a: int8x16x2_t = transmute(vals); - let mut tmp = [0_i8; 32]; - vst1q_s8_x2(tmp.as_mut_ptr().cast(), a); - let r: int8x16x2_t = vld1q_s8_x2(tmp.as_ptr().cast()); - let out: [i8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 32, int8x16x2_t, vst1q_s8_x2, vld1q_s8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s8_x3() { - let vals: [i8; 48] = crate::array::from_fn(|i| i as i8); - let a: int8x16x3_t = transmute(vals); - let mut tmp = [0_i8; 48]; - vst1q_s8_x3(tmp.as_mut_ptr().cast(), a); - let r: int8x16x3_t = vld1q_s8_x3(tmp.as_ptr().cast()); - let out: [i8; 48] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 48, int8x16x3_t, vst1q_s8_x3, vld1q_s8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s8_x4() { - let vals: [i8; 64] = crate::array::from_fn(|i| i as i8); - let a: int8x16x4_t = transmute(vals); - let mut tmp = [0_i8; 64]; - vst1q_s8_x4(tmp.as_mut_ptr().cast(), a); - let r: int8x16x4_t = vld1q_s8_x4(tmp.as_ptr().cast()); - let out: [i8; 64] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i8, 64, int8x16x4_t, vst1q_s8_x4, vld1q_s8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s16_x2() { - let vals: [i16; 8] = crate::array::from_fn(|i| i as i16); - let a: int16x4x2_t = transmute(vals); - let mut tmp = [0_i16; 8]; - vst1_s16_x2(tmp.as_mut_ptr().cast(), a); - let r: int16x4x2_t = vld1_s16_x2(tmp.as_ptr().cast()); - let out: [i16; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 8, int16x4x2_t, vst1_s16_x2, vld1_s16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s16_x3() { - let vals: [i16; 12] = crate::array::from_fn(|i| i as i16); - let a: int16x4x3_t = transmute(vals); - let mut tmp = [0_i16; 12]; - vst1_s16_x3(tmp.as_mut_ptr().cast(), a); - let r: int16x4x3_t = vld1_s16_x3(tmp.as_ptr().cast()); - let out: [i16; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 12, int16x4x3_t, vst1_s16_x3, vld1_s16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s16_x4() { - let vals: [i16; 16] = crate::array::from_fn(|i| i as i16); - let a: int16x4x4_t = transmute(vals); - let mut tmp = [0_i16; 16]; - vst1_s16_x4(tmp.as_mut_ptr().cast(), a); - let r: int16x4x4_t = vld1_s16_x4(tmp.as_ptr().cast()); - let out: [i16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 16, int16x4x4_t, vst1_s16_x4, vld1_s16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s16_x2() { - let vals: [i16; 16] = crate::array::from_fn(|i| i as i16); - let a: int16x8x2_t = transmute(vals); - let mut tmp = [0_i16; 16]; - vst1q_s16_x2(tmp.as_mut_ptr().cast(), a); - let r: int16x8x2_t = vld1q_s16_x2(tmp.as_ptr().cast()); - let out: [i16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 16, int16x8x2_t, vst1q_s16_x2, vld1q_s16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s16_x3() { - let vals: [i16; 24] = crate::array::from_fn(|i| i as i16); - let a: int16x8x3_t = transmute(vals); - let mut tmp = [0_i16; 24]; - vst1q_s16_x3(tmp.as_mut_ptr().cast(), a); - let r: int16x8x3_t = vld1q_s16_x3(tmp.as_ptr().cast()); - let out: [i16; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 24, int16x8x3_t, vst1q_s16_x3, vld1q_s16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s16_x4() { - let vals: [i16; 32] = crate::array::from_fn(|i| i as i16); - let a: int16x8x4_t = transmute(vals); - let mut tmp = [0_i16; 32]; - vst1q_s16_x4(tmp.as_mut_ptr().cast(), a); - let r: int16x8x4_t = vld1q_s16_x4(tmp.as_ptr().cast()); - let out: [i16; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i16, 32, int16x8x4_t, vst1q_s16_x4, vld1q_s16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s32_x2() { - let vals: [i32; 4] = crate::array::from_fn(|i| i as i32); - let a: int32x2x2_t = transmute(vals); - let mut tmp = [0_i32; 4]; - vst1_s32_x2(tmp.as_mut_ptr().cast(), a); - let r: int32x2x2_t = vld1_s32_x2(tmp.as_ptr().cast()); - let out: [i32; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 4, int32x2x2_t, vst1_s32_x2, vld1_s32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s32_x3() { - let vals: [i32; 6] = crate::array::from_fn(|i| i as i32); - let a: int32x2x3_t = transmute(vals); - let mut tmp = [0_i32; 6]; - vst1_s32_x3(tmp.as_mut_ptr().cast(), a); - let r: int32x2x3_t = vld1_s32_x3(tmp.as_ptr().cast()); - let out: [i32; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 6, int32x2x3_t, vst1_s32_x3, vld1_s32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s32_x4() { - let vals: [i32; 8] = crate::array::from_fn(|i| i as i32); - let a: int32x2x4_t = transmute(vals); - let mut tmp = [0_i32; 8]; - vst1_s32_x4(tmp.as_mut_ptr().cast(), a); - let r: int32x2x4_t = vld1_s32_x4(tmp.as_ptr().cast()); - let out: [i32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 8, int32x2x4_t, vst1_s32_x4, vld1_s32_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s32_x2() { - let vals: [i32; 8] = crate::array::from_fn(|i| i as i32); - let a: int32x4x2_t = transmute(vals); - let mut tmp = [0_i32; 8]; - vst1q_s32_x2(tmp.as_mut_ptr().cast(), a); - let r: int32x4x2_t = vld1q_s32_x2(tmp.as_ptr().cast()); - let out: [i32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 8, int32x4x2_t, vst1q_s32_x2, vld1q_s32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s32_x3() { - let vals: [i32; 12] = crate::array::from_fn(|i| i as i32); - let a: int32x4x3_t = transmute(vals); - let mut tmp = [0_i32; 12]; - vst1q_s32_x3(tmp.as_mut_ptr().cast(), a); - let r: int32x4x3_t = vld1q_s32_x3(tmp.as_ptr().cast()); - let out: [i32; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 12, int32x4x3_t, vst1q_s32_x3, vld1q_s32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s32_x4() { - let vals: [i32; 16] = crate::array::from_fn(|i| i as i32); - let a: int32x4x4_t = transmute(vals); - let mut tmp = [0_i32; 16]; - vst1q_s32_x4(tmp.as_mut_ptr().cast(), a); - let r: int32x4x4_t = vld1q_s32_x4(tmp.as_ptr().cast()); - let out: [i32; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i32, 16, int32x4x4_t, vst1q_s32_x4, vld1q_s32_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s64_x2() { - let vals: [i64; 2] = crate::array::from_fn(|i| i as i64); - let a: int64x1x2_t = transmute(vals); - let mut tmp = [0_i64; 2]; - vst1_s64_x2(tmp.as_mut_ptr().cast(), a); - let r: int64x1x2_t = vld1_s64_x2(tmp.as_ptr().cast()); - let out: [i64; 2] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 2, int64x1x2_t, vst1_s64_x2, vld1_s64_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s64_x3() { - let vals: [i64; 3] = crate::array::from_fn(|i| i as i64); - let a: int64x1x3_t = transmute(vals); - let mut tmp = [0_i64; 3]; - vst1_s64_x3(tmp.as_mut_ptr().cast(), a); - let r: int64x1x3_t = vld1_s64_x3(tmp.as_ptr().cast()); - let out: [i64; 3] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 3, int64x1x3_t, vst1_s64_x3, vld1_s64_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_s64_x4() { - let vals: [i64; 4] = crate::array::from_fn(|i| i as i64); - let a: int64x1x4_t = transmute(vals); - let mut tmp = [0_i64; 4]; - vst1_s64_x4(tmp.as_mut_ptr().cast(), a); - let r: int64x1x4_t = vld1_s64_x4(tmp.as_ptr().cast()); - let out: [i64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 4, int64x1x4_t, vst1_s64_x4, vld1_s64_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s64_x2() { - let vals: [i64; 4] = crate::array::from_fn(|i| i as i64); - let a: int64x2x2_t = transmute(vals); - let mut tmp = [0_i64; 4]; - vst1q_s64_x2(tmp.as_mut_ptr().cast(), a); - let r: int64x2x2_t = vld1q_s64_x2(tmp.as_ptr().cast()); - let out: [i64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 4, int64x2x2_t, vst1q_s64_x2, vld1q_s64_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s64_x3() { - let vals: [i64; 6] = crate::array::from_fn(|i| i as i64); - let a: int64x2x3_t = transmute(vals); - let mut tmp = [0_i64; 6]; - vst1q_s64_x3(tmp.as_mut_ptr().cast(), a); - let r: int64x2x3_t = vld1q_s64_x3(tmp.as_ptr().cast()); - let out: [i64; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 6, int64x2x3_t, vst1q_s64_x3, vld1q_s64_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_s64_x4() { - let vals: [i64; 8] = crate::array::from_fn(|i| i as i64); - let a: int64x2x4_t = transmute(vals); - let mut tmp = [0_i64; 8]; - vst1q_s64_x4(tmp.as_mut_ptr().cast(), a); - let r: int64x2x4_t = vld1q_s64_x4(tmp.as_ptr().cast()); - let out: [i64; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(i64, 8, int64x2x4_t, vst1q_s64_x4, vld1q_s64_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u8_x2() { - let vals: [u8; 16] = crate::array::from_fn(|i| i as u8); - let a: uint8x8x2_t = transmute(vals); - let mut tmp = [0_u8; 16]; - vst1_u8_x2(tmp.as_mut_ptr().cast(), a); - let r: uint8x8x2_t = vld1_u8_x2(tmp.as_ptr().cast()); - let out: [u8; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 16, uint8x8x2_t, vst1_u8_x2, vld1_u8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u8_x3() { - let vals: [u8; 24] = crate::array::from_fn(|i| i as u8); - let a: uint8x8x3_t = transmute(vals); - let mut tmp = [0_u8; 24]; - vst1_u8_x3(tmp.as_mut_ptr().cast(), a); - let r: uint8x8x3_t = vld1_u8_x3(tmp.as_ptr().cast()); - let out: [u8; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 24, uint8x8x3_t, vst1_u8_x3, vld1_u8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u8_x4() { - let vals: [u8; 32] = crate::array::from_fn(|i| i as u8); - let a: uint8x8x4_t = transmute(vals); - let mut tmp = [0_u8; 32]; - vst1_u8_x4(tmp.as_mut_ptr().cast(), a); - let r: uint8x8x4_t = vld1_u8_x4(tmp.as_ptr().cast()); - let out: [u8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 32, uint8x8x4_t, vst1_u8_x4, vld1_u8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u8_x2() { - let vals: [u8; 32] = crate::array::from_fn(|i| i as u8); - let a: uint8x16x2_t = transmute(vals); - let mut tmp = [0_u8; 32]; - vst1q_u8_x2(tmp.as_mut_ptr().cast(), a); - let r: uint8x16x2_t = vld1q_u8_x2(tmp.as_ptr().cast()); - let out: [u8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 32, uint8x16x2_t, vst1q_u8_x2, vld1q_u8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u8_x3() { - let vals: [u8; 48] = crate::array::from_fn(|i| i as u8); - let a: uint8x16x3_t = transmute(vals); - let mut tmp = [0_u8; 48]; - vst1q_u8_x3(tmp.as_mut_ptr().cast(), a); - let r: uint8x16x3_t = vld1q_u8_x3(tmp.as_ptr().cast()); - let out: [u8; 48] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 48, uint8x16x3_t, vst1q_u8_x3, vld1q_u8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u8_x4() { - let vals: [u8; 64] = crate::array::from_fn(|i| i as u8); - let a: uint8x16x4_t = transmute(vals); - let mut tmp = [0_u8; 64]; - vst1q_u8_x4(tmp.as_mut_ptr().cast(), a); - let r: uint8x16x4_t = vld1q_u8_x4(tmp.as_ptr().cast()); - let out: [u8; 64] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u8, 64, uint8x16x4_t, vst1q_u8_x4, vld1q_u8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u16_x2() { - let vals: [u16; 8] = crate::array::from_fn(|i| i as u16); - let a: uint16x4x2_t = transmute(vals); - let mut tmp = [0_u16; 8]; - vst1_u16_x2(tmp.as_mut_ptr().cast(), a); - let r: uint16x4x2_t = vld1_u16_x2(tmp.as_ptr().cast()); - let out: [u16; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 8, uint16x4x2_t, vst1_u16_x2, vld1_u16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u16_x3() { - let vals: [u16; 12] = crate::array::from_fn(|i| i as u16); - let a: uint16x4x3_t = transmute(vals); - let mut tmp = [0_u16; 12]; - vst1_u16_x3(tmp.as_mut_ptr().cast(), a); - let r: uint16x4x3_t = vld1_u16_x3(tmp.as_ptr().cast()); - let out: [u16; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 12, uint16x4x3_t, vst1_u16_x3, vld1_u16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u16_x4() { - let vals: [u16; 16] = crate::array::from_fn(|i| i as u16); - let a: uint16x4x4_t = transmute(vals); - let mut tmp = [0_u16; 16]; - vst1_u16_x4(tmp.as_mut_ptr().cast(), a); - let r: uint16x4x4_t = vld1_u16_x4(tmp.as_ptr().cast()); - let out: [u16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 16, uint16x4x4_t, vst1_u16_x4, vld1_u16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u16_x2() { - let vals: [u16; 16] = crate::array::from_fn(|i| i as u16); - let a: uint16x8x2_t = transmute(vals); - let mut tmp = [0_u16; 16]; - vst1q_u16_x2(tmp.as_mut_ptr().cast(), a); - let r: uint16x8x2_t = vld1q_u16_x2(tmp.as_ptr().cast()); - let out: [u16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 16, uint16x8x2_t, vst1q_u16_x2, vld1q_u16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u16_x3() { - let vals: [u16; 24] = crate::array::from_fn(|i| i as u16); - let a: uint16x8x3_t = transmute(vals); - let mut tmp = [0_u16; 24]; - vst1q_u16_x3(tmp.as_mut_ptr().cast(), a); - let r: uint16x8x3_t = vld1q_u16_x3(tmp.as_ptr().cast()); - let out: [u16; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 24, uint16x8x3_t, vst1q_u16_x3, vld1q_u16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u16_x4() { - let vals: [u16; 32] = crate::array::from_fn(|i| i as u16); - let a: uint16x8x4_t = transmute(vals); - let mut tmp = [0_u16; 32]; - vst1q_u16_x4(tmp.as_mut_ptr().cast(), a); - let r: uint16x8x4_t = vld1q_u16_x4(tmp.as_ptr().cast()); - let out: [u16; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u16, 32, uint16x8x4_t, vst1q_u16_x4, vld1q_u16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u32_x2() { - let vals: [u32; 4] = crate::array::from_fn(|i| i as u32); - let a: uint32x2x2_t = transmute(vals); - let mut tmp = [0_u32; 4]; - vst1_u32_x2(tmp.as_mut_ptr().cast(), a); - let r: uint32x2x2_t = vld1_u32_x2(tmp.as_ptr().cast()); - let out: [u32; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 4, uint32x2x2_t, vst1_u32_x2, vld1_u32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u32_x3() { - let vals: [u32; 6] = crate::array::from_fn(|i| i as u32); - let a: uint32x2x3_t = transmute(vals); - let mut tmp = [0_u32; 6]; - vst1_u32_x3(tmp.as_mut_ptr().cast(), a); - let r: uint32x2x3_t = vld1_u32_x3(tmp.as_ptr().cast()); - let out: [u32; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 6, uint32x2x3_t, vst1_u32_x3, vld1_u32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u32_x4() { - let vals: [u32; 8] = crate::array::from_fn(|i| i as u32); - let a: uint32x2x4_t = transmute(vals); - let mut tmp = [0_u32; 8]; - vst1_u32_x4(tmp.as_mut_ptr().cast(), a); - let r: uint32x2x4_t = vld1_u32_x4(tmp.as_ptr().cast()); - let out: [u32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 8, uint32x2x4_t, vst1_u32_x4, vld1_u32_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u32_x2() { - let vals: [u32; 8] = crate::array::from_fn(|i| i as u32); - let a: uint32x4x2_t = transmute(vals); - let mut tmp = [0_u32; 8]; - vst1q_u32_x2(tmp.as_mut_ptr().cast(), a); - let r: uint32x4x2_t = vld1q_u32_x2(tmp.as_ptr().cast()); - let out: [u32; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 8, uint32x4x2_t, vst1q_u32_x2, vld1q_u32_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u32_x3() { - let vals: [u32; 12] = crate::array::from_fn(|i| i as u32); - let a: uint32x4x3_t = transmute(vals); - let mut tmp = [0_u32; 12]; - vst1q_u32_x3(tmp.as_mut_ptr().cast(), a); - let r: uint32x4x3_t = vld1q_u32_x3(tmp.as_ptr().cast()); - let out: [u32; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 12, uint32x4x3_t, vst1q_u32_x3, vld1q_u32_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u32_x4() { - let vals: [u32; 16] = crate::array::from_fn(|i| i as u32); - let a: uint32x4x4_t = transmute(vals); - let mut tmp = [0_u32; 16]; - vst1q_u32_x4(tmp.as_mut_ptr().cast(), a); - let r: uint32x4x4_t = vld1q_u32_x4(tmp.as_ptr().cast()); - let out: [u32; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u32, 16, uint32x4x4_t, vst1q_u32_x4, vld1q_u32_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u64_x2() { - let vals: [u64; 2] = crate::array::from_fn(|i| i as u64); - let a: uint64x1x2_t = transmute(vals); - let mut tmp = [0_u64; 2]; - vst1_u64_x2(tmp.as_mut_ptr().cast(), a); - let r: uint64x1x2_t = vld1_u64_x2(tmp.as_ptr().cast()); - let out: [u64; 2] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 2, uint64x1x2_t, vst1_u64_x2, vld1_u64_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u64_x3() { - let vals: [u64; 3] = crate::array::from_fn(|i| i as u64); - let a: uint64x1x3_t = transmute(vals); - let mut tmp = [0_u64; 3]; - vst1_u64_x3(tmp.as_mut_ptr().cast(), a); - let r: uint64x1x3_t = vld1_u64_x3(tmp.as_ptr().cast()); - let out: [u64; 3] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 3, uint64x1x3_t, vst1_u64_x3, vld1_u64_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_u64_x4() { - let vals: [u64; 4] = crate::array::from_fn(|i| i as u64); - let a: uint64x1x4_t = transmute(vals); - let mut tmp = [0_u64; 4]; - vst1_u64_x4(tmp.as_mut_ptr().cast(), a); - let r: uint64x1x4_t = vld1_u64_x4(tmp.as_ptr().cast()); - let out: [u64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 4, uint64x1x4_t, vst1_u64_x4, vld1_u64_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u64_x2() { - let vals: [u64; 4] = crate::array::from_fn(|i| i as u64); - let a: uint64x2x2_t = transmute(vals); - let mut tmp = [0_u64; 4]; - vst1q_u64_x2(tmp.as_mut_ptr().cast(), a); - let r: uint64x2x2_t = vld1q_u64_x2(tmp.as_ptr().cast()); - let out: [u64; 4] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 4, uint64x2x2_t, vst1q_u64_x2, vld1q_u64_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u64_x3() { - let vals: [u64; 6] = crate::array::from_fn(|i| i as u64); - let a: uint64x2x3_t = transmute(vals); - let mut tmp = [0_u64; 6]; - vst1q_u64_x3(tmp.as_mut_ptr().cast(), a); - let r: uint64x2x3_t = vld1q_u64_x3(tmp.as_ptr().cast()); - let out: [u64; 6] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 6, uint64x2x3_t, vst1q_u64_x3, vld1q_u64_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_u64_x4() { - let vals: [u64; 8] = crate::array::from_fn(|i| i as u64); - let a: uint64x2x4_t = transmute(vals); - let mut tmp = [0_u64; 8]; - vst1q_u64_x4(tmp.as_mut_ptr().cast(), a); - let r: uint64x2x4_t = vld1q_u64_x4(tmp.as_ptr().cast()); - let out: [u64; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(u64, 8, uint64x2x4_t, vst1q_u64_x4, vld1q_u64_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p8_x2() { - let vals: [p8; 16] = crate::array::from_fn(|i| i as p8); - let a: poly8x8x2_t = transmute(vals); - let mut tmp = [0 as p8; 16]; - vst1_p8_x2(tmp.as_mut_ptr().cast(), a); - let r: poly8x8x2_t = vld1_p8_x2(tmp.as_ptr().cast()); - let out: [p8; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 16, poly8x8x2_t, vst1_p8_x2, vld1_p8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p8_x3() { - let vals: [p8; 24] = crate::array::from_fn(|i| i as p8); - let a: poly8x8x3_t = transmute(vals); - let mut tmp = [0 as p8; 24]; - vst1_p8_x3(tmp.as_mut_ptr().cast(), a); - let r: poly8x8x3_t = vld1_p8_x3(tmp.as_ptr().cast()); - let out: [p8; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 24, poly8x8x3_t, vst1_p8_x3, vld1_p8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p8_x4() { - let vals: [p8; 32] = crate::array::from_fn(|i| i as p8); - let a: poly8x8x4_t = transmute(vals); - let mut tmp = [0 as p8; 32]; - vst1_p8_x4(tmp.as_mut_ptr().cast(), a); - let r: poly8x8x4_t = vld1_p8_x4(tmp.as_ptr().cast()); - let out: [p8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 32, poly8x8x4_t, vst1_p8_x4, vld1_p8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p8_x2() { - let vals: [p8; 32] = crate::array::from_fn(|i| i as p8); - let a: poly8x16x2_t = transmute(vals); - let mut tmp = [0 as p8; 32]; - vst1q_p8_x2(tmp.as_mut_ptr().cast(), a); - let r: poly8x16x2_t = vld1q_p8_x2(tmp.as_ptr().cast()); - let out: [p8; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 32, poly8x16x2_t, vst1q_p8_x2, vld1q_p8_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p8_x3() { - let vals: [p8; 48] = crate::array::from_fn(|i| i as p8); - let a: poly8x16x3_t = transmute(vals); - let mut tmp = [0 as p8; 48]; - vst1q_p8_x3(tmp.as_mut_ptr().cast(), a); - let r: poly8x16x3_t = vld1q_p8_x3(tmp.as_ptr().cast()); - let out: [p8; 48] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 48, poly8x16x3_t, vst1q_p8_x3, vld1q_p8_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p8_x4() { - let vals: [p8; 64] = crate::array::from_fn(|i| i as p8); - let a: poly8x16x4_t = transmute(vals); - let mut tmp = [0 as p8; 64]; - vst1q_p8_x4(tmp.as_mut_ptr().cast(), a); - let r: poly8x16x4_t = vld1q_p8_x4(tmp.as_ptr().cast()); - let out: [p8; 64] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p8, 64, poly8x16x4_t, vst1q_p8_x4, vld1q_p8_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p16_x2() { - let vals: [p16; 8] = crate::array::from_fn(|i| i as p16); - let a: poly16x4x2_t = transmute(vals); - let mut tmp = [0 as p16; 8]; - vst1_p16_x2(tmp.as_mut_ptr().cast(), a); - let r: poly16x4x2_t = vld1_p16_x2(tmp.as_ptr().cast()); - let out: [p16; 8] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 8, poly16x4x2_t, vst1_p16_x2, vld1_p16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p16_x3() { - let vals: [p16; 12] = crate::array::from_fn(|i| i as p16); - let a: poly16x4x3_t = transmute(vals); - let mut tmp = [0 as p16; 12]; - vst1_p16_x3(tmp.as_mut_ptr().cast(), a); - let r: poly16x4x3_t = vld1_p16_x3(tmp.as_ptr().cast()); - let out: [p16; 12] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 12, poly16x4x3_t, vst1_p16_x3, vld1_p16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1_p16_x4() { - let vals: [p16; 16] = crate::array::from_fn(|i| i as p16); - let a: poly16x4x4_t = transmute(vals); - let mut tmp = [0 as p16; 16]; - vst1_p16_x4(tmp.as_mut_ptr().cast(), a); - let r: poly16x4x4_t = vld1_p16_x4(tmp.as_ptr().cast()); - let out: [p16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 16, poly16x4x4_t, vst1_p16_x4, vld1_p16_x4); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p16_x2() { - let vals: [p16; 16] = crate::array::from_fn(|i| i as p16); - let a: poly16x8x2_t = transmute(vals); - let mut tmp = [0 as p16; 16]; - vst1q_p16_x2(tmp.as_mut_ptr().cast(), a); - let r: poly16x8x2_t = vld1q_p16_x2(tmp.as_ptr().cast()); - let out: [p16; 16] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 16, poly16x8x2_t, vst1q_p16_x2, vld1q_p16_x2); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p16_x3() { - let vals: [p16; 24] = crate::array::from_fn(|i| i as p16); - let a: poly16x8x3_t = transmute(vals); - let mut tmp = [0 as p16; 24]; - vst1q_p16_x3(tmp.as_mut_ptr().cast(), a); - let r: poly16x8x3_t = vld1q_p16_x3(tmp.as_ptr().cast()); - let out: [p16; 24] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 24, poly16x8x3_t, vst1q_p16_x3, vld1q_p16_x3); } #[simd_test(enable = "neon")] unsafe fn test_vld1q_p16_x4() { - let vals: [p16; 32] = crate::array::from_fn(|i| i as p16); - let a: poly16x8x4_t = transmute(vals); - let mut tmp = [0 as p16; 32]; - vst1q_p16_x4(tmp.as_mut_ptr().cast(), a); - let r: poly16x8x4_t = vld1q_p16_x4(tmp.as_ptr().cast()); - let out: [p16; 32] = transmute(r); - assert_eq!(out, vals); + wide_store_load_roundtrip!(p16, 32, poly16x8x4_t, vst1q_p16_x4, vld1q_p16_x4); } } From 794810f897559a86d2de36344e13ad3c065d5217 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 1 Feb 2026 14:17:35 +0100 Subject: [PATCH 14/81] use more capable macro for wide store/load roundtrip tests --- .../crates/core_arch/src/aarch64/neon/mod.rs | 532 +++++------------- 1 file changed, 140 insertions(+), 392 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index ee27bef9738c..580f203ef066 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -1006,400 +1006,148 @@ mod tests { }; } - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1_f16_x2() { - wide_store_load_roundtrip!(f16, 8, float16x4x2_t, vst1_f16_x2, vld1_f16_x2); - } - - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1_f16_x3() { - wide_store_load_roundtrip!(f16, 12, float16x4x3_t, vst1_f16_x3, vld1_f16_x3); - } - - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1_f16_x4() { - wide_store_load_roundtrip!(f16, 16, float16x4x4_t, vst1_f16_x4, vld1_f16_x4); - } - - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1q_f16_x2() { - wide_store_load_roundtrip!(f16, 16, float16x8x2_t, vst1q_f16_x2, vld1q_f16_x2); - } - - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1q_f16_x3() { - wide_store_load_roundtrip!(f16, 24, float16x8x3_t, vst1q_f16_x3, vld1q_f16_x3); - } - - #[simd_test(enable = "neon,fp16")] - #[cfg(not(target_arch = "arm64ec"))] - unsafe fn test_vld1q_f16_x4() { - wide_store_load_roundtrip!(f16, 32, float16x8x4_t, vst1q_f16_x4, vld1q_f16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_f32_x2() { - wide_store_load_roundtrip!(f32, 4, float32x2x2_t, vst1_f32_x2, vld1_f32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_f32_x3() { - wide_store_load_roundtrip!(f32, 6, float32x2x3_t, vst1_f32_x3, vld1_f32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_f32_x4() { - wide_store_load_roundtrip!(f32, 8, float32x2x4_t, vst1_f32_x4, vld1_f32_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_f32_x2() { - wide_store_load_roundtrip!(f32, 8, float32x4x2_t, vst1q_f32_x2, vld1q_f32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_f32_x3() { - wide_store_load_roundtrip!(f32, 12, float32x4x3_t, vst1q_f32_x3, vld1q_f32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_f32_x4() { - wide_store_load_roundtrip!(f32, 16, float32x4x4_t, vst1q_f32_x4, vld1q_f32_x4); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1_p64_x2() { - wide_store_load_roundtrip!(p64, 2, poly64x1x2_t, vst1_p64_x2, vld1_p64_x2); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1_p64_x3() { - wide_store_load_roundtrip!(p64, 3, poly64x1x3_t, vst1_p64_x3, vld1_p64_x3); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1_p64_x4() { - wide_store_load_roundtrip!(p64, 4, poly64x1x4_t, vst1_p64_x4, vld1_p64_x4); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1q_p64_x2() { - wide_store_load_roundtrip!(p64, 4, poly64x2x2_t, vst1q_p64_x2, vld1q_p64_x2); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1q_p64_x3() { - wide_store_load_roundtrip!(p64, 6, poly64x2x3_t, vst1q_p64_x3, vld1q_p64_x3); - } - - #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1q_p64_x4() { - wide_store_load_roundtrip!(p64, 8, poly64x2x4_t, vst1q_p64_x4, vld1q_p64_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s8_x2() { - wide_store_load_roundtrip!(i8, 16, int8x8x2_t, vst1_s8_x2, vld1_s8_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s8_x3() { - wide_store_load_roundtrip!(i8, 24, int8x8x3_t, vst1_s8_x3, vld1_s8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s8_x4() { - wide_store_load_roundtrip!(i8, 32, int8x8x4_t, vst1_s8_x4, vld1_s8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s8_x2() { - wide_store_load_roundtrip!(i8, 32, int8x16x2_t, vst1q_s8_x2, vld1q_s8_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s8_x3() { - wide_store_load_roundtrip!(i8, 48, int8x16x3_t, vst1q_s8_x3, vld1q_s8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s8_x4() { - wide_store_load_roundtrip!(i8, 64, int8x16x4_t, vst1q_s8_x4, vld1q_s8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s16_x2() { - wide_store_load_roundtrip!(i16, 8, int16x4x2_t, vst1_s16_x2, vld1_s16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s16_x3() { - wide_store_load_roundtrip!(i16, 12, int16x4x3_t, vst1_s16_x3, vld1_s16_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s16_x4() { - wide_store_load_roundtrip!(i16, 16, int16x4x4_t, vst1_s16_x4, vld1_s16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s16_x2() { - wide_store_load_roundtrip!(i16, 16, int16x8x2_t, vst1q_s16_x2, vld1q_s16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s16_x3() { - wide_store_load_roundtrip!(i16, 24, int16x8x3_t, vst1q_s16_x3, vld1q_s16_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s16_x4() { - wide_store_load_roundtrip!(i16, 32, int16x8x4_t, vst1q_s16_x4, vld1q_s16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s32_x2() { - wide_store_load_roundtrip!(i32, 4, int32x2x2_t, vst1_s32_x2, vld1_s32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s32_x3() { - wide_store_load_roundtrip!(i32, 6, int32x2x3_t, vst1_s32_x3, vld1_s32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s32_x4() { - wide_store_load_roundtrip!(i32, 8, int32x2x4_t, vst1_s32_x4, vld1_s32_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s32_x2() { - wide_store_load_roundtrip!(i32, 8, int32x4x2_t, vst1q_s32_x2, vld1q_s32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s32_x3() { - wide_store_load_roundtrip!(i32, 12, int32x4x3_t, vst1q_s32_x3, vld1q_s32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s32_x4() { - wide_store_load_roundtrip!(i32, 16, int32x4x4_t, vst1q_s32_x4, vld1q_s32_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s64_x2() { - wide_store_load_roundtrip!(i64, 2, int64x1x2_t, vst1_s64_x2, vld1_s64_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s64_x3() { - wide_store_load_roundtrip!(i64, 3, int64x1x3_t, vst1_s64_x3, vld1_s64_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_s64_x4() { - wide_store_load_roundtrip!(i64, 4, int64x1x4_t, vst1_s64_x4, vld1_s64_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s64_x2() { - wide_store_load_roundtrip!(i64, 4, int64x2x2_t, vst1q_s64_x2, vld1q_s64_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s64_x3() { - wide_store_load_roundtrip!(i64, 6, int64x2x3_t, vst1q_s64_x3, vld1q_s64_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_s64_x4() { - wide_store_load_roundtrip!(i64, 8, int64x2x4_t, vst1q_s64_x4, vld1q_s64_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u8_x2() { - wide_store_load_roundtrip!(u8, 16, uint8x8x2_t, vst1_u8_x2, vld1_u8_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u8_x3() { - wide_store_load_roundtrip!(u8, 24, uint8x8x3_t, vst1_u8_x3, vld1_u8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u8_x4() { - wide_store_load_roundtrip!(u8, 32, uint8x8x4_t, vst1_u8_x4, vld1_u8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u8_x2() { - wide_store_load_roundtrip!(u8, 32, uint8x16x2_t, vst1q_u8_x2, vld1q_u8_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u8_x3() { - wide_store_load_roundtrip!(u8, 48, uint8x16x3_t, vst1q_u8_x3, vld1q_u8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u8_x4() { - wide_store_load_roundtrip!(u8, 64, uint8x16x4_t, vst1q_u8_x4, vld1q_u8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u16_x2() { - wide_store_load_roundtrip!(u16, 8, uint16x4x2_t, vst1_u16_x2, vld1_u16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u16_x3() { - wide_store_load_roundtrip!(u16, 12, uint16x4x3_t, vst1_u16_x3, vld1_u16_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u16_x4() { - wide_store_load_roundtrip!(u16, 16, uint16x4x4_t, vst1_u16_x4, vld1_u16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u16_x2() { - wide_store_load_roundtrip!(u16, 16, uint16x8x2_t, vst1q_u16_x2, vld1q_u16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u16_x3() { - wide_store_load_roundtrip!(u16, 24, uint16x8x3_t, vst1q_u16_x3, vld1q_u16_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u16_x4() { - wide_store_load_roundtrip!(u16, 32, uint16x8x4_t, vst1q_u16_x4, vld1q_u16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u32_x2() { - wide_store_load_roundtrip!(u32, 4, uint32x2x2_t, vst1_u32_x2, vld1_u32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u32_x3() { - wide_store_load_roundtrip!(u32, 6, uint32x2x3_t, vst1_u32_x3, vld1_u32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u32_x4() { - wide_store_load_roundtrip!(u32, 8, uint32x2x4_t, vst1_u32_x4, vld1_u32_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u32_x2() { - wide_store_load_roundtrip!(u32, 8, uint32x4x2_t, vst1q_u32_x2, vld1q_u32_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u32_x3() { - wide_store_load_roundtrip!(u32, 12, uint32x4x3_t, vst1q_u32_x3, vld1q_u32_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u32_x4() { - wide_store_load_roundtrip!(u32, 16, uint32x4x4_t, vst1q_u32_x4, vld1q_u32_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u64_x2() { - wide_store_load_roundtrip!(u64, 2, uint64x1x2_t, vst1_u64_x2, vld1_u64_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u64_x3() { - wide_store_load_roundtrip!(u64, 3, uint64x1x3_t, vst1_u64_x3, vld1_u64_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_u64_x4() { - wide_store_load_roundtrip!(u64, 4, uint64x1x4_t, vst1_u64_x4, vld1_u64_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u64_x2() { - wide_store_load_roundtrip!(u64, 4, uint64x2x2_t, vst1q_u64_x2, vld1q_u64_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u64_x3() { - wide_store_load_roundtrip!(u64, 6, uint64x2x3_t, vst1q_u64_x3, vld1q_u64_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_u64_x4() { - wide_store_load_roundtrip!(u64, 8, uint64x2x4_t, vst1q_u64_x4, vld1q_u64_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p8_x2() { - wide_store_load_roundtrip!(p8, 16, poly8x8x2_t, vst1_p8_x2, vld1_p8_x2); - } + macro_rules! wide_store_load_roundtrip_fp16 { + ($( $name:ident $args:tt);* $(;)?) => { + $( + #[simd_test(enable = "neon,fp16")] + #[cfg(not(target_arch = "arm64ec"))] + unsafe fn $name() { + wide_store_load_roundtrip! $args; + } + )* + }; + } + + wide_store_load_roundtrip_fp16! { + test_vld1_f16_x2(f16, 8, float16x4x2_t, vst1_f16_x2, vld1_f16_x2); + test_vld1_f16_x3(f16, 12, float16x4x3_t, vst1_f16_x3, vld1_f16_x3); + test_vld1_f16_x4(f16, 16, float16x4x4_t, vst1_f16_x4, vld1_f16_x4); + + test_vld1q_f16_x2(f16, 16, float16x8x2_t, vst1q_f16_x2, vld1q_f16_x2); + test_vld1q_f16_x3(f16, 24, float16x8x3_t, vst1q_f16_x3, vld1q_f16_x3); + test_vld1q_f16_x4(f16, 32, float16x8x4_t, vst1q_f16_x4, vld1q_f16_x4); + } + + macro_rules! wide_store_load_roundtrip_aes { + ($( $name:ident $args:tt);* $(;)?) => { + $( + #[simd_test(enable = "neon,aes")] + unsafe fn $name() { + wide_store_load_roundtrip! $args; + } + )* + }; + } + + wide_store_load_roundtrip_aes! { + test_vld1_p64_x2(p64, 2, poly64x1x2_t, vst1_p64_x2, vld1_p64_x2); + test_vld1_p64_x3(p64, 3, poly64x1x3_t, vst1_p64_x3, vld1_p64_x3); + test_vld1_p64_x4(p64, 4, poly64x1x4_t, vst1_p64_x4, vld1_p64_x4); + + test_vld1q_p64_x2(p64, 4, poly64x2x2_t, vst1q_p64_x2, vld1q_p64_x2); + test_vld1q_p64_x3(p64, 6, poly64x2x3_t, vst1q_p64_x3, vld1q_p64_x3); + test_vld1q_p64_x4(p64, 8, poly64x2x4_t, vst1q_p64_x4, vld1q_p64_x4); + } + + macro_rules! wide_store_load_roundtrip_neon { + ($( $name:ident $args:tt);* $(;)?) => { + $( + #[simd_test(enable = "neon")] + unsafe fn $name() { + wide_store_load_roundtrip! $args; + } + )* + }; + } + + wide_store_load_roundtrip_neon! { + test_vld1_f32_x2(f32, 4, float32x2x2_t, vst1_f32_x2, vld1_f32_x2); + test_vld1_f32_x3(f32, 6, float32x2x3_t, vst1_f32_x3, vld1_f32_x3); + test_vld1_f32_x4(f32, 8, float32x2x4_t, vst1_f32_x4, vld1_f32_x4); + + test_vld1q_f32_x2(f32, 8, float32x4x2_t, vst1q_f32_x2, vld1q_f32_x2); + test_vld1q_f32_x3(f32, 12, float32x4x3_t, vst1q_f32_x3, vld1q_f32_x3); + test_vld1q_f32_x4(f32, 16, float32x4x4_t, vst1q_f32_x4, vld1q_f32_x4); + + test_vld1_s8_x2(i8, 16, int8x8x2_t, vst1_s8_x2, vld1_s8_x2); + test_vld1_s8_x3(i8, 24, int8x8x3_t, vst1_s8_x3, vld1_s8_x3); + test_vld1_s8_x4(i8, 32, int8x8x4_t, vst1_s8_x4, vld1_s8_x4); + + test_vld1q_s8_x2(i8, 32, int8x16x2_t, vst1q_s8_x2, vld1q_s8_x2); + test_vld1q_s8_x3(i8, 48, int8x16x3_t, vst1q_s8_x3, vld1q_s8_x3); + test_vld1q_s8_x4(i8, 64, int8x16x4_t, vst1q_s8_x4, vld1q_s8_x4); + + test_vld1_s16_x2(i16, 8, int16x4x2_t, vst1_s16_x2, vld1_s16_x2); + test_vld1_s16_x3(i16, 12, int16x4x3_t, vst1_s16_x3, vld1_s16_x3); + test_vld1_s16_x4(i16, 16, int16x4x4_t, vst1_s16_x4, vld1_s16_x4); + + test_vld1q_s16_x2(i16, 16, int16x8x2_t, vst1q_s16_x2, vld1q_s16_x2); + test_vld1q_s16_x3(i16, 24, int16x8x3_t, vst1q_s16_x3, vld1q_s16_x3); + test_vld1q_s16_x4(i16, 32, int16x8x4_t, vst1q_s16_x4, vld1q_s16_x4); + + test_vld1_s32_x2(i32, 4, int32x2x2_t, vst1_s32_x2, vld1_s32_x2); + test_vld1_s32_x3(i32, 6, int32x2x3_t, vst1_s32_x3, vld1_s32_x3); + test_vld1_s32_x4(i32, 8, int32x2x4_t, vst1_s32_x4, vld1_s32_x4); + + test_vld1q_s32_x2(i32, 8, int32x4x2_t, vst1q_s32_x2, vld1q_s32_x2); + test_vld1q_s32_x3(i32, 12, int32x4x3_t, vst1q_s32_x3, vld1q_s32_x3); + test_vld1q_s32_x4(i32, 16, int32x4x4_t, vst1q_s32_x4, vld1q_s32_x4); + + test_vld1_s64_x2(i64, 2, int64x1x2_t, vst1_s64_x2, vld1_s64_x2); + test_vld1_s64_x3(i64, 3, int64x1x3_t, vst1_s64_x3, vld1_s64_x3); + test_vld1_s64_x4(i64, 4, int64x1x4_t, vst1_s64_x4, vld1_s64_x4); + + test_vld1q_s64_x2(i64, 4, int64x2x2_t, vst1q_s64_x2, vld1q_s64_x2); + test_vld1q_s64_x3(i64, 6, int64x2x3_t, vst1q_s64_x3, vld1q_s64_x3); + test_vld1q_s64_x4(i64, 8, int64x2x4_t, vst1q_s64_x4, vld1q_s64_x4); + + test_vld1_u8_x2(u8, 16, uint8x8x2_t, vst1_u8_x2, vld1_u8_x2); + test_vld1_u8_x3(u8, 24, uint8x8x3_t, vst1_u8_x3, vld1_u8_x3); + test_vld1_u8_x4(u8, 32, uint8x8x4_t, vst1_u8_x4, vld1_u8_x4); + + test_vld1q_u8_x2(u8, 32, uint8x16x2_t, vst1q_u8_x2, vld1q_u8_x2); + test_vld1q_u8_x3(u8, 48, uint8x16x3_t, vst1q_u8_x3, vld1q_u8_x3); + test_vld1q_u8_x4(u8, 64, uint8x16x4_t, vst1q_u8_x4, vld1q_u8_x4); + + test_vld1_u16_x2(u16, 8, uint16x4x2_t, vst1_u16_x2, vld1_u16_x2); + test_vld1_u16_x3(u16, 12, uint16x4x3_t, vst1_u16_x3, vld1_u16_x3); + test_vld1_u16_x4(u16, 16, uint16x4x4_t, vst1_u16_x4, vld1_u16_x4); + + test_vld1q_u16_x2(u16, 16, uint16x8x2_t, vst1q_u16_x2, vld1q_u16_x2); + test_vld1q_u16_x3(u16, 24, uint16x8x3_t, vst1q_u16_x3, vld1q_u16_x3); + test_vld1q_u16_x4(u16, 32, uint16x8x4_t, vst1q_u16_x4, vld1q_u16_x4); - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p8_x3() { - wide_store_load_roundtrip!(p8, 24, poly8x8x3_t, vst1_p8_x3, vld1_p8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p8_x4() { - wide_store_load_roundtrip!(p8, 32, poly8x8x4_t, vst1_p8_x4, vld1_p8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p8_x2() { - wide_store_load_roundtrip!(p8, 32, poly8x16x2_t, vst1q_p8_x2, vld1q_p8_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p8_x3() { - wide_store_load_roundtrip!(p8, 48, poly8x16x3_t, vst1q_p8_x3, vld1q_p8_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p8_x4() { - wide_store_load_roundtrip!(p8, 64, poly8x16x4_t, vst1q_p8_x4, vld1q_p8_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p16_x2() { - wide_store_load_roundtrip!(p16, 8, poly16x4x2_t, vst1_p16_x2, vld1_p16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p16_x3() { - wide_store_load_roundtrip!(p16, 12, poly16x4x3_t, vst1_p16_x3, vld1_p16_x3); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1_p16_x4() { - wide_store_load_roundtrip!(p16, 16, poly16x4x4_t, vst1_p16_x4, vld1_p16_x4); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p16_x2() { - wide_store_load_roundtrip!(p16, 16, poly16x8x2_t, vst1q_p16_x2, vld1q_p16_x2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p16_x3() { - wide_store_load_roundtrip!(p16, 24, poly16x8x3_t, vst1q_p16_x3, vld1q_p16_x3); - } + test_vld1_u32_x2(u32, 4, uint32x2x2_t, vst1_u32_x2, vld1_u32_x2); + test_vld1_u32_x3(u32, 6, uint32x2x3_t, vst1_u32_x3, vld1_u32_x3); + test_vld1_u32_x4(u32, 8, uint32x2x4_t, vst1_u32_x4, vld1_u32_x4); + + test_vld1q_u32_x2(u32, 8, uint32x4x2_t, vst1q_u32_x2, vld1q_u32_x2); + test_vld1q_u32_x3(u32, 12, uint32x4x3_t, vst1q_u32_x3, vld1q_u32_x3); + test_vld1q_u32_x4(u32, 16, uint32x4x4_t, vst1q_u32_x4, vld1q_u32_x4); + + test_vld1_u64_x2(u64, 2, uint64x1x2_t, vst1_u64_x2, vld1_u64_x2); + test_vld1_u64_x3(u64, 3, uint64x1x3_t, vst1_u64_x3, vld1_u64_x3); + test_vld1_u64_x4(u64, 4, uint64x1x4_t, vst1_u64_x4, vld1_u64_x4); + + test_vld1q_u64_x2(u64, 4, uint64x2x2_t, vst1q_u64_x2, vld1q_u64_x2); + test_vld1q_u64_x3(u64, 6, uint64x2x3_t, vst1q_u64_x3, vld1q_u64_x3); + test_vld1q_u64_x4(u64, 8, uint64x2x4_t, vst1q_u64_x4, vld1q_u64_x4); + + test_vld1_p8_x2(p8, 16, poly8x8x2_t, vst1_p8_x2, vld1_p8_x2); + test_vld1_p8_x3(p8, 24, poly8x8x3_t, vst1_p8_x3, vld1_p8_x3); + test_vld1_p8_x4(p8, 32, poly8x8x4_t, vst1_p8_x4, vld1_p8_x4); - #[simd_test(enable = "neon")] - unsafe fn test_vld1q_p16_x4() { - wide_store_load_roundtrip!(p16, 32, poly16x8x4_t, vst1q_p16_x4, vld1q_p16_x4); + test_vld1q_p8_x2(p8, 32, poly8x16x2_t, vst1q_p8_x2, vld1q_p8_x2); + test_vld1q_p8_x3(p8, 48, poly8x16x3_t, vst1q_p8_x3, vld1q_p8_x3); + test_vld1q_p8_x4(p8, 64, poly8x16x4_t, vst1q_p8_x4, vld1q_p8_x4); + + test_vld1_p16_x2(p16, 8, poly16x4x2_t, vst1_p16_x2, vld1_p16_x2); + test_vld1_p16_x3(p16, 12, poly16x4x3_t, vst1_p16_x3, vld1_p16_x3); + test_vld1_p16_x4(p16, 16, poly16x4x4_t, vst1_p16_x4, vld1_p16_x4); + + test_vld1q_p16_x2(p16, 16, poly16x8x2_t, vst1q_p16_x2, vld1q_p16_x2); + test_vld1q_p16_x3(p16, 24, poly16x8x3_t, vst1q_p16_x3, vld1q_p16_x3); + test_vld1q_p16_x4(p16, 32, poly16x8x4_t, vst1q_p16_x4, vld1q_p16_x4); } } From 141a867b02e090c432895779812948f2c354efa7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 1 Feb 2026 01:40:06 +0100 Subject: [PATCH 15/81] Revert "Use LLVM intrinsics for `madd` intrinsics" This reverts commit 32146718741ee22ff0d54d21b9ab60353014c980. --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 26 +++----- .../crates/core_arch/src/x86/avx512bw.rs | 64 ++++++++++--------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 26 +++----- 3 files changed, 53 insertions(+), 63 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 83aef753c9d9..8e9a56bb8518 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -1841,20 +1841,14 @@ pub const fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { - // It's a trick used in the Adler-32 algorithm to perform a widening addition. - // - // ```rust - // #[target_feature(enable = "avx2")] - // unsafe fn widening_add(mad: __m256i) -> __m256i { - // _mm256_madd_epi16(mad, _mm256_set1_epi16(1)) - // } - // ``` - // - // If we implement this using generic vector intrinsics, the optimizer - // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. - // For this reason, we use x86 intrinsics. - unsafe { transmute(pmaddwd(a.as_i16x16(), b.as_i16x16())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { + unsafe { + let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16())); + let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]); + let odd: i32x8 = simd_shuffle!(r, r, [1, 3, 5, 7, 9, 11, 13, 15]); + simd_add(even, odd).as_m256i() + } } /// Vertically multiplies each unsigned 8-bit integer from `a` with the @@ -3819,8 +3813,6 @@ pub const fn _mm256_extract_epi16(a: __m256i) -> i32 { #[allow(improper_ctypes)] unsafe extern "C" { - #[link_name = "llvm.x86.avx2.pmadd.wd"] - fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; #[link_name = "llvm.x86.avx2.pmadd.ub.sw"] fn pmaddubsw(a: u8x32, b: i8x32) -> i16x16; #[link_name = "llvm.x86.avx2.mpsadbw"] @@ -4669,7 +4661,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_madd_epi16() { + const fn test_mm256_madd_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_madd_epi16(a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 8e074fdcfa48..e2d12cd97264 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6321,20 +6321,22 @@ pub const unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { - // It's a trick used in the Adler-32 algorithm to perform a widening addition. - // - // ```rust - // #[target_feature(enable = "avx512bw")] - // unsafe fn widening_add(mad: __m512i) -> __m512i { - // _mm512_madd_epi16(mad, _mm512_set1_epi16(1)) - // } - // ``` - // - // If we implement this using generic vector intrinsics, the optimizer - // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. - // For this reason, we use x86 intrinsics. - unsafe { transmute(vpmaddwd(a.as_i16x32(), b.as_i16x32())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { + unsafe { + let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32())); + let even: i32x16 = simd_shuffle!( + r, + r, + [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] + ); + let odd: i32x16 = simd_shuffle!( + r, + r, + [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] + ); + simd_add(even, odd).as_m512i() + } } /// Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6344,7 +6346,8 @@ pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, src.as_i32x16())) @@ -6358,7 +6361,8 @@ pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, i32x16::ZERO)) @@ -6372,7 +6376,8 @@ pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, src.as_i32x8())) @@ -6386,7 +6391,8 @@ pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, i32x8::ZERO)) @@ -6400,7 +6406,8 @@ pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, src.as_i32x4())) @@ -6414,7 +6421,8 @@ pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, i32x4::ZERO)) @@ -12574,8 +12582,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"] fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32; - #[link_name = "llvm.x86.avx512.pmaddw.d.512"] - fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16; #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; @@ -17500,7 +17506,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_madd_epi16() { + const fn test_mm512_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_madd_epi16(a, b); @@ -17509,7 +17515,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_madd_epi16() { + const fn test_mm512_mask_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_madd_epi16(a, 0, a, b); @@ -17537,7 +17543,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_madd_epi16() { + const fn test_mm512_maskz_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_madd_epi16(0, a, b); @@ -17548,7 +17554,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_madd_epi16() { + const fn test_mm256_mask_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_madd_epi16(a, 0, a, b); @@ -17568,7 +17574,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_madd_epi16() { + const fn test_mm256_maskz_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_madd_epi16(0, a, b); @@ -17579,7 +17585,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_madd_epi16() { + const fn test_mm_mask_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_madd_epi16(a, 0, a, b); @@ -17590,7 +17596,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_madd_epi16() { + const fn test_mm_maskz_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_madd_epi16(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index f339a003df4d..ecd478511b06 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -210,20 +210,14 @@ pub const fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { - // It's a trick used in the Adler-32 algorithm to perform a widening addition. - // - // ```rust - // #[target_feature(enable = "sse2")] - // unsafe fn widening_add(mad: __m128i) -> __m128i { - // _mm_madd_epi16(mad, _mm_set1_epi16(1)) - // } - // ``` - // - // If we implement this using generic vector intrinsics, the optimizer - // will eliminate this pattern, and `pmaddwd` will no longer be emitted. - // For this reason, we use x86 intrinsics. - unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { + unsafe { + let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8())); + let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]); + let odd: i32x4 = simd_shuffle!(r, r, [1, 3, 5, 7]); + simd_add(even, odd).as_m128i() + } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -3193,8 +3187,6 @@ unsafe extern "C" { fn lfence(); #[link_name = "llvm.x86.sse2.mfence"] fn mfence(); - #[link_name = "llvm.x86.sse2.pmadd.wd"] - fn pmaddwd(a: i16x8, b: i16x8) -> i32x4; #[link_name = "llvm.x86.sse2.psad.bw"] fn psadbw(a: u8x16, b: u8x16) -> u64x2; #[link_name = "llvm.x86.sse2.psll.w"] @@ -3473,7 +3465,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_madd_epi16() { + const fn test_mm_madd_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm_madd_epi16(a, b); From f5540adde9c7a731b1a5bac4b8157975910a54d6 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 1 Feb 2026 01:52:52 +0100 Subject: [PATCH 16/81] add test for multiply by one pattern --- library/stdarch/crates/core_arch/src/x86/avx2.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 8e9a56bb8518..e9463d433180 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -4669,6 +4669,16 @@ mod tests { assert_eq_m256i(r, e); } + #[target_feature(enable = "avx2")] + #[cfg_attr(test, assert_instr(vpmaddwd))] + unsafe fn test_mm256_madd_epi16_mul_one(mad: __m256i) -> __m256i { + // This is a trick used in the adler32 algorithm to get a widening addition. The + // multiplication by 1 is trivial, but must not be optimized out because then the vpmaddwd + // instruction is no longer selected. The assert_instr verifies that this is the case. + let one_v = _mm256_set1_epi16(1); + _mm256_madd_epi16(mad, one_v) + } + #[simd_test(enable = "avx2")] const fn test_mm256_inserti128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); From 7b62d97abdd38850621153e806cc7b0ee6ab4289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 17 Jan 2026 00:19:20 +0000 Subject: [PATCH 17/81] Mention implicit bounds from `#[derive(Clone)]` on moved value When encountering a value that has a borrow checker error where the type was previously moved, when suggesting cloning verify that it is not already being derived. If it is, explain why the `derive(Clone)` doesn't apply: ``` note: if `TypedAddress` implemented `Clone`, you could clone the value --> $DIR/derive-clone-implicit-bound.rs:6:1 | LL | #[derive(Clone, Copy)] | ----- derived `Clone` adds implicit bounds on type parameters LL | pub struct TypedAddress{ | ^^^^^^^^^^^^^^^^^^^^^^^^-^ | | | | | introduces an implicit `T: Clone` bound | consider manually implementing `Clone` for this type ... LL | let old = self.return_value(offset); | ------ you could clone this value ``` --- .../src/diagnostics/conflict_errors.rs | 37 +++++++++++++++++- .../borrowck/derive-clone-implicit-bound.rs | 32 ++++++++++++++++ .../derive-clone-implicit-bound.stderr | 38 +++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 tests/ui/borrowck/derive-clone-implicit-bound.rs create mode 100644 tests/ui/borrowck/derive-clone-implicit-bound.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index caf6a86af098..692ce240e36f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1256,7 +1256,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning_inner(err, ty, expr); } } else if let ty::Adt(def, args) = ty.kind() - && def.did().as_local().is_some() + && let Some(local_did) = def.did().as_local() && def.variants().iter().all(|variant| { variant .fields @@ -1266,7 +1266,40 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { { let ty_span = self.infcx.tcx.def_span(def.did()); let mut span: MultiSpan = ty_span.into(); - span.push_span_label(ty_span, "consider implementing `Clone` for this type"); + let mut derive_clone = false; + self.infcx.tcx.for_each_relevant_impl( + self.infcx.tcx.lang_items().clone_trait().unwrap(), + ty, + |def_id| { + if self.infcx.tcx.is_automatically_derived(def_id) { + derive_clone = true; + span.push_span_label( + self.infcx.tcx.def_span(def_id), + "derived `Clone` adds implicit bounds on type parameters", + ); + if let Some(generics) = self.infcx.tcx.hir_get_generics(local_did) { + for param in generics.params { + if let hir::GenericParamKind::Type { .. } = param.kind { + span.push_span_label( + param.span, + format!( + "introduces an implicit `{}: Clone` bound", + param.name.ident() + ), + ); + } + } + } + } + }, + ); + span.push_span_label( + ty_span, + format!( + "consider {}implementing `Clone` for this type", + if derive_clone { "manually " } else { "" } + ), + ); span.push_span_label(expr.span, "you could clone this value"); err.span_note( span, diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.rs b/tests/ui/borrowck/derive-clone-implicit-bound.rs new file mode 100644 index 000000000000..a20e04d3afdc --- /dev/null +++ b/tests/ui/borrowck/derive-clone-implicit-bound.rs @@ -0,0 +1,32 @@ +// Issue #108894 + +use std::marker::PhantomData; + +#[derive(Clone, Copy)] //~ NOTE derived `Clone` adds implicit bounds on type parameters +pub struct TypedAddress{ +//~^ NOTE if `TypedAddress` implemented `Clone`, you could clone the value +//~| NOTE consider manually implementing `Clone` for this type +//~| NOTE introduces an implicit `T: Clone` bound + inner: u64, + phantom: PhantomData, +} + +pub trait Memory { + fn write_value(&self, offset: TypedAddress, value: &T); + fn return_value(&self, offset: TypedAddress) -> T; + //~^ NOTE consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary + //~| NOTE in this method + //~| NOTE this parameter takes ownership of the value + fn update_value(&self, offset: TypedAddress, update: F) + //~^ NOTE move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait + where F: FnOnce(T) -> T + { + let old = self.return_value(offset); //~ NOTE value moved here + //~^ NOTE you could clone this value + let new = update(old); + self.write_value(offset, &new); //~ ERROR use of moved value: `offset` + //~^ NOTE value used here after move + } +} + +fn main() {} diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.stderr b/tests/ui/borrowck/derive-clone-implicit-bound.stderr new file mode 100644 index 000000000000..b10e3a92c96b --- /dev/null +++ b/tests/ui/borrowck/derive-clone-implicit-bound.stderr @@ -0,0 +1,38 @@ +error[E0382]: use of moved value: `offset` + --> $DIR/derive-clone-implicit-bound.rs:27:26 + | +LL | fn update_value(&self, offset: TypedAddress, update: F) + | ------ move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait +... +LL | let old = self.return_value(offset); + | ------ value moved here +... +LL | self.write_value(offset, &new); + | ^^^^^^ value used here after move + | +note: consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary + --> $DIR/derive-clone-implicit-bound.rs:16:39 + | +LL | fn return_value(&self, offset: TypedAddress) -> T; + | ------------ in this method ^^^^^^^^^^^^^^^ this parameter takes ownership of the value +note: if `TypedAddress` implemented `Clone`, you could clone the value + --> $DIR/derive-clone-implicit-bound.rs:6:1 + | +LL | #[derive(Clone, Copy)] + | ----- derived `Clone` adds implicit bounds on type parameters +LL | pub struct TypedAddress{ + | ^^^^^^^^^^^^^^^^^^^^^^^^-^ + | | | + | | introduces an implicit `T: Clone` bound + | consider manually implementing `Clone` for this type +... +LL | let old = self.return_value(offset); + | ------ you could clone this value +help: consider further restricting type parameter `T` with trait `Copy` + | +LL | where F: FnOnce(T) -> T, T: Copy + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. From 679f38c1259d96463c5f04f175846501fbca2a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 02:29:33 +0000 Subject: [PATCH 18/81] On E0277 pointing at bound in derive, suggest manual impl When encountering a bound coming from a derive macro, suggest manual impl of the trait. Use the span for the specific param when adding bounds in builtin derive macros, so the diagnostic will point at them as well as the derive macro itself. ``` error[E0277]: can't compare `SomeNode` with `SomeNode` --> f29.rs:24:15 | 24 | accept_eq(&node); | --------- ^^^^^ no implementation for `SomeNode == SomeNode` | | | required by a bound introduced by this call | = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs:279:39 = help: the trait `PartialEq` is not implemented for `SomeNode` note: required for `Id` to implement `PartialEq` --> f29.rs:3:10 | 3 | #[derive(PartialEq, Eq)] | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro 4 | pub struct Id(PhantomData); | - = help: consider manually implementing `PartialEq` to avoid undesired bounds note: required by a bound in `accept_eq` --> f29.rs:15:23 | 15 | fn accept_eq(_: &impl PartialEq) { } | ^^^^^^^^^ required by this bound in `accept_eq` help: consider annotating `SomeNode` with `#[derive(PartialEq)]` | 13 + #[derive(PartialEq)] 14 | struct SomeNode(); | ``` --- .../src/deriving/generic/mod.rs | 18 +++++----- compiler/rustc_hir/src/hir.rs | 11 ++++-- compiler/rustc_middle/src/ty/diagnostics.rs | 15 ++++---- .../src/error_reporting/traits/suggestions.rs | 8 +++++ tests/ui/associated-types/issue-38821.stderr | 3 ++ .../unsizing-wfcheck-issue-126272.stderr | 6 +++- .../ui/consts/const-blocks/trait-error.stderr | 5 ++- tests/ui/derives/deriving-copyclone.stderr | 15 ++++++-- .../impl_bounds.stderr | 10 ++++-- .../issue-104884-trait-impl-sugg-err.stderr | 6 +++- ...missing-bound-in-derive-copy-impl-2.stderr | 2 ++ .../missing-bound-in-derive-copy-impl.stderr | 2 ++ tests/ui/traits/derive-implicit-bound.rs | 34 +++++++++++++++++++ tests/ui/traits/derive-implicit-bound.stderr | 31 +++++++++++++++++ 14 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 tests/ui/traits/derive-implicit-bound.rs create mode 100644 tests/ui/traits/derive-implicit-bound.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index c2260a459097..665e0ddab194 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -638,27 +638,27 @@ impl<'a> TraitDef<'a> { GenericParamKind::Type { .. } => { // Extra restrictions on the generics parameters to the // type being derived upon. + let span = param.ident.span.with_ctxt(ctxt); let bounds: Vec<_> = self .additional_bounds .iter() .map(|p| { - cx.trait_bound( - p.to_path(cx, self.span, type_ident, generics), - self.is_const, - ) + cx.trait_bound(p.to_path(cx, span, type_ident, generics), self.is_const) }) .chain( // Add a bound for the current trait. - self.skip_path_as_bound - .not() - .then(|| cx.trait_bound(trait_path.clone(), self.is_const)), + self.skip_path_as_bound.not().then(|| { + let mut trait_path = trait_path.clone(); + trait_path.span = span; + cx.trait_bound(trait_path, self.is_const) + }), ) .chain({ // Add a `Copy` bound if required. if is_packed && self.needs_copy_as_bound_if_packed { let p = deriving::path_std!(marker::Copy); Some(cx.trait_bound( - p.to_path(cx, self.span, type_ident, generics), + p.to_path(cx, span, type_ident, generics), self.is_const, )) } else { @@ -671,7 +671,7 @@ impl<'a> TraitDef<'a> { ) .collect(); - cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) + cx.typaram(span, param.ident, bounds, None) } GenericParamKind::Const { ty, span, .. } => { let const_nodefault_kind = GenericParamKind::Const { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4c1bcffa1cf4..b117fa832729 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,6 +1,7 @@ // ignore-tidy-filelength use std::borrow::Cow; use std::fmt; +use std::ops::Not; use rustc_abi::ExternAbi; use rustc_ast::attr::AttributeExt; @@ -1012,10 +1013,14 @@ impl<'hir> Generics<'hir> { span_for_parentheses.map_or_else( || { - // We include bounds that come from a `#[derive(_)]` but point at the user's code, - // as we use this method to get a span appropriate for suggestions. + // We include bounds that come from a `#[derive(_)]` but point at the user's + // code, as we use this method to get a span appropriate for suggestions. let bs = bound.span(); - bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None)) + // We use `from_expansion` instead of `can_be_used_for_suggestions` because + // the trait bound from imperfect derives do point at the type parameter, + // but expanded to a where clause, so we want to ignore those. This is only + // true for derive intrinsics. + bs.from_expansion().not().then(|| (bs.shrink_to_hi(), None)) }, |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))), ) diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 279c34cb275d..b3b06314e1a0 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -526,12 +526,15 @@ pub fn suggest_constraining_type_params<'a>( // // fn foo(t: T) { ... } // - help: consider restricting this type parameter with `T: Foo` - suggestions.push(( - param.span.shrink_to_hi(), - post, - format!(": {constraint}"), - SuggestChangingConstraintsMessage::RestrictType { ty: param_name }, - )); + let span = param.span.shrink_to_hi(); + if span.can_be_used_for_suggestions() { + suggestions.push(( + span, + post, + format!(": {constraint}"), + SuggestChangingConstraintsMessage::RestrictType { ty: param_name }, + )); + } } // FIXME: remove the suggestions that are from derive, as the span is not correct diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index d54f3812350d..94876c6dd89f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3586,6 +3586,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } spans.push(self_ty.span); let mut spans: MultiSpan = spans.into(); + let mut derived = false; if matches!( self_ty.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _) @@ -3593,6 +3594,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { of_trait.map(|t| t.trait_ref.path.span.ctxt().outer_expn_data().kind), Some(ExpnKind::Macro(MacroKind::Derive, _)) ) { + derived = true; spans.push_span_label( data.span, "unsatisfied trait bound introduced in this `derive` macro", @@ -3621,6 +3623,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } err.span_note(spans, msg); + if derived { + err.help(format!( + "consider manually implementing `{trait_name}` to avoid undesired \ + bounds", + )); + } point_at_assoc_type_restriction( tcx, err, diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index 01329f69c3be..3c5f67fee26a 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -102,6 +102,7 @@ LL | #[derive(Debug, Copy, Clone)] ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Debug` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -146,6 +147,7 @@ LL | #[derive(Debug, Copy, Clone)] ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -219,6 +221,7 @@ LL | #[derive(Debug, Copy, Clone)] ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index aecd97ef7763..ea411741536f 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -65,6 +65,7 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^^^^ LL | struct Bar(T); | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Debug` to avoid undesired bounds = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` @@ -96,7 +97,10 @@ note: required for `Bar` to implement `Eq` --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^ unsatisfied trait bound introduced in this `derive` macro + | ^^ +LL | struct Bar(T); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Eq` to avoid undesired bounds = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` note: required by a bound in `std::cmp::AssertParamIsEq` diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 601d067e3d84..1e66daa7132d 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -8,7 +8,10 @@ note: required for `Foo` to implement `Copy` --> $DIR/trait-error.rs:1:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ +LL | struct Foo(T); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block | diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index befff8802804..f4cd4cff7f44 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -10,7 +10,10 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ +LL | struct B { + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | @@ -33,7 +36,10 @@ note: required for `B` to implement `Clone` --> $DIR/deriving-copyclone.rs:9:16 | LL | #[derive(Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ +LL | struct B { + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Clone` to avoid undesired bounds note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 | @@ -56,7 +62,10 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ +LL | struct B { + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index 7847bbd813cd..d6a794fa0b19 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -32,7 +32,10 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ +LL | struct Fooy(T); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 | @@ -56,7 +59,10 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ +LL | struct Fooy(T); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 | diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index b7aed4a8485a..93fd2df0398e 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -37,7 +37,11 @@ note: required for `PriorityQueue` to implement `PartialOrd` --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^^^^ +... +LL | struct PriorityQueue(BinaryHeap>); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `PartialOrd` to avoid undesired bounds note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index a48dd30d008a..2b8c6baeeafe 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -30,6 +30,7 @@ LL | #[derive(Debug, Copy, Clone)] | ^^^^^ LL | pub struct Vector2 { | ---- unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` | @@ -71,6 +72,7 @@ LL | #[derive(Debug, Copy, Clone)] | ^^^^^ LL | pub struct Vector2 { | ---- unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 645d6ebb3961..2bd56b7688f4 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -65,6 +65,7 @@ LL | #[derive(Debug, Copy, Clone)] | ^^^^^ LL | pub struct Vector2 { | ---- unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` | @@ -134,6 +135,7 @@ LL | #[derive(Debug, Copy, Clone)] | ^^^^^ LL | pub struct Vector2 { | ---- unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/traits/derive-implicit-bound.rs b/tests/ui/traits/derive-implicit-bound.rs new file mode 100644 index 000000000000..22fb68f37c5c --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound.rs @@ -0,0 +1,34 @@ +// Second case reported in issue #108894. + +use std::marker::PhantomData; + +#[derive(PartialEq, Eq)] +pub struct Id(PhantomData); + +// manual implementation which would break the usage of const patterns +// impl PartialEq for Id { fn eq(&self, _: &Id) -> bool { true } } +// impl Eq for Id {} + +// This derive is undesired but cannot be removed without +// breaking the usages below +// #[derive(PartialEq, Eq)] +struct SomeNode(); + +fn accept_eq(_: &impl PartialEq) { } + +fn main() { + let node = Id::(PhantomData); + + // this will only work if + // - `Partial/Eq` is implemented manually, or + // - `SomeNode` also needlessly(?) implements `Partial/Eq` + accept_eq(&node); //~ ERROR can't compare `SomeNode` with `SomeNode` + + const CONST_ID: Id:: = Id::(PhantomData); + // this will work only when `Partial/Eq` is being derived + // otherwise: error: to use a constant of type `Id` in a pattern, + // `Id` must be annotated with `#[derive(PartialEq, Eq)]` + match node { + CONST_ID => {} + } +} diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr new file mode 100644 index 000000000000..9805835bb07f --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -0,0 +1,31 @@ +error[E0277]: can't compare `SomeNode` with `SomeNode` + --> $DIR/derive-implicit-bound.rs:25:15 + | +LL | accept_eq(&node); + | --------- ^^^^^ no implementation for `SomeNode == SomeNode` + | | + | required by a bound introduced by this call + | + = help: the trait `PartialEq` is not implemented for `SomeNode` +note: required for `Id` to implement `PartialEq` + --> $DIR/derive-implicit-bound.rs:5:10 + | +LL | #[derive(PartialEq, Eq)] + | ^^^^^^^^^ +LL | pub struct Id(PhantomData); + | - unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing `PartialEq` to avoid undesired bounds +note: required by a bound in `accept_eq` + --> $DIR/derive-implicit-bound.rs:17:23 + | +LL | fn accept_eq(_: &impl PartialEq) { } + | ^^^^^^^^^ required by this bound in `accept_eq` +help: consider annotating `SomeNode` with `#[derive(PartialEq)]` + | +LL + #[derive(PartialEq)] +LL | struct SomeNode(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 54fe73fd6d3d0b2935977016039ded8d6a0d4772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 05:43:19 +0000 Subject: [PATCH 19/81] Tweak span labels caused by trait bound coming from derive expansion ``` note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct B { | - would need to be `Copy` ``` --- .../src/error_reporting/traits/suggestions.rs | 12 +++++++++++- tests/ui/associated-types/issue-38821.stderr | 12 ++++++------ .../unsizing-wfcheck-issue-126272.stderr | 8 ++++---- tests/ui/consts/const-blocks/trait-error.stderr | 4 ++-- tests/ui/derives/deriving-copyclone.stderr | 12 ++++++------ tests/ui/generic-associated-types/impl_bounds.stderr | 8 ++++---- .../issue-104884-trait-impl-sugg-err.stderr | 4 ++-- .../missing-bound-in-derive-copy-impl-2.stderr | 8 ++++---- .../missing-bound-in-derive-copy-impl.stderr | 8 ++++---- tests/ui/traits/derive-implicit-bound.stderr | 4 ++-- 10 files changed, 45 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 94876c6dd89f..c9dc390ea0be 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3595,9 +3595,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Some(ExpnKind::Macro(MacroKind::Derive, _)) ) { derived = true; + spans.push_span_label( + data.span.ctxt().outer_expn_data().call_site, + format!( + "unsatisfied trait bound introduced in this `derive` macro" + ), + ); spans.push_span_label( data.span, - "unsatisfied trait bound introduced in this `derive` macro", + if data.span.in_derive_expansion() { + format!("would need to be `{trait_name}`") + } else { + format!("") + }, ); } else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) { // `Sized` may be an explicit or implicit trait bound. If it is diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index 3c5f67fee26a..11d0c9d514ff 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -98,10 +98,10 @@ note: required for `ColumnInsertValue` to implement `Debug` --> $DIR/issue-38821.rs:23:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + | ------------------------------------------------ = help: consider manually implementing `Debug` to avoid undesired bounds help: consider further restricting the associated type | @@ -143,10 +143,10 @@ note: required for `ColumnInsertValue` to implement `Copy` --> $DIR/issue-38821.rs:23:17 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + | ------------------------------------------------ = help: consider manually implementing `Copy` to avoid undesired bounds help: consider further restricting the associated type | @@ -217,10 +217,10 @@ note: required for `ColumnInsertValue` to implement `Clone` --> $DIR/issue-38821.rs:23:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro + | ------------------------------------------------ = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting the associated type | diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index ea411741536f..1aaa7591a7be 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -62,9 +62,9 @@ note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` --> $DIR/unsizing-wfcheck-issue-126272.rs:19:10 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct Bar(T); - | - unsatisfied trait bound introduced in this `derive` macro + | - = help: consider manually implementing `Debug` to avoid undesired bounds = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` @@ -97,9 +97,9 @@ note: required for `Bar` to implement `Eq` --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^ + | ^^ unsatisfied trait bound introduced in this `derive` macro LL | struct Bar(T); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Eq` = help: consider manually implementing `Eq` to avoid undesired bounds = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 1e66daa7132d..991a48917efb 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -8,9 +8,9 @@ note: required for `Foo` to implement `Copy` --> $DIR/trait-error.rs:1:10 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct Foo(T); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index f4cd4cff7f44..1baacf85f6a2 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -10,9 +10,9 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct B { - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 @@ -36,9 +36,9 @@ note: required for `B` to implement `Clone` --> $DIR/deriving-copyclone.rs:9:16 | LL | #[derive(Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct B { - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Clone` = help: consider manually implementing `Clone` to avoid undesired bounds note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 @@ -62,9 +62,9 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct B { - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index d6a794fa0b19..fd7dd774cf08 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -32,9 +32,9 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct Fooy(T); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 @@ -59,9 +59,9 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ^^^^ unsatisfied trait bound introduced in this `derive` macro LL | struct Fooy(T); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index 93fd2df0398e..c3513e19981f 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -37,10 +37,10 @@ note: required for `PriorityQueue` to implement `PartialOrd` --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ + | ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro ... LL | struct PriorityQueue(BinaryHeap>); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `PartialOrd` = help: consider manually implementing `PartialOrd` to avoid undesired bounds note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index 2b8c6baeeafe..800f07054af7 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -27,9 +27,9 @@ note: required for `Vector2` to implement `Debug` --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ---- = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` @@ -69,9 +69,9 @@ note: required for `Vector2` to implement `Clone` --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ---- = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 2bd56b7688f4..3f889f31484b 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -62,9 +62,9 @@ note: required for `Vector2` to implement `Debug` --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ---- = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` @@ -132,9 +132,9 @@ note: required for `Vector2` to implement `Clone` --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ---- = help: consider manually implementing `Clone` to avoid undesired bounds help: consider restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr index 9805835bb07f..275cef7a94fd 100644 --- a/tests/ui/traits/derive-implicit-bound.stderr +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -11,9 +11,9 @@ note: required for `Id` to implement `PartialEq` --> $DIR/derive-implicit-bound.rs:5:10 | LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ + | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro LL | pub struct Id(PhantomData); - | - unsatisfied trait bound introduced in this `derive` macro + | - would need to be `PartialEq` = help: consider manually implementing `PartialEq` to avoid undesired bounds note: required by a bound in `accept_eq` --> $DIR/derive-implicit-bound.rs:17:23 From b88fb8a0b0422697a8fe1573598795d7052e936c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 07:22:00 +0000 Subject: [PATCH 20/81] Mention that the trait could be manually impld in E0599 --- compiler/rustc_hir_typeck/src/method/suggest.rs | 5 +++++ tests/ui/derives/derive-assoc-type-not-impl.stderr | 1 + tests/ui/derives/deriving-with-repr-packed-2.stderr | 1 + tests/ui/union/union-derive-clone.stderr | 1 + 4 files changed, 8 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index cd25b866b098..f5ef5adff6bd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1748,6 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find all the requirements that come from a local `impl` block. let mut skip_list: UnordSet<_> = Default::default(); let mut spanned_predicates = FxIndexMap::default(); + let mut manually_impl = false; for (p, parent_p, cause) in unsatisfied_predicates { // Extract the predicate span and parent def id of the cause, // if we have one. @@ -1798,6 +1799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); entry.2.push(p); skip_list.insert(p); + manually_impl = true; } // Unmet obligation coming from an `impl`. @@ -2083,6 +2085,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { *suggested_derive = self.suggest_derive(err, unsatisfied_predicates); *unsatisfied_bounds = true; } + if manually_impl { + err.help("consider manually implementing the trait to avoid undesired bounds"); + } } /// If an appropriate error source is not found, check method chain for possible candidates diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr index 13ba80243a5e..e239ad4ef209 100644 --- a/tests/ui/derives/derive-assoc-type-not-impl.stderr +++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr @@ -15,6 +15,7 @@ note: trait bound `NotClone: Clone` was not satisfied | LL | #[derive(Clone)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NotClone` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/derives/deriving-with-repr-packed-2.stderr b/tests/ui/derives/deriving-with-repr-packed-2.stderr index b62c67d9a9da..fff6269472bd 100644 --- a/tests/ui/derives/deriving-with-repr-packed-2.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-2.stderr @@ -25,6 +25,7 @@ note: the following trait bounds were not satisfied: | LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NonCopy` with `#[derive(Clone, Copy)]` | LL + #[derive(Clone, Copy)] diff --git a/tests/ui/union/union-derive-clone.stderr b/tests/ui/union/union-derive-clone.stderr index 18f862aaa7d6..65488629b629 100644 --- a/tests/ui/union/union-derive-clone.stderr +++ b/tests/ui/union/union-derive-clone.stderr @@ -29,6 +29,7 @@ note: trait bound `CloneNoCopy: Copy` was not satisfied | LL | #[derive(Clone, Copy)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | LL + #[derive(Clone, Copy)] From 085da0cee4e6de6408c401ea2a807eff6b701307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 20:23:18 +0000 Subject: [PATCH 21/81] On E0308 caused by cloning a reference due to missing bounds, account for derive On type errors where the difference is expecting an owned type and getting a reference, if the expression is a `.clone()` call and the type is annotated with `#[derive(Clone)]`, we now explain implicit bounds and suggest manually implementing `Clone`. ``` error[E0308]: mismatched types --> $DIR/derive-implicit-bound-on-clone.rs:10:5 | LL | fn clone_me(x: &ContainsRc) -> ContainsRc { | ---------------- expected `ContainsRc` because of return type LL | x.clone() | ^^^^^^^^^ expected `ContainsRc`, found `&ContainsRc` | = note: expected struct `ContainsRc<_, _>` found reference `&ContainsRc<_, _>` note: `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead --> $DIR/derive-implicit-bound-on-clone.rs:10:5 | LL | x.clone() | ^ help: `Clone` is not implemented because the some trait bounds could not be satisfied --> $DIR/derive-implicit-bound-on-clone.rs:5:19 | LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct ContainsRc { | ^ ^ derive introduces an implicit unsatisfied trait bound `K: Clone` | | | derive introduces an implicit unsatisfied trait bound `T: Clone` = help: consider manually implementing `Clone` to avoid the implict type parameter bounds ``` --- .../src/fn_ctxt/suggestions.rs | 97 ++++++++++++++++--- ...on-ref-due-to-missing-bound.current.stderr | 3 +- ...ll-on-ref-due-to-missing-bound.next.stderr | 3 +- .../traits/derive-implicit-bound-on-clone.rs | 24 +++++ .../derive-implicit-bound-on-clone.stderr | 53 ++++++++++ 5 files changed, 166 insertions(+), 14 deletions(-) create mode 100644 tests/ui/traits/derive-implicit-bound-on-clone.rs create mode 100644 tests/ui/traits/derive-implicit-bound-on-clone.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3e4c194147f9..285288e87ee0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1932,25 +1932,96 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, ); } else { + let mut suggest_derive = true; if let Some(errors) = self.type_implements_trait_shallow(clone_trait_did, expected_ty, self.param_env) { + let manually_impl = "consider manually implementing `Clone` to avoid the \ + implict type parameter bounds"; match &errors[..] { [] => {} [error] => { - diag.help(format!( - "`Clone` is not implemented because the trait bound `{}` is \ - not satisfied", - error.obligation.predicate, - )); + // diag.note("{error:#?}"); + // diag.note(format!("{:#?} {:#?} {:#?}", error.obligation, error.obligation.cause, error.obligation.cause.code())); + let msg = "`Clone` is not implemented because a trait bound is not \ + satisfied"; + if let traits::ObligationCauseCode::ImplDerived(data) = + error.obligation.cause.code() + { + let mut span: MultiSpan = data.span.into(); + if self.tcx.is_automatically_derived(data.impl_or_alias_def_id) { + span.push_span_label( + data.span, + format!( + "derive introduces an implicit `{}` bound", + error.obligation.predicate + ), + ); + } + diag.span_help(span, msg); + if self.tcx.is_automatically_derived(data.impl_or_alias_def_id) + && data.impl_or_alias_def_id.is_local() + { + diag.help(manually_impl); + suggest_derive = false; + } + } else { + diag.help(msg); + } } _ => { - diag.help(format!( - "`Clone` is not implemented because the following trait bounds \ - could not be satisfied: {}", - listify(&errors, |e| format!("`{}`", e.obligation.predicate)) - .unwrap(), - )); + let unsatisfied_bounds: Vec<_> = errors + .iter() + .filter_map(|error| match error.obligation.cause.code() { + traits::ObligationCauseCode::ImplDerived(data) => { + let pre = if self + .tcx + .is_automatically_derived(data.impl_or_alias_def_id) + { + "derive introduces an implicit " + } else { + "" + }; + Some(( + data.span, + format!( + "{pre}unsatisfied trait bound `{}`", + error.obligation.predicate + ), + )) + } + _ => None, + }) + .collect(); + let msg = "`Clone` is not implemented because the some trait bounds \ + could not be satisfied"; + if errors.len() == unsatisfied_bounds.len() { + let mut unsatisfied_bounds_spans: MultiSpan = unsatisfied_bounds + .iter() + .map(|(span, _)| *span) + .collect::>() + .into(); + for (span, label) in unsatisfied_bounds { + unsatisfied_bounds_spans.push_span_label(span, label); + } + diag.span_help(unsatisfied_bounds_spans, msg); + if errors.iter().all(|error| match error.obligation.cause.code() { + traits::ObligationCauseCode::ImplDerived(data) => { + self.tcx.is_automatically_derived(data.impl_or_alias_def_id) + && data.impl_or_alias_def_id.is_local() + } + _ => false, + }) { + diag.help(manually_impl); + suggest_derive = false; + } + } else { + diag.help(format!( + "{msg}: {}", + listify(&errors, |e| format!("`{}`", e.obligation.predicate)) + .unwrap(), + )); + } } } for error in errors { @@ -1968,7 +2039,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]); + if suggest_derive { + self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]); + } } } } diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr index 301f3c3a458d..5de99cc6ca6a 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr @@ -13,7 +13,8 @@ note: `HashSet` does not implement `Clone`, so `&HashSet` was cloned i | LL | let mut x: HashSet = v.clone(); | ^ - = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied +help: `Clone` is not implemented because a trait bound is not satisfied + --> $SRC_DIR/std/src/collections/hash/set.rs:LL:COL help: consider annotating `Day` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr index 301f3c3a458d..5de99cc6ca6a 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr @@ -13,7 +13,8 @@ note: `HashSet` does not implement `Clone`, so `&HashSet` was cloned i | LL | let mut x: HashSet = v.clone(); | ^ - = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied +help: `Clone` is not implemented because a trait bound is not satisfied + --> $SRC_DIR/std/src/collections/hash/set.rs:LL:COL help: consider annotating `Day` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/traits/derive-implicit-bound-on-clone.rs b/tests/ui/traits/derive-implicit-bound-on-clone.rs new file mode 100644 index 000000000000..a4c9e88ef576 --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound-on-clone.rs @@ -0,0 +1,24 @@ +// Issue #146515 +use std::rc::Rc; + +#[derive(Clone)] +struct ContainsRc { //~ HELP `Clone` is not implemented + value: Rc<(T, K)>, +} + +fn clone_me(x: &ContainsRc) -> ContainsRc { + x.clone() //~ ERROR E0308 + //~^ HELP consider manually implementing `Clone` +} + +#[derive(Clone)] +struct ContainsRcSingle { //~ HELP `Clone` is not implemented + value: Rc, +} + +fn clone_me_single(x: &ContainsRcSingle) -> ContainsRcSingle { + x.clone() //~ ERROR E0308 + //~^ HELP consider manually implementing `Clone` +} + +fn main() {} diff --git a/tests/ui/traits/derive-implicit-bound-on-clone.stderr b/tests/ui/traits/derive-implicit-bound-on-clone.stderr new file mode 100644 index 000000000000..0cec4ef7c609 --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound-on-clone.stderr @@ -0,0 +1,53 @@ +error[E0308]: mismatched types + --> $DIR/derive-implicit-bound-on-clone.rs:10:5 + | +LL | fn clone_me(x: &ContainsRc) -> ContainsRc { + | ---------------- expected `ContainsRc` because of return type +LL | x.clone() + | ^^^^^^^^^ expected `ContainsRc`, found `&ContainsRc` + | + = note: expected struct `ContainsRc<_, _>` + found reference `&ContainsRc<_, _>` +note: `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead + --> $DIR/derive-implicit-bound-on-clone.rs:10:5 + | +LL | x.clone() + | ^ +help: `Clone` is not implemented because the some trait bounds could not be satisfied + --> $DIR/derive-implicit-bound-on-clone.rs:5:19 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRc { + | ^ ^ derive introduces an implicit unsatisfied trait bound `K: Clone` + | | + | derive introduces an implicit unsatisfied trait bound `T: Clone` + = help: consider manually implementing `Clone` to avoid the implict type parameter bounds + +error[E0308]: mismatched types + --> $DIR/derive-implicit-bound-on-clone.rs:20:5 + | +LL | fn clone_me_single(x: &ContainsRcSingle) -> ContainsRcSingle { + | ------------------- expected `ContainsRcSingle` because of return type +LL | x.clone() + | ^^^^^^^^^ expected `ContainsRcSingle`, found `&ContainsRcSingle` + | + = note: expected struct `ContainsRcSingle<_>` + found reference `&ContainsRcSingle<_>` +note: `ContainsRcSingle` does not implement `Clone`, so `&ContainsRcSingle` was cloned instead + --> $DIR/derive-implicit-bound-on-clone.rs:20:5 + | +LL | x.clone() + | ^ +help: `Clone` is not implemented because a trait bound is not satisfied + --> $DIR/derive-implicit-bound-on-clone.rs:15:25 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRcSingle { + | ^ derive introduces an implicit `T: Clone` bound + = help: consider manually implementing `Clone` to avoid the implict type parameter bounds + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From aebf1fdcf9c3b1e7b674499ce10aee43960569a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 20:40:29 +0000 Subject: [PATCH 22/81] Keep span of type in builtin derive macros expansions --- .../src/deriving/generic/mod.rs | 3 +- tests/ui/associated-types/issue-38821.rs | 6 +-- tests/ui/associated-types/issue-38821.stderr | 47 +++++++++++++++---- .../const_param_ty_impl_bad_field.rs | 4 +- .../const_param_ty_impl_bad_field.stderr | 7 ++- .../const_param_ty_impl_no_structural_eq.rs | 8 ++-- ...onst_param_ty_impl_no_structural_eq.stderr | 14 ++++-- .../nested_bad_const_param_ty.rs | 6 +-- .../nested_bad_const_param_ty.stderr | 27 +++++------ .../adt_const_params/unsized_field-1.rs | 6 +-- .../adt_const_params/unsized_field-1.stderr | 27 +++++------ .../unsizing-wfcheck-issue-126272.rs | 2 +- .../unsizing-wfcheck-issue-126272.stderr | 22 ++++++--- .../ui/consts/const-blocks/trait-error.stderr | 7 ++- .../derives/copy-drop-mutually-exclusive.rs | 8 ++-- .../copy-drop-mutually-exclusive.stderr | 12 +++-- tests/ui/derives/deriving-copyclone.stderr | 21 ++++++--- tests/ui/derives/issue-97343.stderr | 9 ++-- ...ith-same-name-and-derive-default-133965.rs | 12 ++--- ...same-name-and-derive-default-133965.stderr | 23 ++++----- ...ultiple-types-with-same-name-and-derive.rs | 12 ++--- ...ple-types-with-same-name-and-derive.stderr | 40 ++++++++-------- tests/ui/error-codes/E0184.rs | 4 +- tests/ui/error-codes/E0184.stderr | 6 ++- .../impl_bounds.stderr | 14 ++++-- tests/ui/issues/issue-27340.rs | 4 +- tests/ui/issues/issue-27340.stderr | 10 ++-- tests/ui/malformed/malformed-derive-entry.rs | 10 ++-- .../malformed/malformed-derive-entry.stderr | 14 ++++-- .../issue-104884-trait-impl-sugg-err.rs | 13 +++-- .../issue-104884-trait-impl-sugg-err.stderr | 20 +++++--- tests/ui/range/range_traits-2.rs | 4 +- tests/ui/range/range_traits-2.stderr | 6 +-- tests/ui/range/range_traits-3.rs | 4 +- tests/ui/range/range_traits-3.stderr | 6 +-- tests/ui/range/range_traits-6.rs | 4 +- tests/ui/range/range_traits-6.stderr | 6 +-- tests/ui/span/E0204.rs | 8 ++-- tests/ui/span/E0204.stderr | 10 ++-- .../ui/suggestions/derive-clone-for-eq.fixed | 4 +- tests/ui/suggestions/derive-clone-for-eq.rs | 4 +- .../ui/suggestions/derive-clone-for-eq.stderr | 6 ++- ...missing-bound-in-derive-copy-impl-2.stderr | 14 ++++-- .../missing-bound-in-derive-copy-impl-3.fixed | 4 +- .../missing-bound-in-derive-copy-impl-3.rs | 4 +- ...missing-bound-in-derive-copy-impl-3.stderr | 17 +++---- .../missing-bound-in-derive-copy-impl.rs | 4 +- .../missing-bound-in-derive-copy-impl.stderr | 19 +++++--- tests/ui/traits/derive-implicit-bound.stderr | 7 ++- tests/ui/traits/issue-106072.rs | 8 ++-- tests/ui/traits/issue-106072.stderr | 15 ++++-- tests/ui/traits/issue-50480.rs | 11 ++--- tests/ui/traits/issue-50480.stderr | 35 +++++++------- .../global-cache-and-parallel-frontend.rs | 4 +- .../global-cache-and-parallel-frontend.stderr | 6 ++- 55 files changed, 356 insertions(+), 272 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 665e0ddab194..bc86cdbc9f7e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -791,7 +791,8 @@ impl<'a> TraitDef<'a> { .collect(); // Create the type of `self`. - let path = cx.path_all(self.span, false, vec![type_ident], self_params); + let path = + cx.path_all(type_ident.span.with_ctxt(ctxt), false, vec![type_ident], self_params); let self_type = cx.ty_path(path); let rustc_const_unstable = cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span)); diff --git a/tests/ui/associated-types/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs index 5212bc886f0d..35c371235e64 100644 --- a/tests/ui/associated-types/issue-38821.rs +++ b/tests/ui/associated-types/issue-38821.rs @@ -34,11 +34,11 @@ pub trait Column: Expression {} //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied pub enum ColumnInsertValue where //~^ ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied Col: Column, Expr: Expression::Nullable>, //~^ ERROR the trait bound `::SqlType: IntoNullable` is not satisfied diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index 11d0c9d514ff..58d06860fe30 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:40:1 + --> $DIR/issue-38821.rs:37:1 | LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` @@ -82,10 +82,13 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:23:10 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -98,7 +101,13 @@ note: required for `ColumnInsertValue` to implement `Debug` --> $DIR/issue-38821.rs:23:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ @@ -127,10 +136,13 @@ LL | Expr: Expression::Nullable>, ::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:23:17 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ the trait `NotNull` is not implemented for `::SqlType` + | ---- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -143,7 +155,13 @@ note: required for `ColumnInsertValue` to implement `Copy` --> $DIR/issue-38821.rs:23:17 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ @@ -201,10 +219,13 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:23:23 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -217,7 +238,13 @@ note: required for `ColumnInsertValue` to implement `Clone` --> $DIR/issue-38821.rs:23:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs index 0614ea97b1ad..1900931b3f35 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -8,10 +8,10 @@ struct NotParam; struct CantParam(NotParam); impl std::marker::ConstParamTy_ for CantParam {} -//~^ error: the trait `ConstParamTy_` cannot be implemented for this type +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(std::marker::ConstParamTy, Eq, PartialEq)] -//~^ error: the trait `ConstParamTy_` cannot be implemented for this type struct CantParamDerive(NotParam); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr index fd1836802c4a..084c64d27335 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -8,13 +8,12 @@ LL | impl std::marker::ConstParamTy_ for CantParam {} | ^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/const_param_ty_impl_bad_field.rs:13:10 + --> $DIR/const_param_ty_impl_bad_field.rs:14:8 | LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | + | ------------------------- in this derive macro expansion LL | struct CantParamDerive(NotParam); - | -------- this field does not implement `ConstParamTy_` + | ^^^^^^^^^^^^^^^ -------- this field does not implement `ConstParamTy_` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index a1c8eccfb095..a8f190609c04 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -8,13 +8,13 @@ impl std::marker::ConstParamTy_ for ImplementsConstParamTy {} struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy_ for CantParam {} -//~^ error: the type `CantParam` does not `#[derive(PartialEq)]` -//~| ERROR the trait bound `CantParam: Eq` is not satisfied +//~^ ERROR: the type `CantParam` does not `#[derive(PartialEq)]` +//~| ERROR: the trait bound `CantParam: Eq` is not satisfied #[derive(std::marker::ConstParamTy)] -//~^ error: the type `CantParamDerive` does not `#[derive(PartialEq)]` -//~| ERROR the trait bound `CantParamDerive: Eq` is not satisfied struct CantParamDerive(ImplementsConstParamTy); +//~^ ERROR: the type `CantParamDerive` does not `#[derive(PartialEq)]` +//~| ERROR: the trait bound `CantParamDerive: Eq` is not satisfied fn check() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index ca2a693d48ce..1219d5f04380 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -27,10 +27,12 @@ note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:8 | LL | #[derive(std::marker::ConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` + | ------------------------- in this derive macro expansion +LL | struct CantParamDerive(ImplementsConstParamTy); + | ^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` | note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL @@ -41,13 +43,15 @@ LL | struct CantParamDerive(ImplementsConstParamTy); | error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:8 | LL | #[derive(std::marker::ConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | ------------------------- in this derive macro expansion +LL | struct CantParamDerive(ImplementsConstParamTy); + | ^^^^^^^^^^^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `StructuralPartialEq` is not implemented for `CantParamDerive` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:17:1 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:1 | LL | struct CantParamDerive(ImplementsConstParamTy); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs index d42ef90e1b18..e8a16be2197b 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs @@ -4,15 +4,15 @@ use std::marker::ConstParamTy; #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo([*const u8; 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo2([*mut u8; 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo3([fn(); 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr index 442ec6b96cef..6c8a506d1f40 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr @@ -1,44 +1,41 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:6:10 + --> $DIR/nested_bad_const_param_ty.rs:7:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo([*const u8; 1]); - | -------------- this field does not implement `ConstParamTy_` + | ^^^ -------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:8:12 + --> $DIR/nested_bad_const_param_ty.rs:7:12 | LL | struct Foo([*const u8; 1]); | ^^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:10:10 + --> $DIR/nested_bad_const_param_ty.rs:11:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo2([*mut u8; 1]); - | ------------ this field does not implement `ConstParamTy_` + | ^^^^ ------------ this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:12:13 + --> $DIR/nested_bad_const_param_ty.rs:11:13 | LL | struct Foo2([*mut u8; 1]); | ^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:14:10 + --> $DIR/nested_bad_const_param_ty.rs:15:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo3([fn(); 1]); - | --------- this field does not implement `ConstParamTy_` + | ^^^^ --------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:16:13 + --> $DIR/nested_bad_const_param_ty.rs:15:13 | LL | struct Foo3([fn(); 1]); | ^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs index 5db031cb900f..f2d972612dc6 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs @@ -6,18 +6,18 @@ extern crate unsized_const_param; use std::marker::ConstParamTy; #[derive(ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct A([u8]); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct B(&'static [u8]); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(ConstParamTy, Eq, PartialEq)] struct C(unsized_const_param::Foo); #[derive(std::marker::ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr index 134dbba0d63a..2538b811618b 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr @@ -1,44 +1,41 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:8:10 + --> $DIR/unsized_field-1.rs:9:8 | LL | #[derive(ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct A([u8]); - | ---- this field does not implement `ConstParamTy_` + | ^ ---- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[u8]` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:10:10 + --> $DIR/unsized_field-1.rs:9:10 | LL | struct A([u8]); | ^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:12:10 + --> $DIR/unsized_field-1.rs:13:8 | LL | #[derive(ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct B(&'static [u8]); - | ------------- this field does not implement `ConstParamTy_` + | ^ ------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `&'static [u8]` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:14:10 + --> $DIR/unsized_field-1.rs:13:10 | LL | struct B(&'static [u8]); | ^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:19:10 + --> $DIR/unsized_field-1.rs:20:8 | LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | + | ------------------------- in this derive macro expansion LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - | ---------------------------------------------------------- this field does not implement `ConstParamTy_` + | ^ ---------------------------------------------------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `GenericNotUnsizedParam<&'static [u8]>` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:21:10 + --> $DIR/unsized_field-1.rs:20:10 | LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs index 500e8e22b0e3..71ac662cf580 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs @@ -6,8 +6,8 @@ use std::marker::ConstParamTy; #[derive(Debug, PartialEq, Eq, ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` struct Foo { +//~^ ERROR the trait `ConstParamTy_` nested: &'static Bar, //~^ ERROR the size for values //~| ERROR the size for values diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index 1aaa7591a7be..f90f0b45d967 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -19,11 +19,13 @@ LL | struct Bar(T); | this could be changed to `T: ?Sized`... error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsizing-wfcheck-issue-126272.rs:8:32 + --> $DIR/unsizing-wfcheck-issue-126272.rs:9:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^^^^^^^^ -... + | ------------ in this derive macro expansion +LL | struct Foo { + | ^^^ +LL | LL | nested: &'static Bar, | ----------------------------------------- this field does not implement `ConstParamTy_` | @@ -62,9 +64,12 @@ note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` --> $DIR/unsizing-wfcheck-issue-126272.rs:19:10 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct Bar(T); - | - + | ^^^ - = help: consider manually implementing `Debug` to avoid undesired bounds = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` @@ -97,9 +102,12 @@ note: required for `Bar` to implement `Eq` --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^ unsatisfied trait bound introduced in this `derive` macro + | ^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct Bar(T); - | - would need to be `Eq` + | ^^^ - would need to be `Eq` = help: consider manually implementing `Eq` to avoid undesired bounds = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 991a48917efb..aa9177d2b017 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -8,9 +8,12 @@ note: required for `Foo` to implement `Copy` --> $DIR/trait-error.rs:1:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct Foo(T); - | - would need to be `Copy` + | ^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block diff --git a/tests/ui/derives/copy-drop-mutually-exclusive.rs b/tests/ui/derives/copy-drop-mutually-exclusive.rs index 5147605910d7..64cd5bf594b0 100644 --- a/tests/ui/derives/copy-drop-mutually-exclusive.rs +++ b/tests/ui/derives/copy-drop-mutually-exclusive.rs @@ -1,14 +1,14 @@ //! Regression test for issue #20126: Copy and Drop traits are mutually exclusive -#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented -struct Foo; +#[derive(Copy, Clone)] +struct Foo; //~ ERROR the trait `Copy` cannot be implemented impl Drop for Foo { fn drop(&mut self) {} } -#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented -struct Bar(::std::marker::PhantomData); +#[derive(Copy, Clone)] +struct Bar(::std::marker::PhantomData); //~ ERROR the trait `Copy` cannot be implemented impl Drop for Bar { fn drop(&mut self) {} diff --git a/tests/ui/derives/copy-drop-mutually-exclusive.stderr b/tests/ui/derives/copy-drop-mutually-exclusive.stderr index 771bbc925695..f17d33ffbfed 100644 --- a/tests/ui/derives/copy-drop-mutually-exclusive.stderr +++ b/tests/ui/derives/copy-drop-mutually-exclusive.stderr @@ -1,14 +1,18 @@ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/copy-drop-mutually-exclusive.rs:3:10 + --> $DIR/copy-drop-mutually-exclusive.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Foo; + | ^^^ `Copy` not allowed on types with destructors error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/copy-drop-mutually-exclusive.rs:10:10 + --> $DIR/copy-drop-mutually-exclusive.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Bar(::std::marker::PhantomData); + | ^^^ `Copy` not allowed on types with destructors error: aborting due to 2 previous errors diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index 1baacf85f6a2..226163474482 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -10,9 +10,12 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct B { - | - would need to be `Copy` + | ^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 @@ -36,9 +39,12 @@ note: required for `B` to implement `Clone` --> $DIR/deriving-copyclone.rs:9:16 | LL | #[derive(Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct B { - | - would need to be `Clone` + | ^ - would need to be `Clone` = help: consider manually implementing `Clone` to avoid undesired bounds note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 @@ -62,9 +68,12 @@ note: required for `B` to implement `Copy` --> $DIR/deriving-copyclone.rs:9:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct B { - | - would need to be `Copy` + | ^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 diff --git a/tests/ui/derives/issue-97343.stderr b/tests/ui/derives/issue-97343.stderr index 27691f571884..c033a3d227c1 100644 --- a/tests/ui/derives/issue-97343.stderr +++ b/tests/ui/derives/issue-97343.stderr @@ -2,12 +2,11 @@ error[E0109]: type arguments are not allowed on type parameter `Irrelevant` --> $DIR/issue-97343.rs:4:23 | LL | #[derive(Debug)] - | ----- - | | - | not allowed on type parameter `Irrelevant` - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Irrelevant { - | ^^^^^^^^^^ type argument not allowed + | ---------- ^^^^^^^^^^ type argument not allowed + | | + | not allowed on type parameter `Irrelevant` | note: type parameter `Irrelevant` defined here --> $DIR/issue-97343.rs:4:23 diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs index 8e5cd4248f14..f4193f18352d 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs @@ -3,12 +3,12 @@ struct NonGeneric {} #[derive(Default)] -//~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied -//~^^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied -//~^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied -//~^^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied +//~^ ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR: struct takes 0 generic arguments but 1 generic argument was supplied struct NonGeneric<'a, const N: usize> {} -//~^ ERROR lifetime parameter `'a` is never used -//~^^ ERROR the name `NonGeneric` is defined multiple times +//~^ ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR: struct takes 0 generic arguments but 1 generic argument was supplied +//~| ERROR: lifetime parameter `'a` is never used +//~| ERROR: the name `NonGeneric` is defined multiple times pub fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr index cf9c0d0ad3be..0d6aaaf5186d 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `NonGeneric` is defined multiple times - --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:1 + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:1 | LL | struct NonGeneric {} | ----------------- previous definition of the type `NonGeneric` here @@ -37,7 +37,7 @@ LL | struct NonGeneric {} | ^^^^^^^^^^ error[E0392]: lifetime parameter `'a` is never used - --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:19 + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:19 | LL | struct NonGeneric<'a, const N: usize> {} | ^^ unused lifetime parameter @@ -45,29 +45,26 @@ LL | struct NonGeneric<'a, const N: usize> {} = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:8 | -LL | #[derive(Default)] - | ^^^^^^^ expected 0 lifetime arguments -... LL | struct NonGeneric<'a, const N: usize> {} - | -- help: remove the lifetime argument + | ^^^^^^^^^^ -- help: remove the lifetime argument + | | + | expected 0 lifetime arguments | note: struct defined here, with 0 lifetime parameters --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 | LL | struct NonGeneric {} | ^^^^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:8 | -LL | #[derive(Default)] - | ^^^^^^^ expected 0 generic arguments -... LL | struct NonGeneric<'a, const N: usize> {} - | - help: remove the unnecessary generic argument + | ^^^^^^^^^^ - help: remove the unnecessary generic argument + | | + | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs index f3bf299aa65f..e946c0c5350e 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs @@ -8,12 +8,12 @@ struct NotSM; #[derive(PartialEq, Eq)] -//~^ ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments +//~^ ERROR: struct takes 0 generic arguments struct NotSM(T); -//~^ ERROR the name `NotSM` is defined multiple times -//~| ERROR no field `0` +//~^ ERROR: struct takes 0 generic arguments +//~| ERROR: struct takes 0 generic arguments +//~| ERROR: struct takes 0 generic arguments +//~| ERROR: the name `NotSM` is defined multiple times +//~| ERROR: no field `0` fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr index 32c3cf440316..e80cf35d81e1 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `NotSM` is defined multiple times - --> $DIR/multiple-types-with-same-name-and-derive.rs:15:1 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:1 | LL | struct NotSM; | ------------- previous definition of the type `NotSM` here @@ -10,10 +10,10 @@ LL | struct NotSM(T); = note: `NotSM` must be defined only once in the type namespace of this module error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ expected 0 generic arguments +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 @@ -30,27 +30,27 @@ LL | #[derive(PartialEq, Eq)] note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 | +LL | struct NotSM; + | ^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 + | +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 + | LL | struct NotSM; | ^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:21 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 | -LL | #[derive(PartialEq, Eq)] - | ^^ expected 0 generic arguments - | -note: struct defined here, with 0 generic parameters - --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 - | -LL | struct NotSM; - | ^^^^^ - -error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10 - | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ expected 0 generic arguments +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 @@ -60,7 +60,7 @@ LL | struct NotSM; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0609]: no field `0` on type `&NotSM` - --> $DIR/multiple-types-with-same-name-and-derive.rs:15:17 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:17 | LL | struct NotSM(T); | ^ unknown field diff --git a/tests/ui/error-codes/E0184.rs b/tests/ui/error-codes/E0184.rs index 0c448e4ad8bc..64cc1f0d1538 100644 --- a/tests/ui/error-codes/E0184.rs +++ b/tests/ui/error-codes/E0184.rs @@ -1,5 +1,5 @@ -#[derive(Copy)] //~ ERROR E0184 -struct Foo; +#[derive(Copy)] +struct Foo; //~ ERROR E0184 impl Drop for Foo { fn drop(&mut self) { diff --git a/tests/ui/error-codes/E0184.stderr b/tests/ui/error-codes/E0184.stderr index 1a7df9ac095a..98b5305ad0dc 100644 --- a/tests/ui/error-codes/E0184.stderr +++ b/tests/ui/error-codes/E0184.stderr @@ -1,8 +1,10 @@ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/E0184.rs:1:10 + --> $DIR/E0184.rs:2:8 | LL | #[derive(Copy)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Foo; + | ^^^ `Copy` not allowed on types with destructors error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index fd7dd774cf08..d918bd62c2d7 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -32,9 +32,12 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct Fooy(T); - | - would need to be `Copy` + | ^^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 @@ -59,9 +62,12 @@ note: required for `Fooy` to implement `Copy` --> $DIR/impl_bounds.rs:10:10 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | struct Fooy(T); - | - would need to be `Copy` + | ^^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/issues/issue-27340.rs index 53ca2bc973ff..9966c24a7441 100644 --- a/tests/ui/issues/issue-27340.rs +++ b/tests/ui/issues/issue-27340.rs @@ -1,7 +1,7 @@ struct Foo; #[derive(Copy, Clone)] -//~^ ERROR the trait `Copy` cannot be implemented for this type struct Bar(Foo); -//~^ ERROR `Foo: Clone` is not satisfied +//~^ ERROR: the trait `Copy` cannot be implemented for this type +//~| ERROR: `Foo: Clone` is not satisfied fn main() {} diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr index 7cde901ffd95..3b4ad58b1f08 100644 --- a/tests/ui/issues/issue-27340.stderr +++ b/tests/ui/issues/issue-27340.stderr @@ -1,18 +1,16 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-27340.rs:2:10 + --> $DIR/issue-27340.rs:3:8 | LL | #[derive(Copy, Clone)] - | ^^^^ -LL | + | ---- in this derive macro expansion LL | struct Bar(Foo); - | --- this field does not implement `Copy` + | ^^^ --- this field does not implement `Copy` error[E0277]: the trait bound `Foo: Clone` is not satisfied - --> $DIR/issue-27340.rs:4:12 + --> $DIR/issue-27340.rs:3:12 | LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion -LL | LL | struct Bar(Foo); | ^^^ the trait `Clone` is not implemented for `Foo` | diff --git a/tests/ui/malformed/malformed-derive-entry.rs b/tests/ui/malformed/malformed-derive-entry.rs index 77fa2f566a8f..f9dc98d9d270 100644 --- a/tests/ui/malformed/malformed-derive-entry.rs +++ b/tests/ui/malformed/malformed-derive-entry.rs @@ -1,14 +1,14 @@ #[derive(Copy(Bad))] -//~^ ERROR traits in `#[derive(...)]` don't accept arguments -//~| ERROR the trait bound +//~^ ERROR: traits in `#[derive(...)]` don't accept arguments struct Test1; +//~^ ERROR: the trait bound #[derive(Copy="bad")] -//~^ ERROR traits in `#[derive(...)]` don't accept values -//~| ERROR the trait bound +//~^ ERROR: traits in `#[derive(...)]` don't accept values struct Test2; +//~^ ERROR: the trait bound -#[derive] //~ ERROR malformed `derive` attribute input +#[derive] //~ ERROR: malformed `derive` attribute input struct Test4; fn main() {} diff --git a/tests/ui/malformed/malformed-derive-entry.stderr b/tests/ui/malformed/malformed-derive-entry.stderr index 02036e8d4c90..a5d7c3a4f8aa 100644 --- a/tests/ui/malformed/malformed-derive-entry.stderr +++ b/tests/ui/malformed/malformed-derive-entry.stderr @@ -17,10 +17,13 @@ LL | #[derive] | ^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]` error[E0277]: the trait bound `Test1: Clone` is not satisfied - --> $DIR/malformed-derive-entry.rs:1:10 + --> $DIR/malformed-derive-entry.rs:3:8 | LL | #[derive(Copy(Bad))] - | ^^^^ the trait `Clone` is not implemented for `Test1` + | ---- in this derive macro expansion +LL | +LL | struct Test1; + | ^^^^^ the trait `Clone` is not implemented for `Test1` | note: required by a bound in `Copy` --> $SRC_DIR/core/src/marker.rs:LL:COL @@ -31,10 +34,13 @@ LL | struct Test1; | error[E0277]: the trait bound `Test2: Clone` is not satisfied - --> $DIR/malformed-derive-entry.rs:6:10 + --> $DIR/malformed-derive-entry.rs:8:8 | LL | #[derive(Copy="bad")] - | ^^^^ the trait `Clone` is not implemented for `Test2` + | ---- in this derive macro expansion +LL | +LL | struct Test2; + | ^^^^^ the trait `Clone` is not implemented for `Test2` | note: required by a bound in `Copy` --> $SRC_DIR/core/src/marker.rs:LL:COL diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index d420f2641daf..0c66b47b3941 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -12,12 +12,11 @@ struct PriorityQueueEntry { } #[derive(PartialOrd, AddImpl)] -//~^ ERROR can't compare `PriorityQueue` with `PriorityQueue` -//~| ERROR the trait bound `PriorityQueue: Eq` is not satisfied -//~| ERROR can't compare `T` with `T` -//~| ERROR no method named `cmp` found for struct `BinaryHeap>` -//~| ERROR no field `height` on type `&PriorityQueue` - +//~^ ERROR: the trait bound `PriorityQueue: Eq` is not satisfied +//~| ERROR: can't compare `T` with `T` +//~| ERROR: no method named `cmp` found for struct `BinaryHeap>` +//~| ERROR: no field `height` on type `&PriorityQueue` struct PriorityQueue(BinaryHeap>); -//~^ ERROR can't compare `BinaryHeap>` with `_` +//~^ ERROR: can't compare `PriorityQueue` with `PriorityQueue` +//~| ERROR: can't compare `BinaryHeap>` with `_` fn main() {} diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index c3513e19981f..e49cf6256cb2 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -1,11 +1,14 @@ error[E0277]: can't compare `PriorityQueue` with `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:8 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ no implementation for `PriorityQueue == PriorityQueue` + | ---------- in this derive macro expansion +... +LL | struct PriorityQueue(BinaryHeap>); + | ^^^^^^^^^^^^^ no implementation for `PriorityQueue == PriorityQueue` | help: the trait `PartialEq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +22,7 @@ LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ unsatisfied trait bound | help: the trait `Eq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,16 +40,19 @@ note: required for `PriorityQueue` to implement `PartialOrd` --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion ... LL | struct PriorityQueue(BinaryHeap>); - | - would need to be `PartialOrd` + | ^^^^^^^^^^^^^ - would need to be `PartialOrd` = help: consider manually implementing `PartialOrd` to avoid undesired bounds note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: can't compare `BinaryHeap>` with `_` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:25 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:25 | LL | #[derive(PartialOrd, AddImpl)] | ---------- in this derive macro expansion diff --git a/tests/ui/range/range_traits-2.rs b/tests/ui/range/range_traits-2.rs index 234d7a64dc8b..7dd91243082c 100644 --- a/tests/ui/range/range_traits-2.rs +++ b/tests/ui/range/range_traits-2.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(Range); +#[derive(Copy, Clone)] +struct R(Range); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-2.stderr b/tests/ui/range/range_traits-2.stderr index 2001c85c4348..f38539cc648c 100644 --- a/tests/ui/range/range_traits-2.stderr +++ b/tests/ui/range/range_traits-2.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-2.rs:3:10 + --> $DIR/range_traits-2.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(Range); - | ------------ this field does not implement `Copy` + | ^ ------------ this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/range/range_traits-3.rs b/tests/ui/range/range_traits-3.rs index 2d597cce5ad5..79ba1842f62f 100644 --- a/tests/ui/range/range_traits-3.rs +++ b/tests/ui/range/range_traits-3.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(RangeFrom); +#[derive(Copy, Clone)] +struct R(RangeFrom); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-3.stderr b/tests/ui/range/range_traits-3.stderr index 71210379c79c..1f3768ad8d84 100644 --- a/tests/ui/range/range_traits-3.stderr +++ b/tests/ui/range/range_traits-3.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-3.rs:3:10 + --> $DIR/range_traits-3.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(RangeFrom); - | ---------------- this field does not implement `Copy` + | ^ ---------------- this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/range/range_traits-6.rs b/tests/ui/range/range_traits-6.rs index bce106bbfe79..72c6cecc88d6 100644 --- a/tests/ui/range/range_traits-6.rs +++ b/tests/ui/range/range_traits-6.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(RangeInclusive); +#[derive(Copy, Clone)] +struct R(RangeInclusive); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-6.stderr b/tests/ui/range/range_traits-6.stderr index a58022ef7e4f..53fe2fed0a61 100644 --- a/tests/ui/range/range_traits-6.stderr +++ b/tests/ui/range/range_traits-6.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-6.rs:3:10 + --> $DIR/range_traits-6.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(RangeInclusive); - | --------------------- this field does not implement `Copy` + | ^ --------------------- this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/span/E0204.rs b/tests/ui/span/E0204.rs index 8793a05c8a85..841bd5e32b8a 100644 --- a/tests/ui/span/E0204.rs +++ b/tests/ui/span/E0204.rs @@ -4,8 +4,8 @@ struct Foo { impl Copy for Foo { } //~ ERROR cannot be implemented for this type -#[derive(Copy)] //~ ERROR cannot be implemented for this type -struct Foo2<'a> { +#[derive(Copy)] +struct Foo2<'a> { //~ ERROR cannot be implemented for this type ty: &'a mut bool, } @@ -16,8 +16,8 @@ enum EFoo { impl Copy for EFoo { } //~ ERROR cannot be implemented for this type -#[derive(Copy)] //~ ERROR cannot be implemented for this type -enum EFoo2<'a> { +#[derive(Copy)] +enum EFoo2<'a> { //~ ERROR cannot be implemented for this type Bar(&'a mut bool), Baz, } diff --git a/tests/ui/span/E0204.stderr b/tests/ui/span/E0204.stderr index fe375b94781b..a0b51be17863 100644 --- a/tests/ui/span/E0204.stderr +++ b/tests/ui/span/E0204.stderr @@ -8,11 +8,12 @@ LL | impl Copy for Foo { } | ^^^ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/E0204.rs:7:10 + --> $DIR/E0204.rs:8:8 | LL | #[derive(Copy)] - | ^^^^ + | ---- in this derive macro expansion LL | struct Foo2<'a> { + | ^^^^ LL | ty: &'a mut bool, | ---------------- this field does not implement `Copy` @@ -26,11 +27,12 @@ LL | impl Copy for EFoo { } | ^^^^ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/E0204.rs:19:10 + --> $DIR/E0204.rs:20:6 | LL | #[derive(Copy)] - | ^^^^ + | ---- in this derive macro expansion LL | enum EFoo2<'a> { + | ^^^^^ LL | Bar(&'a mut bool), | ------------ this field does not implement `Copy` diff --git a/tests/ui/suggestions/derive-clone-for-eq.fixed b/tests/ui/suggestions/derive-clone-for-eq.fixed index 4dc362f94787..17259dd687c6 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.fixed +++ b/tests/ui/suggestions/derive-clone-for-eq.fixed @@ -1,8 +1,8 @@ //@ run-rustfix // https://github.com/rust-lang/rust/issues/79076 -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/suggestions/derive-clone-for-eq.rs b/tests/ui/suggestions/derive-clone-for-eq.rs index b3635000f165..3e4331745be8 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.rs +++ b/tests/ui/suggestions/derive-clone-for-eq.rs @@ -1,8 +1,8 @@ //@ run-rustfix // https://github.com/rust-lang/rust/issues/79076 -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/suggestions/derive-clone-for-eq.stderr b/tests/ui/suggestions/derive-clone-for-eq.stderr index eb0355853daa..bed5ff90c194 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.stderr +++ b/tests/ui/suggestions/derive-clone-for-eq.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/derive-clone-for-eq.rs:4:17 + --> $DIR/derive-clone-for-eq.rs:5:12 | LL | #[derive(Clone, Eq)] - | ^^ the trait `Clone` is not implemented for `T` + | -- in this derive macro expansion +LL | pub struct Struct(T); + | ^^^^^^ the trait `Clone` is not implemented for `T` | note: required for `Struct` to implement `PartialEq` --> $DIR/derive-clone-for-eq.rs:7:19 diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index 800f07054af7..872ce7105ce8 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -27,9 +27,12 @@ note: required for `Vector2` to implement `Debug` --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | pub struct Vector2 { - | ---- + | ^^^^^^^ ---- = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` @@ -69,9 +72,12 @@ note: required for `Vector2` to implement `Clone` --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | pub struct Vector2 { - | ---- + | ^^^^^^^ ---- = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed index 74df1d7c7cfd..bd1785e35112 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed @@ -7,8 +7,8 @@ pub struct Vector2{ pub y: T } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB{ +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~ ERROR `K` doesn't implement `Debug` //~^ ERROR `K` doesn't implement `Debug` pub size: Vector2 //~ ERROR `K` doesn't implement `Debug` diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs index 8550a4d72476..36502044bd46 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs @@ -7,8 +7,8 @@ pub struct Vector2{ pub y: T } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB{ +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~ ERROR `K` doesn't implement `Debug` //~^ ERROR `K` doesn't implement `Debug` pub size: Vector2 //~ ERROR `K` doesn't implement `Debug` diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr index e3375b67c86d..cc80e7297e48 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr @@ -1,9 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/missing-bound-in-derive-copy-impl-3.rs:10:17 + --> $DIR/missing-bound-in-derive-copy-impl-3.rs:11:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ -LL | pub struct AABB{ + | ---- in this derive macro expansion +LL | pub struct AABB { + | ^^^^ LL | pub loc: Vector2, | ------------------- this field does not implement `Copy` | @@ -14,7 +15,7 @@ LL | pub loc: Vector2, | ^^^^^^^^^^ help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++ error[E0277]: `K` doesn't implement `Debug` @@ -30,7 +31,7 @@ LL | pub struct Vector2{ | ^^^^^ required by this bound in `Vector2` help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error[E0277]: `K` doesn't implement `Debug` @@ -38,13 +39,13 @@ error[E0277]: `K` doesn't implement `Debug` | LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion -LL | pub struct AABB{ +LL | pub struct AABB { LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K` | help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error[E0277]: `K` doesn't implement `Debug` @@ -58,7 +59,7 @@ LL | pub size: Vector2 | help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs index 0ffc1b8f7a25..60a9074e5c0d 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs @@ -6,8 +6,8 @@ pub struct Vector2 { pub y: T, } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB { +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~^ ERROR doesn't implement `Debug` //~| ERROR `K: Copy` is not satisfied diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 3f889f31484b..f843fb0d6d7e 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -1,9 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/missing-bound-in-derive-copy-impl.rs:9:17 + --> $DIR/missing-bound-in-derive-copy-impl.rs:10:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | pub struct AABB { + | ^^^^ LL | pub loc: Vector2, | ------------------- this field does not implement `Copy` | @@ -62,9 +63,12 @@ note: required for `Vector2` to implement `Debug` --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | pub struct Vector2 { - | ---- + | ^^^^^^^ ---- = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` @@ -132,9 +136,12 @@ note: required for `Vector2` to implement `Clone` --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | pub struct Vector2 { - | ---- + | ^^^^^^^ ---- = help: consider manually implementing `Clone` to avoid undesired bounds help: consider restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr index 275cef7a94fd..02c7fe9e689e 100644 --- a/tests/ui/traits/derive-implicit-bound.stderr +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -11,9 +11,12 @@ note: required for `Id` to implement `PartialEq` --> $DIR/derive-implicit-bound.rs:5:10 | LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^^^ + | | + | unsatisfied trait bound introduced in this `derive` macro + | in this derive macro expansion LL | pub struct Id(PhantomData); - | - would need to be `PartialEq` + | ^^ - would need to be `PartialEq` = help: consider manually implementing `PartialEq` to avoid undesired bounds note: required by a bound in `accept_eq` --> $DIR/derive-implicit-bound.rs:17:23 diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index d45668312218..6b04004621d8 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,6 +1,4 @@ -#[derive(Clone)] -//~^ ERROR expected a type, found a trait -//~| ERROR expected a type, found a trait -struct Foo; -trait Foo {} //~ ERROR the name `Foo` is defined multiple times +#[derive(Clone)] //~ ERROR: expected a type, found a trait +struct Foo; //~ ERROR: expected a type, found a trait +trait Foo {} //~ ERROR: the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index 815787c3bfec..ebb22cb9cd74 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:5:1 + --> $DIR/issue-106072.rs:3:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -9,18 +9,23 @@ LL | trait Foo {} = note: `Foo` must be defined only once in the type namespace of this module error[E0782]: expected a type, found a trait - --> $DIR/issue-106072.rs:1:10 + --> $DIR/issue-106072.rs:2:8 | LL | #[derive(Clone)] - | ^^^^^ + | ----- in this derive macro expansion +LL | struct Foo; + | ^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | struct dyn Foo; + | +++ error[E0782]: expected a type, found a trait --> $DIR/issue-106072.rs:1:10 | LL | #[derive(Clone)] | ^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs index ccd35a850f2d..2f62906e9df3 100644 --- a/tests/ui/traits/issue-50480.rs +++ b/tests/ui/traits/issue-50480.rs @@ -1,18 +1,17 @@ #[derive(Clone, Copy)] -//~^ ERROR the trait `Copy` cannot be implemented for this type struct Foo(N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope +//~^ ERROR the trait `Copy` cannot be implemented for this type +//~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator -#[derive(Clone, Copy)] -//~^ ERROR the trait `Copy` cannot be implemented for this type -//~| ERROR `i32` is not an iterator +#[derive(Clone, Copy)] //~ ERROR `i32` is not an iterator struct Bar(T, N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope +//~^ ERROR the trait `Copy` cannot be implemented for this type +//~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 32c8b2cf3ac1..1fb5e8b00783 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:3:12 + --> $DIR/issue-50480.rs:2:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope @@ -10,13 +10,13 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:3:15 + --> $DIR/issue-50480.rs:2:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:3:12 + --> $DIR/issue-50480.rs:2:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope @@ -27,7 +27,7 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:3:15 + --> $DIR/issue-50480.rs:2:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope @@ -38,7 +38,7 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, St | ++++++++++++ error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:14:18 + --> $DIR/issue-50480.rs:12:18 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | - ^ @@ -56,13 +56,13 @@ LL | struct Bar(T, N, NotDefined, ::Item, Vec, Strin | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:14:21 + --> $DIR/issue-50480.rs:12:21 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:3:27 + --> $DIR/issue-50480.rs:2:27 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator @@ -70,29 +70,27 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); = help: the trait `Iterator` is not implemented for `i32` error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-50480.rs:1:17 + --> $DIR/issue-50480.rs:2:8 | LL | #[derive(Clone, Copy)] - | ^^^^ -LL | + | ---- in this derive macro expansion LL | struct Foo(N, NotDefined, ::Item, Vec, String); - | -------- ------ this field does not implement `Copy` + | ^^^ -------- ------ this field does not implement `Copy` | | | this field does not implement `Copy` error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-50480.rs:11:17 + --> $DIR/issue-50480.rs:12:8 | LL | #[derive(Clone, Copy)] - | ^^^^ -... + | ---- in this derive macro expansion LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); - | -------- ------ this field does not implement `Copy` + | ^^^ -------- ------ this field does not implement `Copy` | | | this field does not implement `Copy` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:14:33 + --> $DIR/issue-50480.rs:12:33 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator @@ -100,7 +98,7 @@ LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); = help: the trait `Iterator` is not implemented for `i32` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:3:28 + --> $DIR/issue-50480.rs:2:28 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^ `i32` is not an iterator @@ -116,11 +114,10 @@ LL | #[derive(Clone, Copy)] = help: the trait `Iterator` is not implemented for `i32` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:14:33 + --> $DIR/issue-50480.rs:12:33 | LL | #[derive(Clone, Copy)] | ----- in this derive macro expansion -... LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs index 2b4f7ba9fa29..ceef87d76abb 100644 --- a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs +++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs @@ -12,8 +12,8 @@ // we already face this difficulty, probably. If we need to fix this by reducing the error margin, // we should improve compiletest. -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr index 290b1df1665d..912286a48faf 100644 --- a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr +++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/global-cache-and-parallel-frontend.rs:15:17 + --> $DIR/global-cache-and-parallel-frontend.rs:16:12 | LL | #[derive(Clone, Eq)] - | ^^ the trait `Clone` is not implemented for `T` + | -- in this derive macro expansion +LL | pub struct Struct(T); + | ^^^^^^ the trait `Clone` is not implemented for `T` | note: required for `Struct` to implement `PartialEq` --> $DIR/global-cache-and-parallel-frontend.rs:18:19 From b9e5cf7806b824c1080b66755701840f9d88f80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 20:57:27 +0000 Subject: [PATCH 23/81] Fix incorrect suggestion caused by change in derive expansion Span --- .../rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs | 6 +++++- tests/ui/traits/issue-106072.stderr | 5 ----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index 29f29761b605..57defac577d8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -592,7 +592,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if span.can_be_used_for_suggestions() && poly_trait_ref.trait_ref.trait_def_id().is_some() && !self.maybe_suggest_impl_trait(span, hir_id, hir_bounds, &mut diag) - && !self.maybe_suggest_dyn_trait(hir_id, sugg, &mut diag) + && !self.maybe_suggest_dyn_trait(hir_id, span, sugg, &mut diag) { self.maybe_suggest_add_generic_impl_trait(span, hir_id, &mut diag); } @@ -750,10 +750,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn maybe_suggest_dyn_trait( &self, hir_id: hir::HirId, + span: Span, sugg: Vec<(Span, String)>, diag: &mut Diag<'_>, ) -> bool { let tcx = self.tcx(); + if span.in_derive_expansion() { + return false; + } // Look at the direct HIR parent, since we care about the relationship between // the type and the thing that directly encloses it. diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index ebb22cb9cd74..57661fda7307 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -15,11 +15,6 @@ LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct Foo; | ^^^ - | -help: you can add the `dyn` keyword if you want a trait object - | -LL | struct dyn Foo; - | +++ error[E0782]: expected a type, found a trait --> $DIR/issue-106072.rs:1:10 From dd8148373fa376541b40e24129251153e0bf5271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 21:16:39 +0000 Subject: [PATCH 24/81] Tweak span labels --- .../src/error_reporting/traits/suggestions.rs | 12 +++------ tests/ui/associated-types/issue-38821.stderr | 27 +++++++------------ .../unsizing-wfcheck-issue-126272.stderr | 16 ++++------- .../ui/consts/const-blocks/trait-error.stderr | 7 ++--- tests/ui/derives/deriving-copyclone.stderr | 21 +++++---------- .../impl_bounds.stderr | 14 +++------- .../issue-104884-trait-impl-sugg-err.stderr | 7 ++--- ...missing-bound-in-derive-copy-impl-2.stderr | 18 +++++-------- .../missing-bound-in-derive-copy-impl.stderr | 18 +++++-------- tests/ui/traits/derive-implicit-bound.stderr | 7 ++--- 10 files changed, 46 insertions(+), 101 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index c9dc390ea0be..70a16b23d276 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3581,7 +3581,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. })) => { let mut spans = Vec::with_capacity(2); - if let Some(of_trait) = of_trait { + if let Some(of_trait) = of_trait + && !of_trait.trait_ref.path.span.in_derive_expansion() + { spans.push(of_trait.trait_ref.path.span); } spans.push(self_ty.span); @@ -3595,18 +3597,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Some(ExpnKind::Macro(MacroKind::Derive, _)) ) { derived = true; - spans.push_span_label( - data.span.ctxt().outer_expn_data().call_site, - format!( - "unsatisfied trait bound introduced in this `derive` macro" - ), - ); spans.push_span_label( data.span, if data.span.in_derive_expansion() { format!("would need to be `{trait_name}`") } else { - format!("") + format!("unsatisfied trait bound") }, ); } else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) { diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index 58d06860fe30..fae388c98d36 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -98,19 +98,16 @@ LL | impl IntoNullable for T { | | | unsatisfied trait bound introduced here note: required for `ColumnInsertValue` to implement `Debug` - --> $DIR/issue-38821.rs:23:10 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion ... LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ + | ------------------------------------------------ unsatisfied trait bound = help: consider manually implementing `Debug` to avoid undesired bounds help: consider further restricting the associated type | @@ -152,19 +149,16 @@ LL | impl IntoNullable for T { | | | unsatisfied trait bound introduced here note: required for `ColumnInsertValue` to implement `Copy` - --> $DIR/issue-38821.rs:23:17 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion ... LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ + | ------------------------------------------------ unsatisfied trait bound = help: consider manually implementing `Copy` to avoid undesired bounds help: consider further restricting the associated type | @@ -235,19 +229,16 @@ LL | impl IntoNullable for T { | | | unsatisfied trait bound introduced here note: required for `ColumnInsertValue` to implement `Clone` - --> $DIR/issue-38821.rs:23:23 + --> $DIR/issue-38821.rs:37:10 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion ... LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^ ... LL | Expr: Expression::Nullable>, - | ------------------------------------------------ + | ------------------------------------------------ unsatisfied trait bound = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting the associated type | diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index f90f0b45d967..fc681e655e1a 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -61,15 +61,12 @@ help: the trait `Debug` is implemented for `Bar` LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^^^^ note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` - --> $DIR/unsizing-wfcheck-issue-126272.rs:19:10 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | struct Bar(T); - | ^^^ - + | ^^^ - unsatisfied trait bound = help: consider manually implementing `Debug` to avoid undesired bounds = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` @@ -99,13 +96,10 @@ help: the trait `Eq` is implemented for `Bar` LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^ note: required for `Bar` to implement `Eq` - --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | -- in this derive macro expansion LL | struct Bar(T); | ^^^ - would need to be `Eq` = help: consider manually implementing `Eq` to avoid undesired bounds diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index aa9177d2b017..60402a412362 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -5,13 +5,10 @@ LL | [Foo(String::new()); 4]; | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | note: required for `Foo` to implement `Copy` - --> $DIR/trait-error.rs:1:10 + --> $DIR/trait-error.rs:2:8 | LL | #[derive(Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion LL | struct Foo(T); | ^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index 226163474482..f8d2859f211e 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -7,13 +7,10 @@ LL | is_copy(B { a: 1, b: C }); | required by a bound introduced by this call | note: required for `B` to implement `Copy` - --> $DIR/deriving-copyclone.rs:9:10 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion LL | struct B { | ^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds @@ -36,13 +33,10 @@ LL | is_clone(B { a: 1, b: C }); | required by a bound introduced by this call | note: required for `B` to implement `Clone` - --> $DIR/deriving-copyclone.rs:9:16 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | struct B { | ^ - would need to be `Clone` = help: consider manually implementing `Clone` to avoid undesired bounds @@ -65,13 +59,10 @@ LL | is_copy(B { a: 1, b: D }); | required by a bound introduced by this call | note: required for `B` to implement `Copy` - --> $DIR/deriving-copyclone.rs:9:10 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion LL | struct B { | ^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index d918bd62c2d7..f65675686532 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -29,13 +29,10 @@ LL | type C = String where Self: Copy; | ^^^^ the trait `Copy` is not implemented for `T` | note: required for `Fooy` to implement `Copy` - --> $DIR/impl_bounds.rs:10:10 + --> $DIR/impl_bounds.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion LL | struct Fooy(T); | ^^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds @@ -59,13 +56,10 @@ LL | fn d() where Self: Copy {} | ^^^^ the trait `Copy` is not implemented for `T` | note: required for `Fooy` to implement `Copy` - --> $DIR/impl_bounds.rs:10:10 + --> $DIR/impl_bounds.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---- in this derive macro expansion LL | struct Fooy(T); | ^^^^ - would need to be `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index e49cf6256cb2..d14f9eae6950 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -37,13 +37,10 @@ LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ no implementation for `T < T` and `T > T` | note: required for `PriorityQueue` to implement `PartialOrd` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:8 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ---------- in this derive macro expansion ... LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^ - would need to be `PartialOrd` diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index 872ce7105ce8..791e2d19f2f9 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -24,15 +24,12 @@ LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Debug` - --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10 + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ^^^^^^^ ---- + | ^^^^^^^ ---- unsatisfied trait bound = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` @@ -69,15 +66,12 @@ LL | pub size: Vector2, | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ^^^^^^^ ---- + | ^^^^^^^ ---- unsatisfied trait bound = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index f843fb0d6d7e..55d6391f975e 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -60,15 +60,12 @@ LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Debug` - --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10 + --> $DIR/missing-bound-in-derive-copy-impl.rs:4:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ^^^^^^^ ---- + | ^^^^^^^ ---- unsatisfied trait bound = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` @@ -133,15 +130,12 @@ LL | pub size: Vector2, | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 + --> $DIR/missing-bound-in-derive-copy-impl.rs:4:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ^^^^^^^ ---- + | ^^^^^^^ ---- unsatisfied trait bound = help: consider manually implementing `Clone` to avoid undesired bounds help: consider restricting type parameter `K` with trait `Copy` | diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr index 02c7fe9e689e..ee78cba5af27 100644 --- a/tests/ui/traits/derive-implicit-bound.stderr +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -8,13 +8,10 @@ LL | accept_eq(&node); | = help: the trait `PartialEq` is not implemented for `SomeNode` note: required for `Id` to implement `PartialEq` - --> $DIR/derive-implicit-bound.rs:5:10 + --> $DIR/derive-implicit-bound.rs:6:12 | LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ - | | - | unsatisfied trait bound introduced in this `derive` macro - | in this derive macro expansion + | --------- in this derive macro expansion LL | pub struct Id(PhantomData); | ^^ - would need to be `PartialEq` = help: consider manually implementing `PartialEq` to avoid undesired bounds From 20000ca25a90c1704e02e349b9583b0bb00086b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 21:28:58 +0000 Subject: [PATCH 25/81] Point at destructor when denying deriving `Copy` --- compiler/rustc_hir_analysis/messages.ftl | 1 + compiler/rustc_hir_analysis/src/coherence/builtin.rs | 5 +++-- compiler/rustc_hir_analysis/src/errors.rs | 2 ++ compiler/rustc_trait_selection/src/traits/misc.rs | 6 +++--- tests/ui/derives/copy-drop-mutually-exclusive.stderr | 12 ++++++++++++ tests/ui/error-codes/E0184.stderr | 6 ++++++ 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index d9f8eba65c4a..611aa070124a 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -142,6 +142,7 @@ hir_analysis_copy_impl_on_non_adt = hir_analysis_copy_impl_on_type_with_dtor = the trait `Copy` cannot be implemented for this type; the type has a destructor .label = `Copy` not allowed on types with destructors + .note = destructor declared here hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type, not `{$self_ty}` .label = can't implement cross-crate trait with a default impl for non-struct/enum type diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61562cc1e4f3..558d2ec84e4b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -121,9 +121,10 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } - Err(CopyImplementationError::HasDestructor) => { + Err(CopyImplementationError::HasDestructor(did)) => { let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; - Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) + let impl_ = tcx.def_span(did); + Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span, impl_ })) } Err(CopyImplementationError::HasUnsafeFields) => { let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 2a77d0b997e2..b90ccc6716d0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -278,6 +278,8 @@ pub(crate) struct CopyImplOnTypeWithDtor { #[primary_span] #[label] pub span: Span, + #[note] + pub impl_: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index f33196bab647..2fd3a6e738cf 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -13,7 +13,7 @@ use crate::traits::{self, FulfillmentError, Obligation, ObligationCause}; pub enum CopyImplementationError<'tcx> { InfringingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>), NotAnAdt, - HasDestructor, + HasDestructor(hir::def_id::DefId), HasUnsafeFields, } @@ -76,8 +76,8 @@ pub fn type_allowed_to_implement_copy<'tcx>( ) .map_err(CopyImplementationError::InfringingFields)?; - if adt.has_dtor(tcx) { - return Err(CopyImplementationError::HasDestructor); + if let Some(did) = adt.destructor(tcx).map(|dtor| dtor.did) { + return Err(CopyImplementationError::HasDestructor(did)); } if impl_safety.is_safe() && self_type.has_unsafe_fields() { diff --git a/tests/ui/derives/copy-drop-mutually-exclusive.stderr b/tests/ui/derives/copy-drop-mutually-exclusive.stderr index f17d33ffbfed..ab2d086c7f5f 100644 --- a/tests/ui/derives/copy-drop-mutually-exclusive.stderr +++ b/tests/ui/derives/copy-drop-mutually-exclusive.stderr @@ -5,6 +5,12 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Foo; | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/copy-drop-mutually-exclusive.rs:7:5 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^^^^^^^^^^ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor --> $DIR/copy-drop-mutually-exclusive.rs:11:8 @@ -13,6 +19,12 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Bar(::std::marker::PhantomData); | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/copy-drop-mutually-exclusive.rs:14:5 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0184.stderr b/tests/ui/error-codes/E0184.stderr index 98b5305ad0dc..13294959bc3c 100644 --- a/tests/ui/error-codes/E0184.stderr +++ b/tests/ui/error-codes/E0184.stderr @@ -5,6 +5,12 @@ LL | #[derive(Copy)] | ---- in this derive macro expansion LL | struct Foo; | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/E0184.rs:5:5 + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error From 23b766ce631dc90c89f1c71878058a2618b7b8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Jan 2026 21:43:18 +0000 Subject: [PATCH 26/81] fix typo --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- tests/ui/traits/derive-implicit-bound-on-clone.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 285288e87ee0..349b2c756b64 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1937,7 +1937,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.type_implements_trait_shallow(clone_trait_did, expected_ty, self.param_env) { let manually_impl = "consider manually implementing `Clone` to avoid the \ - implict type parameter bounds"; + implicit type parameter bounds"; match &errors[..] { [] => {} [error] => { diff --git a/tests/ui/traits/derive-implicit-bound-on-clone.stderr b/tests/ui/traits/derive-implicit-bound-on-clone.stderr index 0cec4ef7c609..2fb039f96528 100644 --- a/tests/ui/traits/derive-implicit-bound-on-clone.stderr +++ b/tests/ui/traits/derive-implicit-bound-on-clone.stderr @@ -22,7 +22,7 @@ LL | struct ContainsRc { | ^ ^ derive introduces an implicit unsatisfied trait bound `K: Clone` | | | derive introduces an implicit unsatisfied trait bound `T: Clone` - = help: consider manually implementing `Clone` to avoid the implict type parameter bounds + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds error[E0308]: mismatched types --> $DIR/derive-implicit-bound-on-clone.rs:20:5 @@ -46,7 +46,7 @@ LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct ContainsRcSingle { | ^ derive introduces an implicit `T: Clone` bound - = help: consider manually implementing `Clone` to avoid the implict type parameter bounds + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds error: aborting due to 2 previous errors From b534229a3ace7e39381efb8941d8277d17a985f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Jan 2026 18:49:12 +0000 Subject: [PATCH 27/81] remove commented out code --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 349b2c756b64..b8f99bbd7e17 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1941,8 +1941,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &errors[..] { [] => {} [error] => { - // diag.note("{error:#?}"); - // diag.note(format!("{:#?} {:#?} {:#?}", error.obligation, error.obligation.cause, error.obligation.cause.code())); let msg = "`Clone` is not implemented because a trait bound is not \ satisfied"; if let traits::ObligationCauseCode::ImplDerived(data) = From 6c8eee82970d4b1659329a8ff1f9bad7ac66e152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Jan 2026 18:59:32 +0000 Subject: [PATCH 28/81] reword span label --- .../src/error_reporting/traits/suggestions.rs | 2 +- .../adt_const_params/unsizing-wfcheck-issue-126272.stderr | 2 +- tests/ui/consts/const-blocks/trait-error.stderr | 2 +- tests/ui/derives/deriving-copyclone.stderr | 6 +++--- tests/ui/generic-associated-types/impl_bounds.stderr | 4 ++-- tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr | 2 +- tests/ui/traits/derive-implicit-bound.stderr | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 70a16b23d276..1880465eff54 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3600,7 +3600,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { spans.push_span_label( data.span, if data.span.in_derive_expansion() { - format!("would need to be `{trait_name}`") + format!("type parameter would need to implement `{trait_name}`") } else { format!("unsatisfied trait bound") }, diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index fc681e655e1a..f520413927c3 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -101,7 +101,7 @@ note: required for `Bar` to implement `Eq` LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | -- in this derive macro expansion LL | struct Bar(T); - | ^^^ - would need to be `Eq` + | ^^^ - type parameter would need to implement `Eq` = help: consider manually implementing `Eq` to avoid undesired bounds = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 60402a412362..853e10e0b35a 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -10,7 +10,7 @@ note: required for `Foo` to implement `Copy` LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Foo(T); - | ^^^ - would need to be `Copy` + | ^^^ - type parameter would need to implement `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index f8d2859f211e..40f96919121f 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -12,7 +12,7 @@ note: required for `B` to implement `Copy` LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct B { - | ^ - would need to be `Copy` + | ^ - type parameter would need to implement `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 @@ -38,7 +38,7 @@ note: required for `B` to implement `Clone` LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion LL | struct B { - | ^ - would need to be `Clone` + | ^ - type parameter would need to implement `Clone` = help: consider manually implementing `Clone` to avoid undesired bounds note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 @@ -64,7 +64,7 @@ note: required for `B` to implement `Copy` LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct B { - | ^ - would need to be `Copy` + | ^ - type parameter would need to implement `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index f65675686532..63c4ba900829 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -34,7 +34,7 @@ note: required for `Fooy` to implement `Copy` LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Fooy(T); - | ^^^^ - would need to be `Copy` + | ^^^^ - type parameter would need to implement `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 @@ -61,7 +61,7 @@ note: required for `Fooy` to implement `Copy` LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Fooy(T); - | ^^^^ - would need to be `Copy` + | ^^^^ - type parameter would need to implement `Copy` = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index d14f9eae6950..b53ebe9f7271 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -43,7 +43,7 @@ LL | #[derive(PartialOrd, AddImpl)] | ---------- in this derive macro expansion ... LL | struct PriorityQueue(BinaryHeap>); - | ^^^^^^^^^^^^^ - would need to be `PartialOrd` + | ^^^^^^^^^^^^^ - type parameter would need to implement `PartialOrd` = help: consider manually implementing `PartialOrd` to avoid undesired bounds note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr index ee78cba5af27..fe2bc77b9529 100644 --- a/tests/ui/traits/derive-implicit-bound.stderr +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -13,7 +13,7 @@ note: required for `Id` to implement `PartialEq` LL | #[derive(PartialEq, Eq)] | --------- in this derive macro expansion LL | pub struct Id(PhantomData); - | ^^ - would need to be `PartialEq` + | ^^ - type parameter would need to implement `PartialEq` = help: consider manually implementing `PartialEq` to avoid undesired bounds note: required by a bound in `accept_eq` --> $DIR/derive-implicit-bound.rs:17:23 From 879633f97b3affafd87a8726240b8109a7bc8363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Jan 2026 19:24:10 +0000 Subject: [PATCH 29/81] Change note to help --- .../src/diagnostics/conflict_errors.rs | 2 +- tests/ui/associated-types/issue-25700.stderr | 2 +- .../closure-shim-borrowck-error.stderr | 2 +- .../async-closures/move-out-of-ref.stderr | 2 +- .../borrowck-move-out-of-static-item.stderr | 2 +- .../borrowck-move-subcomponent.stderr | 2 +- .../borrowck/borrowck-overloaded-call.stderr | 2 +- tests/ui/borrowck/clone-on-ref.stderr | 2 +- .../borrowck/derive-clone-implicit-bound.rs | 4 ++-- .../derive-clone-implicit-bound.stderr | 2 +- tests/ui/borrowck/issue-103624.stderr | 2 +- .../issue-119915-bad-clone-suggestion.stderr | 2 +- .../borrowck/issue-17718-static-move.stderr | 2 +- tests/ui/borrowck/issue-20801.stderr | 8 +++---- .../borrowck/move-error-in-promoted-2.stderr | 2 +- tests/ui/borrowck/move-error-snippets.stderr | 2 +- ...e-in-static-initializer-issue-38520.stderr | 4 ++-- tests/ui/box/leak-alloc.stderr | 2 +- .../closure-move-use-after-move-diagnostic.rs | 2 +- ...sure-move-use-after-move-diagnostic.stderr | 2 +- tests/ui/coroutine/moved-twice.stderr | 2 +- .../derives/deriving-with-repr-packed.stderr | 2 +- tests/ui/error-codes/E0504.stderr | 2 +- tests/ui/error-codes/E0505.stderr | 2 +- tests/ui/error-codes/E0507.stderr | 2 +- tests/ui/error-codes/E0508-fail.stderr | 2 +- tests/ui/error-codes/E0508.stderr | 2 +- tests/ui/error-codes/E0509.stderr | 2 +- tests/ui/mir/issue-102389.stderr | 2 +- tests/ui/moves/issue-72649-uninit-in-loop.rs | 10 ++++---- .../moves/issue-72649-uninit-in-loop.stderr | 15 ++++++------ .../issue-75904-move-closure-loop.stderr | 2 +- ...atching-partially-moved-value-17385.stderr | 4 ++-- tests/ui/moves/move-fn-self-receiver.stderr | 2 +- tests/ui/moves/move-out-of-array-1.stderr | 2 +- .../ui/moves/moved-value-on-as-ref-arg.stderr | 4 ++-- .../issue-21232-partial-init-and-use.stderr | 4 ++-- tests/ui/nll/move-errors.stderr | 12 +++++----- .../pin-ergonomics/borrow-unpin.pinned.stderr | 24 +++++++++---------- .../pin-ergonomics/borrow-unpin.unpin.stderr | 6 ++--- tests/ui/pin-macro/pin_move.stderr | 4 ++-- .../non_copy_move_out_of_tuple.stderr | 2 +- .../suggestions/option-content-move3.stderr | 4 ++-- .../union-borrow-move-parent-sibling.stderr | 2 +- tests/ui/union/union-move.stderr | 4 ++-- tests/ui/variance/variance-issue-20533.stderr | 8 +++---- 46 files changed, 90 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 692ce240e36f..72a35de73f32 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1301,7 +1301,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ), ); span.push_span_label(expr.span, "you could clone this value"); - err.span_note( + err.span_help( span, format!("if `{ty}` implemented `Clone`, you could clone the value"), ); diff --git a/tests/ui/associated-types/issue-25700.stderr b/tests/ui/associated-types/issue-25700.stderr index 8d40e6905e07..595aefc9a215 100644 --- a/tests/ui/associated-types/issue-25700.stderr +++ b/tests/ui/associated-types/issue-25700.stderr @@ -8,7 +8,7 @@ LL | drop(t); LL | drop(t); | ^ value used here after move | -note: if `S<()>` implemented `Clone`, you could clone the value +help: if `S<()>` implemented `Clone`, you could clone the value --> $DIR/issue-25700.rs:1:1 | LL | struct S(#[allow(dead_code)] Option<&'static T>); diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr index 3fe1431fda71..a4d239090830 100644 --- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr @@ -9,7 +9,7 @@ LL | LL | x.hello(); | - variable moved due to use in coroutine | -note: if `Ty` implemented `Clone`, you could clone the value +help: if `Ty` implemented `Clone`, you could clone the value --> $DIR/closure-shim-borrowck-error.rs:17:1 | LL | x.hello(); diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.stderr b/tests/ui/async-await/async-closures/move-out-of-ref.stderr index d443dc9d4831..c516597c81f9 100644 --- a/tests/ui/async-await/async-closures/move-out-of-ref.stderr +++ b/tests/ui/async-await/async-closures/move-out-of-ref.stderr @@ -7,7 +7,7 @@ LL | let c = async || { LL | *x; | ^^ `*x` is moved here | -note: if `Ty` implemented `Clone`, you could clone the value +help: if `Ty` implemented `Clone`, you could clone the value --> $DIR/move-out-of-ref.rs:5:1 | LL | struct Ty; diff --git a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr index b4b60d40d914..9eb90e169fd3 100644 --- a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr +++ b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of static item `BAR` LL | test(BAR); | ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-out-of-static-item.rs:3:1 | LL | struct Foo { diff --git a/tests/ui/borrowck/borrowck-move-subcomponent.stderr b/tests/ui/borrowck/borrowck-move-subcomponent.stderr index b5dc01f180b2..8dcb81273f89 100644 --- a/tests/ui/borrowck/borrowck-move-subcomponent.stderr +++ b/tests/ui/borrowck/borrowck-move-subcomponent.stderr @@ -10,7 +10,7 @@ LL | let S { x: ax } = a; LL | f(pb); | -- borrow later used here | -note: if `S` implemented `Clone`, you could clone the value +help: if `S` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-subcomponent.rs:6:1 | LL | struct S { diff --git a/tests/ui/borrowck/borrowck-overloaded-call.stderr b/tests/ui/borrowck/borrowck-overloaded-call.stderr index c3b7b0b6080c..c838c6512bc4 100644 --- a/tests/ui/borrowck/borrowck-overloaded-call.stderr +++ b/tests/ui/borrowck/borrowck-overloaded-call.stderr @@ -30,7 +30,7 @@ LL | s(" world".to_string()); LL | s(" world".to_string()); | ^ value used here after move | -note: if `SFnOnce` implemented `Clone`, you could clone the value +help: if `SFnOnce` implemented `Clone`, you could clone the value --> $DIR/borrowck-overloaded-call.rs:41:1 | LL | struct SFnOnce { diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr index 72580e7464b7..535550409dd8 100644 --- a/tests/ui/borrowck/clone-on-ref.stderr +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -59,7 +59,7 @@ LL | LL | println!("{b:?}"); | - borrow later used here | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/clone-on-ref.rs:19:1 | LL | struct A; diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.rs b/tests/ui/borrowck/derive-clone-implicit-bound.rs index a20e04d3afdc..12fd2129331b 100644 --- a/tests/ui/borrowck/derive-clone-implicit-bound.rs +++ b/tests/ui/borrowck/derive-clone-implicit-bound.rs @@ -4,7 +4,7 @@ use std::marker::PhantomData; #[derive(Clone, Copy)] //~ NOTE derived `Clone` adds implicit bounds on type parameters pub struct TypedAddress{ -//~^ NOTE if `TypedAddress` implemented `Clone`, you could clone the value +//~^ HELP if `TypedAddress` implemented `Clone`, you could clone the value //~| NOTE consider manually implementing `Clone` for this type //~| NOTE introduces an implicit `T: Clone` bound inner: u64, @@ -19,7 +19,7 @@ pub trait Memory { //~| NOTE this parameter takes ownership of the value fn update_value(&self, offset: TypedAddress, update: F) //~^ NOTE move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait - where F: FnOnce(T) -> T + where F: FnOnce(T) -> T //~ HELP consider further restricting type parameter `T` { let old = self.return_value(offset); //~ NOTE value moved here //~^ NOTE you could clone this value diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.stderr b/tests/ui/borrowck/derive-clone-implicit-bound.stderr index b10e3a92c96b..31a55b448eb6 100644 --- a/tests/ui/borrowck/derive-clone-implicit-bound.stderr +++ b/tests/ui/borrowck/derive-clone-implicit-bound.stderr @@ -15,7 +15,7 @@ note: consider changing this parameter type in method `return_value` to borrow i | LL | fn return_value(&self, offset: TypedAddress) -> T; | ------------ in this method ^^^^^^^^^^^^^^^ this parameter takes ownership of the value -note: if `TypedAddress` implemented `Clone`, you could clone the value +help: if `TypedAddress` implemented `Clone`, you could clone the value --> $DIR/derive-clone-implicit-bound.rs:6:1 | LL | #[derive(Clone, Copy)] diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index bd6c1c44bfb3..85769e187691 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -18,7 +18,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | async fn spawn_blocking(f: impl (Fn() -> T) + Send + Sync + 'static) -> T { | ^^^^^^^^^^^ -note: if `StructB` implemented `Clone`, you could clone the value +help: if `StructB` implemented `Clone`, you could clone the value --> $DIR/issue-103624.rs:23:1 | LL | self.b; diff --git a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr index dde17d1f6523..a5a218a0641d 100644 --- a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr +++ b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr @@ -11,7 +11,7 @@ note: `Example::::change` takes ownership of the receiver `self`, | LL | unsafe fn change(self) -> Example { | ^^^^ -note: if `Example` implemented `Clone`, you could clone the value +help: if `Example` implemented `Clone`, you could clone the value --> $DIR/issue-119915-bad-clone-suggestion.rs:3:1 | LL | struct Example(PhantomData<(fn(E), fn(FakeParam))>); diff --git a/tests/ui/borrowck/issue-17718-static-move.stderr b/tests/ui/borrowck/issue-17718-static-move.stderr index 057ac6d7e3df..959b1d1a3b84 100644 --- a/tests/ui/borrowck/issue-17718-static-move.stderr +++ b/tests/ui/borrowck/issue-17718-static-move.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of static item `FOO` LL | let _a = FOO; | ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/issue-17718-static-move.rs:1:1 | LL | struct Foo; diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr index 5fda92634d8f..5336352e0dbd 100644 --- a/tests/ui/borrowck/issue-20801.stderr +++ b/tests/ui/borrowck/issue-20801.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of a mutable reference LL | let a = unsafe { *mut_ref() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -note: if `T` implemented `Clone`, you could clone the value +help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -24,7 +24,7 @@ error[E0507]: cannot move out of a shared reference LL | let b = unsafe { *imm_ref() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -note: if `T` implemented `Clone`, you could clone the value +help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -44,7 +44,7 @@ error[E0507]: cannot move out of a raw pointer LL | let c = unsafe { *mut_ptr() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -note: if `T` implemented `Clone`, you could clone the value +help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -59,7 +59,7 @@ error[E0507]: cannot move out of a raw pointer LL | let d = unsafe { *const_ptr() }; | ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -note: if `T` implemented `Clone`, you could clone the value +help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); diff --git a/tests/ui/borrowck/move-error-in-promoted-2.stderr b/tests/ui/borrowck/move-error-in-promoted-2.stderr index 1e9b1d5209cb..f2bc6bd4760a 100644 --- a/tests/ui/borrowck/move-error-in-promoted-2.stderr +++ b/tests/ui/borrowck/move-error-in-promoted-2.stderr @@ -7,7 +7,7 @@ LL | &([S][0],); | cannot move out of here | move occurs because value has type `S`, which does not implement the `Copy` trait | -note: if `S` implemented `Clone`, you could clone the value +help: if `S` implemented `Clone`, you could clone the value --> $DIR/move-error-in-promoted-2.rs:3:1 | LL | struct S; diff --git a/tests/ui/borrowck/move-error-snippets.stderr b/tests/ui/borrowck/move-error-snippets.stderr index 97d140515184..3796b7e05fb4 100644 --- a/tests/ui/borrowck/move-error-snippets.stderr +++ b/tests/ui/borrowck/move-error-snippets.stderr @@ -9,7 +9,7 @@ LL | let a = $c; LL | sss!(); | ------ in this macro invocation | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-error-snippets.rs:9:1 | LL | struct A; diff --git a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr index 009e85a8031e..af5cbdcf150f 100644 --- a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr +++ b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of a shared reference LL | static Y: usize = get(*&X); | ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); @@ -19,7 +19,7 @@ error[E0507]: cannot move out of a shared reference LL | const Z: usize = get(*&X); | ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); diff --git a/tests/ui/box/leak-alloc.stderr b/tests/ui/box/leak-alloc.stderr index bdaa9449f913..f0d6dd3d4692 100644 --- a/tests/ui/box/leak-alloc.stderr +++ b/tests/ui/box/leak-alloc.stderr @@ -12,7 +12,7 @@ LL | LL | use_value(*theref) | ------- borrow later used here | -note: if `Alloc` implemented `Clone`, you could clone the value +help: if `Alloc` implemented `Clone`, you could clone the value --> $DIR/leak-alloc.rs:8:1 | LL | struct Alloc {} diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs index 3326af7486c5..b55c8c16f611 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs @@ -1,5 +1,5 @@ //! regression test for -struct NoCopy; //~ NOTE if `NoCopy` implemented `Clone`, you could clone the value +struct NoCopy; //~ HELP if `NoCopy` implemented `Clone`, you could clone the value //~^ NOTE consider implementing `Clone` for this type fn main() { let x = NoCopy; diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr index 94f80da1b10a..bde39ca6ca71 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr @@ -13,7 +13,7 @@ LL | let y = x; LL | let z = x; | ^ value used here after move | -note: if `NoCopy` implemented `Clone`, you could clone the value +help: if `NoCopy` implemented `Clone`, you could clone the value --> $DIR/closure-move-use-after-move-diagnostic.rs:2:1 | LL | struct NoCopy; diff --git a/tests/ui/coroutine/moved-twice.stderr b/tests/ui/coroutine/moved-twice.stderr index 2b21f6c59f0b..561b3b331d9f 100644 --- a/tests/ui/coroutine/moved-twice.stderr +++ b/tests/ui/coroutine/moved-twice.stderr @@ -10,7 +10,7 @@ LL | yield; LL | let second = first; | ^^^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/moved-twice.rs:9:1 | LL | struct Foo([u8; FOO_SIZE]); diff --git a/tests/ui/derives/deriving-with-repr-packed.stderr b/tests/ui/derives/deriving-with-repr-packed.stderr index 9cfc4abdc0cb..7c716fb9dd4c 100644 --- a/tests/ui/derives/deriving-with-repr-packed.stderr +++ b/tests/ui/derives/deriving-with-repr-packed.stderr @@ -7,7 +7,7 @@ LL | #[repr(packed)] LL | struct X(Y); | ^ move occurs because value has type `Y`, which does not implement the `Copy` trait | -note: if `Y` implemented `Clone`, you could clone the value +help: if `Y` implemented `Clone`, you could clone the value --> $DIR/deriving-with-repr-packed.rs:16:1 | LL | struct Y(usize); diff --git a/tests/ui/error-codes/E0504.stderr b/tests/ui/error-codes/E0504.stderr index c4cbc834ad98..528f311765df 100644 --- a/tests/ui/error-codes/E0504.stderr +++ b/tests/ui/error-codes/E0504.stderr @@ -14,7 +14,7 @@ LL | println!("child function: {}", fancy_num.num); LL | println!("main function: {}", fancy_ref.num); | ------------- borrow later used here | -note: if `FancyNum` implemented `Clone`, you could clone the value +help: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0504.rs:2:1 | LL | struct FancyNum { diff --git a/tests/ui/error-codes/E0505.stderr b/tests/ui/error-codes/E0505.stderr index 3f2913e9fe3c..ac0f390bc54b 100644 --- a/tests/ui/error-codes/E0505.stderr +++ b/tests/ui/error-codes/E0505.stderr @@ -11,7 +11,7 @@ LL | eat(x); LL | _ref_to_val.use_ref(); | ----------- borrow later used here | -note: if `Value` implemented `Clone`, you could clone the value +help: if `Value` implemented `Clone`, you could clone the value --> $DIR/E0505.rs:1:1 | LL | struct Value {} diff --git a/tests/ui/error-codes/E0507.stderr b/tests/ui/error-codes/E0507.stderr index 70d99ea2cce5..ac03e5ea9cd5 100644 --- a/tests/ui/error-codes/E0507.stderr +++ b/tests/ui/error-codes/E0507.stderr @@ -11,7 +11,7 @@ note: `TheDarkKnight::nothing_is_true` takes ownership of the receiver `self`, w | LL | fn nothing_is_true(self) {} | ^^^^ -note: if `TheDarkKnight` implemented `Clone`, you could clone the value +help: if `TheDarkKnight` implemented `Clone`, you could clone the value --> $DIR/E0507.rs:3:1 | LL | struct TheDarkKnight; diff --git a/tests/ui/error-codes/E0508-fail.stderr b/tests/ui/error-codes/E0508-fail.stderr index fcfac399e0df..48ede17dc26a 100644 --- a/tests/ui/error-codes/E0508-fail.stderr +++ b/tests/ui/error-codes/E0508-fail.stderr @@ -7,7 +7,7 @@ LL | let _value = array[0]; | cannot move out of here | move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508-fail.rs:1:1 | LL | struct NonCopy; diff --git a/tests/ui/error-codes/E0508.stderr b/tests/ui/error-codes/E0508.stderr index b9fa0f4d17a5..c001b9461ebf 100644 --- a/tests/ui/error-codes/E0508.stderr +++ b/tests/ui/error-codes/E0508.stderr @@ -7,7 +7,7 @@ LL | let _value = array[0]; | cannot move out of here | move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508.rs:1:1 | LL | struct NonCopy; diff --git a/tests/ui/error-codes/E0509.stderr b/tests/ui/error-codes/E0509.stderr index 628a253e0859..89c3a5848423 100644 --- a/tests/ui/error-codes/E0509.stderr +++ b/tests/ui/error-codes/E0509.stderr @@ -7,7 +7,7 @@ LL | let fancy_field = drop_struct.fancy; | cannot move out of here | move occurs because `drop_struct.fancy` has type `FancyNum`, which does not implement the `Copy` trait | -note: if `FancyNum` implemented `Clone`, you could clone the value +help: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0509.rs:1:1 | LL | struct FancyNum { diff --git a/tests/ui/mir/issue-102389.stderr b/tests/ui/mir/issue-102389.stderr index 162d7ac031a6..7aafe081deaf 100644 --- a/tests/ui/mir/issue-102389.stderr +++ b/tests/ui/mir/issue-102389.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of `*inbounds` which is behind a shared reference LL | array[*inbounds as usize] | ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait | -note: if `Enum` implemented `Clone`, you could clone the value +help: if `Enum` implemented `Clone`, you could clone the value --> $DIR/issue-102389.rs:1:1 | LL | enum Enum { A, B, C } diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.rs b/tests/ui/moves/issue-72649-uninit-in-loop.rs index 8f2e01bdf1ab..965a4206253e 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.rs +++ b/tests/ui/moves/issue-72649-uninit-in-loop.rs @@ -3,10 +3,10 @@ // 'value moved in previous iteration of loop' message struct NonCopy; -//~^ NOTE if `NonCopy` implemented `Clone` -//~| NOTE if `NonCopy` implemented `Clone` -//~| NOTE if `NonCopy` implemented `Clone` -//~| NOTE if `NonCopy` implemented `Clone` +//~^ HELP if `NonCopy` implemented `Clone` +//~| HELP if `NonCopy` implemented `Clone` +//~| HELP if `NonCopy` implemented `Clone` +//~| HELP if `NonCopy` implemented `Clone` //~| NOTE consider implementing `Clone` for this type //~| NOTE consider implementing `Clone` for this type //~| NOTE consider implementing `Clone` for this type @@ -70,6 +70,7 @@ fn moved_loop_2() { fn uninit_1() { loop { let value: NonCopy; //~ NOTE declared here + //~^ HELP consider assigning a value let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized } @@ -77,6 +78,7 @@ fn uninit_1() { fn uninit_2() { let mut value: NonCopy; //~ NOTE declared here + //~^ HELP consider assigning a value loop { let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 3a93769ac454..1c54d3997ed6 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -10,7 +10,7 @@ LL | let _used = value; LL | let _used2 = value; | ^^^^^ value used here after move | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -33,7 +33,7 @@ LL | let _used = value; LL | let _used2 = value; | ^^^^^ value used here after move | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -53,7 +53,7 @@ LL | loop { LL | let _used = value; | ^^^^^ value moved here, in previous iteration of loop | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -73,7 +73,7 @@ LL | loop { LL | let _used2 = value; | ^^^^^ value moved here, in previous iteration of loop | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -83,10 +83,11 @@ LL | let _used2 = value; | ----- you could clone this value error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:73:21 + --> $DIR/issue-72649-uninit-in-loop.rs:74:21 | LL | let value: NonCopy; | ----- binding declared here but left uninitialized +LL | LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized | @@ -96,11 +97,11 @@ LL | let value: NonCopy = /* value */; | +++++++++++++ error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:81:21 + --> $DIR/issue-72649-uninit-in-loop.rs:83:21 | LL | let mut value: NonCopy; | --------- binding declared here but left uninitialized -LL | loop { +... LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized | diff --git a/tests/ui/moves/issue-75904-move-closure-loop.stderr b/tests/ui/moves/issue-75904-move-closure-loop.stderr index 815e91b0f4df..3fc50c48315d 100644 --- a/tests/ui/moves/issue-75904-move-closure-loop.stderr +++ b/tests/ui/moves/issue-75904-move-closure-loop.stderr @@ -11,7 +11,7 @@ LL | &mut a; LL | a; | - use occurs due to use in closure | -note: if `NotCopy` implemented `Clone`, you could clone the value +help: if `NotCopy` implemented `Clone`, you could clone the value --> $DIR/issue-75904-move-closure-loop.rs:5:1 | LL | struct NotCopy; diff --git a/tests/ui/moves/matching-partially-moved-value-17385.stderr b/tests/ui/moves/matching-partially-moved-value-17385.stderr index 906f7868bccb..83f4f4320485 100644 --- a/tests/ui/moves/matching-partially-moved-value-17385.stderr +++ b/tests/ui/moves/matching-partially-moved-value-17385.stderr @@ -8,7 +8,7 @@ LL | drop(foo); LL | match foo { | ^^^^^^^^^ value used here after move | -note: if `X` implemented `Clone`, you could clone the value +help: if `X` implemented `Clone`, you could clone the value --> $DIR/matching-partially-moved-value-17385.rs:2:1 | LL | struct X(isize); @@ -27,7 +27,7 @@ LL | drop(e); LL | match e { | ^ value used here after move | -note: if `Enum` implemented `Clone`, you could clone the value +help: if `Enum` implemented `Clone`, you could clone the value --> $DIR/matching-partially-moved-value-17385.rs:4:1 | LL | enum Enum { diff --git a/tests/ui/moves/move-fn-self-receiver.stderr b/tests/ui/moves/move-fn-self-receiver.stderr index de19a99d388c..b3a1215fa2f7 100644 --- a/tests/ui/moves/move-fn-self-receiver.stderr +++ b/tests/ui/moves/move-fn-self-receiver.stderr @@ -132,7 +132,7 @@ LL | foo_add + Foo; LL | foo_add; | ^^^^^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-fn-self-receiver.rs:5:1 | LL | struct Foo; diff --git a/tests/ui/moves/move-out-of-array-1.stderr b/tests/ui/moves/move-out-of-array-1.stderr index 8a030f021920..7ef859200b21 100644 --- a/tests/ui/moves/move-out-of-array-1.stderr +++ b/tests/ui/moves/move-out-of-array-1.stderr @@ -7,7 +7,7 @@ LL | a[i] | cannot move out of here | move occurs because `a[_]` has type `D`, which does not implement the `Copy` trait | -note: if `D` implemented `Clone`, you could clone the value +help: if `D` implemented `Clone`, you could clone the value --> $DIR/move-out-of-array-1.rs:5:1 | LL | struct D { _x: u8 } diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.stderr b/tests/ui/moves/moved-value-on-as-ref-arg.stderr index a99bdb4fe9d4..b553938c6fed 100644 --- a/tests/ui/moves/moved-value-on-as-ref-arg.stderr +++ b/tests/ui/moves/moved-value-on-as-ref-arg.stderr @@ -23,7 +23,7 @@ LL | qux(bar); LL | let _baa = bar; | ^^^ value used here after move | -note: if `Bar` implemented `Clone`, you could clone the value +help: if `Bar` implemented `Clone`, you could clone the value --> $DIR/moved-value-on-as-ref-arg.rs:5:1 | LL | struct Bar; @@ -61,7 +61,7 @@ LL | baz(bar); LL | let _baa = bar; | ^^^ value used here after move | -note: if `Bar` implemented `Clone`, you could clone the value +help: if `Bar` implemented `Clone`, you could clone the value --> $DIR/moved-value-on-as-ref-arg.rs:5:1 | LL | struct Bar; diff --git a/tests/ui/nll/issue-21232-partial-init-and-use.stderr b/tests/ui/nll/issue-21232-partial-init-and-use.stderr index 496a298a36ce..84c543921687 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/tests/ui/nll/issue-21232-partial-init-and-use.stderr @@ -28,7 +28,7 @@ LL | let mut s: S = S::new(); drop(s); LL | s.x = 10; s.y = Box::new(20); | ^^^^^^^^ value partially assigned here after move | -note: if `S>` implemented `Clone`, you could clone the value +help: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { @@ -82,7 +82,7 @@ LL | let mut s: S = S::new(); drop(s); LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move | -note: if `S>` implemented `Clone`, you could clone the value +help: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { diff --git a/tests/ui/nll/move-errors.stderr b/tests/ui/nll/move-errors.stderr index bcb2ab84a239..e84f75455217 100644 --- a/tests/ui/nll/move-errors.stderr +++ b/tests/ui/nll/move-errors.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of `*a` which is behind a shared reference LL | let b = *a; | ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -27,7 +27,7 @@ LL | let b = a[0]; | cannot move out of here | move occurs because `a[_]` has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -46,7 +46,7 @@ error[E0507]: cannot move out of `**r` which is behind a shared reference LL | let s = **r; | ^^^ move occurs because `**r` has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -66,7 +66,7 @@ error[E0507]: cannot move out of an `Rc` LL | let s = *r; | ^^ move occurs because value has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -89,7 +89,7 @@ LL | let a = [A("".to_string())][0]; | cannot move out of here | move occurs because value has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -137,7 +137,7 @@ error[E0507]: cannot move out of `*a` which is behind a shared reference LL | b = *a; | ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait | -note: if `A` implemented `Clone`, you could clone the value +help: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); diff --git a/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr b/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr index cc438461a5d1..f9bef8d83f96 100644 --- a/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr +++ b/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr @@ -8,7 +8,7 @@ LL | foo_pin_mut(&pin mut foo); LL | foo_move(foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -27,7 +27,7 @@ LL | let x = &pin mut foo; LL | foo_move(foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -46,7 +46,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_move(foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -65,7 +65,7 @@ LL | let x = &pin mut foo; // ok LL | foo_move(foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -87,7 +87,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -106,7 +106,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_ref(&foo); | ^^^^ value borrowed here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -125,7 +125,7 @@ LL | let x = &pin mut foo; // ok LL | foo_ref(&foo); | ^^^^ value borrowed here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -144,7 +144,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_pin_mut(&pin mut foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -163,7 +163,7 @@ LL | let x = &pin mut foo; // ok LL | foo_pin_mut(&pin mut foo); | ^^^ value used here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -185,7 +185,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -204,7 +204,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_pin_ref(&pin const foo); | ^^^^^^^^^^^^^^ value borrowed here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -223,7 +223,7 @@ LL | let x = &pin mut foo; // ok LL | foo_pin_ref(&pin const foo); | ^^^^^^^^^^^^^^ value borrowed here after move | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); diff --git a/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr b/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr index bf9921343ee7..523191655813 100644 --- a/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr +++ b/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr @@ -33,7 +33,7 @@ LL | LL | foo_pin_mut(x); // | - borrow later used here | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; @@ -55,7 +55,7 @@ LL | LL | foo_pin_mut(x); // | - borrow later used here | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; @@ -77,7 +77,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -note: if `Foo` implemented `Clone`, you could clone the value +help: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; diff --git a/tests/ui/pin-macro/pin_move.stderr b/tests/ui/pin-macro/pin_move.stderr index 3f4660209885..cf7d50091ba4 100644 --- a/tests/ui/pin-macro/pin_move.stderr +++ b/tests/ui/pin-macro/pin_move.stderr @@ -8,7 +8,7 @@ LL | pin!(pointee); LL | let _moved = pointee; | ^^^^^^^ value used here after move | -note: if `a::NotCopy` implemented `Clone`, you could clone the value +help: if `a::NotCopy` implemented `Clone`, you could clone the value --> $DIR/pin_move.rs:7:5 | LL | struct NotCopy(T); @@ -23,7 +23,7 @@ error[E0507]: cannot move out of a mutable reference LL | pin!(*&mut pointee); | ^^^^^^^^^^^^^ move occurs because value has type `b::NotCopy`, which does not implement the `Copy` trait | -note: if `b::NotCopy` implemented `Clone`, you could clone the value +help: if `b::NotCopy` implemented `Clone`, you could clone the value --> $DIR/pin_move.rs:16:5 | LL | struct NotCopy(T); diff --git a/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr b/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr index 62f24324fcc1..5e447a57bfee 100644 --- a/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr +++ b/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr @@ -7,7 +7,7 @@ LL | (b,) = *tuple; | data moved here | move occurs because the place has type `NonCopy`, which does not implement the `Copy` trait | -note: if `NonCopy` implemented `Clone`, you could clone the value +help: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/non_copy_move_out_of_tuple.rs:3:1 | LL | struct NonCopy; diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr index f78d3cf67862..cd13592d652e 100644 --- a/tests/ui/suggestions/option-content-move3.stderr +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -10,7 +10,7 @@ LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait | = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once -note: if `NotCopyable` implemented `Clone`, you could clone the value +help: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | LL | struct NotCopyable; @@ -43,7 +43,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | fn func H, H: FnMut()>(_: F) {} | ^^^^^^^^^^^^ -note: if `NotCopyable` implemented `Clone`, you could clone the value +help: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | LL | struct NotCopyable; diff --git a/tests/ui/union/union-borrow-move-parent-sibling.stderr b/tests/ui/union/union-borrow-move-parent-sibling.stderr index 461ee407e2dd..5974441dd807 100644 --- a/tests/ui/union/union-borrow-move-parent-sibling.stderr +++ b/tests/ui/union/union-borrow-move-parent-sibling.stderr @@ -59,7 +59,7 @@ error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec, Moc LL | let a = (u.x.0).0; | ^^^^^^^^^ move occurs because value has type `MockVec`, which does not implement the `Copy` trait | -note: if `MockVec` implemented `Clone`, you could clone the value +help: if `MockVec` implemented `Clone`, you could clone the value --> $DIR/union-borrow-move-parent-sibling.rs:25:1 | LL | struct MockVec { diff --git a/tests/ui/union/union-move.stderr b/tests/ui/union/union-move.stderr index d520fb00ea9d..6266bb4770e0 100644 --- a/tests/ui/union/union-move.stderr +++ b/tests/ui/union/union-move.stderr @@ -16,7 +16,7 @@ LL | fn move_out(x: T) {} | -------- ^ this parameter takes ownership of the value | | | in this function -note: if `U1` implemented `Clone`, you could clone the value +help: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { @@ -43,7 +43,7 @@ LL | fn move_out(x: T) {} | -------- ^ this parameter takes ownership of the value | | | in this function -note: if `U1` implemented `Clone`, you could clone the value +help: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr index 21d8de6ae881..2a33a88bdd56 100644 --- a/tests/ui/variance/variance-issue-20533.stderr +++ b/tests/ui/variance/variance-issue-20533.stderr @@ -10,7 +10,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -note: if `AffineU32` implemented `Clone`, you could clone the value +help: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -31,7 +31,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -note: if `AffineU32` implemented `Clone`, you could clone the value +help: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -52,7 +52,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -note: if `AffineU32` implemented `Clone`, you could clone the value +help: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -73,7 +73,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -note: if `AffineU32` implemented `Clone`, you could clone the value +help: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); From 8543404e8d8668d9834dc48a687d5096d4949f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Jan 2026 21:33:39 +0000 Subject: [PATCH 30/81] Tweak span in E0599 --- .../rustc_hir_typeck/src/method/suggest.rs | 50 ++++++++++++------- .../derives/derive-assoc-type-not-impl.stderr | 6 ++- .../deriving-with-repr-packed-2.stderr | 7 ++- tests/ui/union/union-derive-clone.stderr | 6 ++- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f5ef5adff6bd..517d73f51783 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1752,16 +1752,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (p, parent_p, cause) in unsatisfied_predicates { // Extract the predicate span and parent def id of the cause, // if we have one. - let (item_def_id, cause_span) = match cause.as_ref().map(|cause| cause.code()) { - Some(ObligationCauseCode::ImplDerived(data)) => { - (data.impl_or_alias_def_id, data.span) - } - Some( - ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _) - | ObligationCauseCode::WhereClause(def_id, span), - ) if !span.is_dummy() => (*def_id, *span), - _ => continue, - }; + let (item_def_id, cause_span, cause_msg) = + match cause.as_ref().map(|cause| cause.code()) { + Some(ObligationCauseCode::ImplDerived(data)) => { + let msg = if let DefKind::Impl { of_trait: true } = + self.tcx.def_kind(data.impl_or_alias_def_id) + { + format!( + "type parameter would need to implement `{}`", + self.tcx + .item_name(self.tcx.impl_trait_id(data.impl_or_alias_def_id)) + ) + } else { + format!("unsatisfied bound `{p}` introduced here") + }; + (data.impl_or_alias_def_id, data.span, msg) + } + Some( + ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _) + | ObligationCauseCode::WhereClause(def_id, span), + ) if !span.is_dummy() => { + (*def_id, *span, format!("unsatisfied bound `{p}` introduced here")) + } + _ => continue, + }; // Don't point out the span of `WellFormed` predicates. if !matches!( @@ -1792,10 +1806,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let entry = entry.or_insert_with(|| { (FxIndexSet::default(), FxIndexSet::default(), Vec::new()) }); - entry.0.insert(span); + entry.0.insert(cause_span); entry.1.insert(( - span, - "unsatisfied trait bound introduced in this `derive` macro", + cause_span, + cause_msg, )); entry.2.push(p); skip_list.insert(p); @@ -1844,7 +1858,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { entry.2.push(p); if cause_span != *item_span { entry.0.insert(cause_span); - entry.1.insert((cause_span, "unsatisfied trait bound introduced here")); + entry.1.insert((cause_span, "unsatisfied trait bound introduced here".to_string())); } else { if let Some(of_trait) = of_trait { entry.0.insert(of_trait.trait_ref.path.span); @@ -1852,9 +1866,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { entry.0.insert(self_ty.span); }; if let Some(of_trait) = of_trait { - entry.1.insert((of_trait.trait_ref.path.span, "")); + entry.1.insert((of_trait.trait_ref.path.span, String::new())); } - entry.1.insert((self_ty.span, "")); + entry.1.insert((self_ty.span, String::new())); } Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, rustc_ast::ast::IsAuto::Yes, ..), @@ -1883,8 +1897,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (FxIndexSet::default(), FxIndexSet::default(), Vec::new()) }); entry.0.insert(cause_span); - entry.1.insert((ident.span, "")); - entry.1.insert((cause_span, "unsatisfied trait bound introduced here")); + entry.1.insert((ident.span, String::new())); + entry.1.insert((cause_span, "unsatisfied trait bound introduced here".to_string())); entry.2.push(p); } _ => { diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr index e239ad4ef209..ca968910fde4 100644 --- a/tests/ui/derives/derive-assoc-type-not-impl.stderr +++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr @@ -11,10 +11,12 @@ LL | Bar:: { x: 1 }.clone(); | ^^^^^ method cannot be called on `Bar` due to unsatisfied trait bounds | note: trait bound `NotClone: Clone` was not satisfied - --> $DIR/derive-assoc-type-not-impl.rs:6:10 + --> $DIR/derive-assoc-type-not-impl.rs:7:12 | LL | #[derive(Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | struct Bar { + | ^ type parameter would need to implement `Clone` = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NotClone` with `#[derive(Clone)]` | diff --git a/tests/ui/derives/deriving-with-repr-packed-2.stderr b/tests/ui/derives/deriving-with-repr-packed-2.stderr index fff6269472bd..6bd3fff39790 100644 --- a/tests/ui/derives/deriving-with-repr-packed-2.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-2.stderr @@ -21,10 +21,13 @@ LL | let x: Foo = Foo(NonCopy, NonCopy, NonCopy); note: the following trait bounds were not satisfied: `NonCopy: Clone` `NonCopy: Copy` - --> $DIR/deriving-with-repr-packed-2.rs:5:16 + --> $DIR/deriving-with-repr-packed-2.rs:7:16 | LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | #[repr(packed)] +LL | pub struct Foo(T, T, T); + | ^ type parameter would need to implement `Clone` = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NonCopy` with `#[derive(Clone, Copy)]` | diff --git a/tests/ui/union/union-derive-clone.stderr b/tests/ui/union/union-derive-clone.stderr index 65488629b629..62ef35b76192 100644 --- a/tests/ui/union/union-derive-clone.stderr +++ b/tests/ui/union/union-derive-clone.stderr @@ -25,10 +25,12 @@ LL | let w = u.clone(); | ^^^^^ method cannot be called on `U5` due to unsatisfied trait bounds | note: trait bound `CloneNoCopy: Copy` was not satisfied - --> $DIR/union-derive-clone.rs:25:10 + --> $DIR/union-derive-clone.rs:26:10 | LL | #[derive(Clone, Copy)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | union U5 { + | ^ type parameter would need to implement `Clone` = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | From dffec20dee76131f74736f05f01abf44161d3264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Jan 2026 21:54:43 +0000 Subject: [PATCH 31/81] Tweak help to unify formatting and wording --- .../src/diagnostics/conflict_errors.rs | 27 +++++++++++-------- tests/ui/associated-types/issue-25700.stderr | 2 +- .../closure-shim-borrowck-error.stderr | 2 +- .../async-closures/move-out-of-ref.stderr | 2 +- .../borrowck-move-out-of-static-item.stderr | 2 +- .../borrowck-move-subcomponent.stderr | 2 +- .../borrowck/borrowck-overloaded-call.stderr | 2 +- tests/ui/borrowck/clone-on-ref.stderr | 2 +- .../borrowck/derive-clone-implicit-bound.rs | 26 +++++++++--------- .../derive-clone-implicit-bound.stderr | 12 ++++----- tests/ui/borrowck/issue-103624.stderr | 2 +- .../issue-119915-bad-clone-suggestion.stderr | 2 +- .../borrowck/issue-17718-static-move.stderr | 2 +- tests/ui/borrowck/issue-20801.stderr | 8 +++--- .../borrowck/move-error-in-promoted-2.stderr | 2 +- tests/ui/borrowck/move-error-snippets.stderr | 2 +- ...e-in-static-initializer-issue-38520.stderr | 4 +-- tests/ui/box/leak-alloc.stderr | 2 +- .../closure-move-use-after-move-diagnostic.rs | 16 +++++------ ...sure-move-use-after-move-diagnostic.stderr | 2 +- tests/ui/coroutine/moved-twice.stderr | 2 +- .../derives/deriving-with-repr-packed.stderr | 2 +- tests/ui/error-codes/E0504.stderr | 2 +- tests/ui/error-codes/E0505.stderr | 2 +- tests/ui/error-codes/E0507.stderr | 2 +- tests/ui/error-codes/E0508-fail.stderr | 2 +- tests/ui/error-codes/E0508.stderr | 2 +- tests/ui/error-codes/E0509.stderr | 2 +- tests/ui/mir/issue-102389.stderr | 2 +- tests/ui/moves/issue-72649-uninit-in-loop.rs | 8 +++--- .../moves/issue-72649-uninit-in-loop.stderr | 8 +++--- .../issue-75904-move-closure-loop.stderr | 2 +- ...atching-partially-moved-value-17385.stderr | 4 +-- tests/ui/moves/move-fn-self-receiver.stderr | 2 +- tests/ui/moves/move-out-of-array-1.stderr | 2 +- .../ui/moves/moved-value-on-as-ref-arg.stderr | 4 +-- .../issue-21232-partial-init-and-use.stderr | 4 +-- tests/ui/nll/move-errors.stderr | 12 ++++----- .../pin-ergonomics/borrow-unpin.pinned.stderr | 24 ++++++++--------- .../pin-ergonomics/borrow-unpin.unpin.stderr | 6 ++--- tests/ui/pin-macro/pin_move.stderr | 4 +-- .../non_copy_move_out_of_tuple.stderr | 2 +- .../suggestions/option-content-move3.stderr | 4 +-- .../union-borrow-move-parent-sibling.stderr | 2 +- tests/ui/union/union-move.stderr | 4 +-- tests/ui/variance/variance-issue-20533.stderr | 8 +++--- 46 files changed, 122 insertions(+), 117 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 72a35de73f32..a39300f7030f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1293,18 +1293,23 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } }, ); - span.push_span_label( - ty_span, - format!( - "consider {}implementing `Clone` for this type", - if derive_clone { "manually " } else { "" } - ), - ); + let msg = if !derive_clone { + span.push_span_label( + ty_span, + format!( + "consider {}implementing `Clone` for this type", + if derive_clone { "manually " } else { "" } + ), + ); + format!("if `{ty}` implemented `Clone`, you could clone the value") + } else { + format!("if all bounds were met, you could clone the value") + }; span.push_span_label(expr.span, "you could clone this value"); - err.span_help( - span, - format!("if `{ty}` implemented `Clone`, you could clone the value"), - ); + err.span_note(span, msg); + if derive_clone { + err.help("consider manually implementing `Clone` to avoid undesired bounds"); + } } else if let ty::Param(param) = ty.kind() && let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() && let generics = self.infcx.tcx.generics_of(self.mir_def_id()) diff --git a/tests/ui/associated-types/issue-25700.stderr b/tests/ui/associated-types/issue-25700.stderr index 595aefc9a215..8d40e6905e07 100644 --- a/tests/ui/associated-types/issue-25700.stderr +++ b/tests/ui/associated-types/issue-25700.stderr @@ -8,7 +8,7 @@ LL | drop(t); LL | drop(t); | ^ value used here after move | -help: if `S<()>` implemented `Clone`, you could clone the value +note: if `S<()>` implemented `Clone`, you could clone the value --> $DIR/issue-25700.rs:1:1 | LL | struct S(#[allow(dead_code)] Option<&'static T>); diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr index a4d239090830..3fe1431fda71 100644 --- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr @@ -9,7 +9,7 @@ LL | LL | x.hello(); | - variable moved due to use in coroutine | -help: if `Ty` implemented `Clone`, you could clone the value +note: if `Ty` implemented `Clone`, you could clone the value --> $DIR/closure-shim-borrowck-error.rs:17:1 | LL | x.hello(); diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.stderr b/tests/ui/async-await/async-closures/move-out-of-ref.stderr index c516597c81f9..d443dc9d4831 100644 --- a/tests/ui/async-await/async-closures/move-out-of-ref.stderr +++ b/tests/ui/async-await/async-closures/move-out-of-ref.stderr @@ -7,7 +7,7 @@ LL | let c = async || { LL | *x; | ^^ `*x` is moved here | -help: if `Ty` implemented `Clone`, you could clone the value +note: if `Ty` implemented `Clone`, you could clone the value --> $DIR/move-out-of-ref.rs:5:1 | LL | struct Ty; diff --git a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr index 9eb90e169fd3..b4b60d40d914 100644 --- a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr +++ b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of static item `BAR` LL | test(BAR); | ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-out-of-static-item.rs:3:1 | LL | struct Foo { diff --git a/tests/ui/borrowck/borrowck-move-subcomponent.stderr b/tests/ui/borrowck/borrowck-move-subcomponent.stderr index 8dcb81273f89..b5dc01f180b2 100644 --- a/tests/ui/borrowck/borrowck-move-subcomponent.stderr +++ b/tests/ui/borrowck/borrowck-move-subcomponent.stderr @@ -10,7 +10,7 @@ LL | let S { x: ax } = a; LL | f(pb); | -- borrow later used here | -help: if `S` implemented `Clone`, you could clone the value +note: if `S` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-subcomponent.rs:6:1 | LL | struct S { diff --git a/tests/ui/borrowck/borrowck-overloaded-call.stderr b/tests/ui/borrowck/borrowck-overloaded-call.stderr index c838c6512bc4..c3b7b0b6080c 100644 --- a/tests/ui/borrowck/borrowck-overloaded-call.stderr +++ b/tests/ui/borrowck/borrowck-overloaded-call.stderr @@ -30,7 +30,7 @@ LL | s(" world".to_string()); LL | s(" world".to_string()); | ^ value used here after move | -help: if `SFnOnce` implemented `Clone`, you could clone the value +note: if `SFnOnce` implemented `Clone`, you could clone the value --> $DIR/borrowck-overloaded-call.rs:41:1 | LL | struct SFnOnce { diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr index 535550409dd8..72580e7464b7 100644 --- a/tests/ui/borrowck/clone-on-ref.stderr +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -59,7 +59,7 @@ LL | LL | println!("{b:?}"); | - borrow later used here | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/clone-on-ref.rs:19:1 | LL | struct A; diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.rs b/tests/ui/borrowck/derive-clone-implicit-bound.rs index 12fd2129331b..cd92ac1e9e59 100644 --- a/tests/ui/borrowck/derive-clone-implicit-bound.rs +++ b/tests/ui/borrowck/derive-clone-implicit-bound.rs @@ -2,11 +2,10 @@ use std::marker::PhantomData; -#[derive(Clone, Copy)] //~ NOTE derived `Clone` adds implicit bounds on type parameters +#[derive(Clone, Copy)] //~ NOTE: derived `Clone` adds implicit bounds on type parameters pub struct TypedAddress{ -//~^ HELP if `TypedAddress` implemented `Clone`, you could clone the value -//~| NOTE consider manually implementing `Clone` for this type -//~| NOTE introduces an implicit `T: Clone` bound +//~^ NOTE: if all bounds were met, you could clone the value +//~| NOTE: introduces an implicit `T: Clone` bound inner: u64, phantom: PhantomData, } @@ -14,18 +13,19 @@ pub struct TypedAddress{ pub trait Memory { fn write_value(&self, offset: TypedAddress, value: &T); fn return_value(&self, offset: TypedAddress) -> T; - //~^ NOTE consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary - //~| NOTE in this method - //~| NOTE this parameter takes ownership of the value + //~^ NOTE: consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary + //~| NOTE: in this method + //~| NOTE: this parameter takes ownership of the value fn update_value(&self, offset: TypedAddress, update: F) - //~^ NOTE move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait - where F: FnOnce(T) -> T //~ HELP consider further restricting type parameter `T` + //~^ NOTE: move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait + where F: FnOnce(T) -> T //~ HELP: consider further restricting type parameter `T` { - let old = self.return_value(offset); //~ NOTE value moved here - //~^ NOTE you could clone this value + let old = self.return_value(offset); //~ NOTE: value moved here + //~^ NOTE: you could clone this value let new = update(old); - self.write_value(offset, &new); //~ ERROR use of moved value: `offset` - //~^ NOTE value used here after move + self.write_value(offset, &new); //~ ERROR: use of moved value: `offset` + //~^ NOTE: value used here after move + //~| HELP: consider manually implementing `Clone` to avoid undesired bounds } } diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.stderr b/tests/ui/borrowck/derive-clone-implicit-bound.stderr index 31a55b448eb6..246fd1eaf075 100644 --- a/tests/ui/borrowck/derive-clone-implicit-bound.stderr +++ b/tests/ui/borrowck/derive-clone-implicit-bound.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `offset` - --> $DIR/derive-clone-implicit-bound.rs:27:26 + --> $DIR/derive-clone-implicit-bound.rs:26:26 | LL | fn update_value(&self, offset: TypedAddress, update: F) | ------ move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait @@ -11,23 +11,23 @@ LL | self.write_value(offset, &new); | ^^^^^^ value used here after move | note: consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary - --> $DIR/derive-clone-implicit-bound.rs:16:39 + --> $DIR/derive-clone-implicit-bound.rs:15:39 | LL | fn return_value(&self, offset: TypedAddress) -> T; | ------------ in this method ^^^^^^^^^^^^^^^ this parameter takes ownership of the value -help: if `TypedAddress` implemented `Clone`, you could clone the value +note: if all bounds were met, you could clone the value --> $DIR/derive-clone-implicit-bound.rs:6:1 | LL | #[derive(Clone, Copy)] | ----- derived `Clone` adds implicit bounds on type parameters LL | pub struct TypedAddress{ | ^^^^^^^^^^^^^^^^^^^^^^^^-^ - | | | - | | introduces an implicit `T: Clone` bound - | consider manually implementing `Clone` for this type + | | + | introduces an implicit `T: Clone` bound ... LL | let old = self.return_value(offset); | ------ you could clone this value + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `T` with trait `Copy` | LL | where F: FnOnce(T) -> T, T: Copy diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index 85769e187691..bd6c1c44bfb3 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -18,7 +18,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | async fn spawn_blocking(f: impl (Fn() -> T) + Send + Sync + 'static) -> T { | ^^^^^^^^^^^ -help: if `StructB` implemented `Clone`, you could clone the value +note: if `StructB` implemented `Clone`, you could clone the value --> $DIR/issue-103624.rs:23:1 | LL | self.b; diff --git a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr index a5a218a0641d..dde17d1f6523 100644 --- a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr +++ b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr @@ -11,7 +11,7 @@ note: `Example::::change` takes ownership of the receiver `self`, | LL | unsafe fn change(self) -> Example { | ^^^^ -help: if `Example` implemented `Clone`, you could clone the value +note: if `Example` implemented `Clone`, you could clone the value --> $DIR/issue-119915-bad-clone-suggestion.rs:3:1 | LL | struct Example(PhantomData<(fn(E), fn(FakeParam))>); diff --git a/tests/ui/borrowck/issue-17718-static-move.stderr b/tests/ui/borrowck/issue-17718-static-move.stderr index 959b1d1a3b84..057ac6d7e3df 100644 --- a/tests/ui/borrowck/issue-17718-static-move.stderr +++ b/tests/ui/borrowck/issue-17718-static-move.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of static item `FOO` LL | let _a = FOO; | ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/issue-17718-static-move.rs:1:1 | LL | struct Foo; diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr index 5336352e0dbd..5fda92634d8f 100644 --- a/tests/ui/borrowck/issue-20801.stderr +++ b/tests/ui/borrowck/issue-20801.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of a mutable reference LL | let a = unsafe { *mut_ref() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -help: if `T` implemented `Clone`, you could clone the value +note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -24,7 +24,7 @@ error[E0507]: cannot move out of a shared reference LL | let b = unsafe { *imm_ref() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -help: if `T` implemented `Clone`, you could clone the value +note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -44,7 +44,7 @@ error[E0507]: cannot move out of a raw pointer LL | let c = unsafe { *mut_ptr() }; | ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -help: if `T` implemented `Clone`, you could clone the value +note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); @@ -59,7 +59,7 @@ error[E0507]: cannot move out of a raw pointer LL | let d = unsafe { *const_ptr() }; | ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | -help: if `T` implemented `Clone`, you could clone the value +note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); diff --git a/tests/ui/borrowck/move-error-in-promoted-2.stderr b/tests/ui/borrowck/move-error-in-promoted-2.stderr index f2bc6bd4760a..1e9b1d5209cb 100644 --- a/tests/ui/borrowck/move-error-in-promoted-2.stderr +++ b/tests/ui/borrowck/move-error-in-promoted-2.stderr @@ -7,7 +7,7 @@ LL | &([S][0],); | cannot move out of here | move occurs because value has type `S`, which does not implement the `Copy` trait | -help: if `S` implemented `Clone`, you could clone the value +note: if `S` implemented `Clone`, you could clone the value --> $DIR/move-error-in-promoted-2.rs:3:1 | LL | struct S; diff --git a/tests/ui/borrowck/move-error-snippets.stderr b/tests/ui/borrowck/move-error-snippets.stderr index 3796b7e05fb4..97d140515184 100644 --- a/tests/ui/borrowck/move-error-snippets.stderr +++ b/tests/ui/borrowck/move-error-snippets.stderr @@ -9,7 +9,7 @@ LL | let a = $c; LL | sss!(); | ------ in this macro invocation | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-error-snippets.rs:9:1 | LL | struct A; diff --git a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr index af5cbdcf150f..009e85a8031e 100644 --- a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr +++ b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of a shared reference LL | static Y: usize = get(*&X); | ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); @@ -19,7 +19,7 @@ error[E0507]: cannot move out of a shared reference LL | const Z: usize = get(*&X); | ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); diff --git a/tests/ui/box/leak-alloc.stderr b/tests/ui/box/leak-alloc.stderr index f0d6dd3d4692..bdaa9449f913 100644 --- a/tests/ui/box/leak-alloc.stderr +++ b/tests/ui/box/leak-alloc.stderr @@ -12,7 +12,7 @@ LL | LL | use_value(*theref) | ------- borrow later used here | -help: if `Alloc` implemented `Clone`, you could clone the value +note: if `Alloc` implemented `Clone`, you could clone the value --> $DIR/leak-alloc.rs:8:1 | LL | struct Alloc {} diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs index b55c8c16f611..863bcedd01e6 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs @@ -1,16 +1,16 @@ //! regression test for -struct NoCopy; //~ HELP if `NoCopy` implemented `Clone`, you could clone the value -//~^ NOTE consider implementing `Clone` for this type +struct NoCopy; //~ NOTE: if `NoCopy` implemented `Clone`, you could clone the value +//~^ NOTE: consider implementing `Clone` for this type fn main() { let x = NoCopy; - //~^ NOTE move occurs because `x` has type `NoCopy` + //~^ NOTE: move occurs because `x` has type `NoCopy` let f = move || { - //~^ NOTE value moved into closure here + //~^ NOTE: value moved into closure here let y = x; - //~^ NOTE variable moved due to use in closure - //~| NOTE you could clone this value + //~^ NOTE: variable moved due to use in closure + //~| NOTE: you could clone this value }; let z = x; - //~^ ERROR use of moved value: `x` - //~| NOTE value used here after move + //~^ ERROR: use of moved value: `x` + //~| NOTE: value used here after move } diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr index bde39ca6ca71..94f80da1b10a 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr @@ -13,7 +13,7 @@ LL | let y = x; LL | let z = x; | ^ value used here after move | -help: if `NoCopy` implemented `Clone`, you could clone the value +note: if `NoCopy` implemented `Clone`, you could clone the value --> $DIR/closure-move-use-after-move-diagnostic.rs:2:1 | LL | struct NoCopy; diff --git a/tests/ui/coroutine/moved-twice.stderr b/tests/ui/coroutine/moved-twice.stderr index 561b3b331d9f..2b21f6c59f0b 100644 --- a/tests/ui/coroutine/moved-twice.stderr +++ b/tests/ui/coroutine/moved-twice.stderr @@ -10,7 +10,7 @@ LL | yield; LL | let second = first; | ^^^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/moved-twice.rs:9:1 | LL | struct Foo([u8; FOO_SIZE]); diff --git a/tests/ui/derives/deriving-with-repr-packed.stderr b/tests/ui/derives/deriving-with-repr-packed.stderr index 7c716fb9dd4c..9cfc4abdc0cb 100644 --- a/tests/ui/derives/deriving-with-repr-packed.stderr +++ b/tests/ui/derives/deriving-with-repr-packed.stderr @@ -7,7 +7,7 @@ LL | #[repr(packed)] LL | struct X(Y); | ^ move occurs because value has type `Y`, which does not implement the `Copy` trait | -help: if `Y` implemented `Clone`, you could clone the value +note: if `Y` implemented `Clone`, you could clone the value --> $DIR/deriving-with-repr-packed.rs:16:1 | LL | struct Y(usize); diff --git a/tests/ui/error-codes/E0504.stderr b/tests/ui/error-codes/E0504.stderr index 528f311765df..c4cbc834ad98 100644 --- a/tests/ui/error-codes/E0504.stderr +++ b/tests/ui/error-codes/E0504.stderr @@ -14,7 +14,7 @@ LL | println!("child function: {}", fancy_num.num); LL | println!("main function: {}", fancy_ref.num); | ------------- borrow later used here | -help: if `FancyNum` implemented `Clone`, you could clone the value +note: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0504.rs:2:1 | LL | struct FancyNum { diff --git a/tests/ui/error-codes/E0505.stderr b/tests/ui/error-codes/E0505.stderr index ac0f390bc54b..3f2913e9fe3c 100644 --- a/tests/ui/error-codes/E0505.stderr +++ b/tests/ui/error-codes/E0505.stderr @@ -11,7 +11,7 @@ LL | eat(x); LL | _ref_to_val.use_ref(); | ----------- borrow later used here | -help: if `Value` implemented `Clone`, you could clone the value +note: if `Value` implemented `Clone`, you could clone the value --> $DIR/E0505.rs:1:1 | LL | struct Value {} diff --git a/tests/ui/error-codes/E0507.stderr b/tests/ui/error-codes/E0507.stderr index ac03e5ea9cd5..70d99ea2cce5 100644 --- a/tests/ui/error-codes/E0507.stderr +++ b/tests/ui/error-codes/E0507.stderr @@ -11,7 +11,7 @@ note: `TheDarkKnight::nothing_is_true` takes ownership of the receiver `self`, w | LL | fn nothing_is_true(self) {} | ^^^^ -help: if `TheDarkKnight` implemented `Clone`, you could clone the value +note: if `TheDarkKnight` implemented `Clone`, you could clone the value --> $DIR/E0507.rs:3:1 | LL | struct TheDarkKnight; diff --git a/tests/ui/error-codes/E0508-fail.stderr b/tests/ui/error-codes/E0508-fail.stderr index 48ede17dc26a..fcfac399e0df 100644 --- a/tests/ui/error-codes/E0508-fail.stderr +++ b/tests/ui/error-codes/E0508-fail.stderr @@ -7,7 +7,7 @@ LL | let _value = array[0]; | cannot move out of here | move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508-fail.rs:1:1 | LL | struct NonCopy; diff --git a/tests/ui/error-codes/E0508.stderr b/tests/ui/error-codes/E0508.stderr index c001b9461ebf..b9fa0f4d17a5 100644 --- a/tests/ui/error-codes/E0508.stderr +++ b/tests/ui/error-codes/E0508.stderr @@ -7,7 +7,7 @@ LL | let _value = array[0]; | cannot move out of here | move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508.rs:1:1 | LL | struct NonCopy; diff --git a/tests/ui/error-codes/E0509.stderr b/tests/ui/error-codes/E0509.stderr index 89c3a5848423..628a253e0859 100644 --- a/tests/ui/error-codes/E0509.stderr +++ b/tests/ui/error-codes/E0509.stderr @@ -7,7 +7,7 @@ LL | let fancy_field = drop_struct.fancy; | cannot move out of here | move occurs because `drop_struct.fancy` has type `FancyNum`, which does not implement the `Copy` trait | -help: if `FancyNum` implemented `Clone`, you could clone the value +note: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0509.rs:1:1 | LL | struct FancyNum { diff --git a/tests/ui/mir/issue-102389.stderr b/tests/ui/mir/issue-102389.stderr index 7aafe081deaf..162d7ac031a6 100644 --- a/tests/ui/mir/issue-102389.stderr +++ b/tests/ui/mir/issue-102389.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of `*inbounds` which is behind a shared reference LL | array[*inbounds as usize] | ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait | -help: if `Enum` implemented `Clone`, you could clone the value +note: if `Enum` implemented `Clone`, you could clone the value --> $DIR/issue-102389.rs:1:1 | LL | enum Enum { A, B, C } diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.rs b/tests/ui/moves/issue-72649-uninit-in-loop.rs index 965a4206253e..f115656d7c0d 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.rs +++ b/tests/ui/moves/issue-72649-uninit-in-loop.rs @@ -3,10 +3,10 @@ // 'value moved in previous iteration of loop' message struct NonCopy; -//~^ HELP if `NonCopy` implemented `Clone` -//~| HELP if `NonCopy` implemented `Clone` -//~| HELP if `NonCopy` implemented `Clone` -//~| HELP if `NonCopy` implemented `Clone` +//~^ NOTE if `NonCopy` implemented `Clone` +//~| NOTE if `NonCopy` implemented `Clone` +//~| NOTE if `NonCopy` implemented `Clone` +//~| NOTE if `NonCopy` implemented `Clone` //~| NOTE consider implementing `Clone` for this type //~| NOTE consider implementing `Clone` for this type //~| NOTE consider implementing `Clone` for this type diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 1c54d3997ed6..8bde3b5c042d 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -10,7 +10,7 @@ LL | let _used = value; LL | let _used2 = value; | ^^^^^ value used here after move | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -33,7 +33,7 @@ LL | let _used = value; LL | let _used2 = value; | ^^^^^ value used here after move | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -53,7 +53,7 @@ LL | loop { LL | let _used = value; | ^^^^^ value moved here, in previous iteration of loop | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; @@ -73,7 +73,7 @@ LL | loop { LL | let _used2 = value; | ^^^^^ value moved here, in previous iteration of loop | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; diff --git a/tests/ui/moves/issue-75904-move-closure-loop.stderr b/tests/ui/moves/issue-75904-move-closure-loop.stderr index 3fc50c48315d..815e91b0f4df 100644 --- a/tests/ui/moves/issue-75904-move-closure-loop.stderr +++ b/tests/ui/moves/issue-75904-move-closure-loop.stderr @@ -11,7 +11,7 @@ LL | &mut a; LL | a; | - use occurs due to use in closure | -help: if `NotCopy` implemented `Clone`, you could clone the value +note: if `NotCopy` implemented `Clone`, you could clone the value --> $DIR/issue-75904-move-closure-loop.rs:5:1 | LL | struct NotCopy; diff --git a/tests/ui/moves/matching-partially-moved-value-17385.stderr b/tests/ui/moves/matching-partially-moved-value-17385.stderr index 83f4f4320485..906f7868bccb 100644 --- a/tests/ui/moves/matching-partially-moved-value-17385.stderr +++ b/tests/ui/moves/matching-partially-moved-value-17385.stderr @@ -8,7 +8,7 @@ LL | drop(foo); LL | match foo { | ^^^^^^^^^ value used here after move | -help: if `X` implemented `Clone`, you could clone the value +note: if `X` implemented `Clone`, you could clone the value --> $DIR/matching-partially-moved-value-17385.rs:2:1 | LL | struct X(isize); @@ -27,7 +27,7 @@ LL | drop(e); LL | match e { | ^ value used here after move | -help: if `Enum` implemented `Clone`, you could clone the value +note: if `Enum` implemented `Clone`, you could clone the value --> $DIR/matching-partially-moved-value-17385.rs:4:1 | LL | enum Enum { diff --git a/tests/ui/moves/move-fn-self-receiver.stderr b/tests/ui/moves/move-fn-self-receiver.stderr index b3a1215fa2f7..de19a99d388c 100644 --- a/tests/ui/moves/move-fn-self-receiver.stderr +++ b/tests/ui/moves/move-fn-self-receiver.stderr @@ -132,7 +132,7 @@ LL | foo_add + Foo; LL | foo_add; | ^^^^^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-fn-self-receiver.rs:5:1 | LL | struct Foo; diff --git a/tests/ui/moves/move-out-of-array-1.stderr b/tests/ui/moves/move-out-of-array-1.stderr index 7ef859200b21..8a030f021920 100644 --- a/tests/ui/moves/move-out-of-array-1.stderr +++ b/tests/ui/moves/move-out-of-array-1.stderr @@ -7,7 +7,7 @@ LL | a[i] | cannot move out of here | move occurs because `a[_]` has type `D`, which does not implement the `Copy` trait | -help: if `D` implemented `Clone`, you could clone the value +note: if `D` implemented `Clone`, you could clone the value --> $DIR/move-out-of-array-1.rs:5:1 | LL | struct D { _x: u8 } diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.stderr b/tests/ui/moves/moved-value-on-as-ref-arg.stderr index b553938c6fed..a99bdb4fe9d4 100644 --- a/tests/ui/moves/moved-value-on-as-ref-arg.stderr +++ b/tests/ui/moves/moved-value-on-as-ref-arg.stderr @@ -23,7 +23,7 @@ LL | qux(bar); LL | let _baa = bar; | ^^^ value used here after move | -help: if `Bar` implemented `Clone`, you could clone the value +note: if `Bar` implemented `Clone`, you could clone the value --> $DIR/moved-value-on-as-ref-arg.rs:5:1 | LL | struct Bar; @@ -61,7 +61,7 @@ LL | baz(bar); LL | let _baa = bar; | ^^^ value used here after move | -help: if `Bar` implemented `Clone`, you could clone the value +note: if `Bar` implemented `Clone`, you could clone the value --> $DIR/moved-value-on-as-ref-arg.rs:5:1 | LL | struct Bar; diff --git a/tests/ui/nll/issue-21232-partial-init-and-use.stderr b/tests/ui/nll/issue-21232-partial-init-and-use.stderr index 84c543921687..496a298a36ce 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/tests/ui/nll/issue-21232-partial-init-and-use.stderr @@ -28,7 +28,7 @@ LL | let mut s: S = S::new(); drop(s); LL | s.x = 10; s.y = Box::new(20); | ^^^^^^^^ value partially assigned here after move | -help: if `S>` implemented `Clone`, you could clone the value +note: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { @@ -82,7 +82,7 @@ LL | let mut s: S = S::new(); drop(s); LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move | -help: if `S>` implemented `Clone`, you could clone the value +note: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { diff --git a/tests/ui/nll/move-errors.stderr b/tests/ui/nll/move-errors.stderr index e84f75455217..bcb2ab84a239 100644 --- a/tests/ui/nll/move-errors.stderr +++ b/tests/ui/nll/move-errors.stderr @@ -4,7 +4,7 @@ error[E0507]: cannot move out of `*a` which is behind a shared reference LL | let b = *a; | ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -27,7 +27,7 @@ LL | let b = a[0]; | cannot move out of here | move occurs because `a[_]` has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -46,7 +46,7 @@ error[E0507]: cannot move out of `**r` which is behind a shared reference LL | let s = **r; | ^^^ move occurs because `**r` has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -66,7 +66,7 @@ error[E0507]: cannot move out of an `Rc` LL | let s = *r; | ^^ move occurs because value has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -89,7 +89,7 @@ LL | let a = [A("".to_string())][0]; | cannot move out of here | move occurs because value has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); @@ -137,7 +137,7 @@ error[E0507]: cannot move out of `*a` which is behind a shared reference LL | b = *a; | ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait | -help: if `A` implemented `Clone`, you could clone the value +note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); diff --git a/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr b/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr index f9bef8d83f96..cc438461a5d1 100644 --- a/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr +++ b/tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr @@ -8,7 +8,7 @@ LL | foo_pin_mut(&pin mut foo); LL | foo_move(foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -27,7 +27,7 @@ LL | let x = &pin mut foo; LL | foo_move(foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -46,7 +46,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_move(foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -65,7 +65,7 @@ LL | let x = &pin mut foo; // ok LL | foo_move(foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -87,7 +87,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -106,7 +106,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_ref(&foo); | ^^^^ value borrowed here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -125,7 +125,7 @@ LL | let x = &pin mut foo; // ok LL | foo_ref(&foo); | ^^^^ value borrowed here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -144,7 +144,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_pin_mut(&pin mut foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -163,7 +163,7 @@ LL | let x = &pin mut foo; // ok LL | foo_pin_mut(&pin mut foo); | ^^^ value used here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -185,7 +185,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -204,7 +204,7 @@ LL | foo_pin_mut(&pin mut foo); // ok LL | foo_pin_ref(&pin const foo); | ^^^^^^^^^^^^^^ value borrowed here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); @@ -223,7 +223,7 @@ LL | let x = &pin mut foo; // ok LL | foo_pin_ref(&pin const foo); | ^^^^^^^^^^^^^^ value borrowed here after move | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:16:1 | LL | struct Foo(PhantomPinned); diff --git a/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr b/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr index 523191655813..bf9921343ee7 100644 --- a/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr +++ b/tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr @@ -33,7 +33,7 @@ LL | LL | foo_pin_mut(x); // | - borrow later used here | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; @@ -55,7 +55,7 @@ LL | LL | foo_pin_mut(x); // | - borrow later used here | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; @@ -77,7 +77,7 @@ LL | LL | foo_pin_ref(x); | - borrow later used here | -help: if `Foo` implemented `Clone`, you could clone the value +note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrow-unpin.rs:20:1 | LL | struct Foo; diff --git a/tests/ui/pin-macro/pin_move.stderr b/tests/ui/pin-macro/pin_move.stderr index cf7d50091ba4..3f4660209885 100644 --- a/tests/ui/pin-macro/pin_move.stderr +++ b/tests/ui/pin-macro/pin_move.stderr @@ -8,7 +8,7 @@ LL | pin!(pointee); LL | let _moved = pointee; | ^^^^^^^ value used here after move | -help: if `a::NotCopy` implemented `Clone`, you could clone the value +note: if `a::NotCopy` implemented `Clone`, you could clone the value --> $DIR/pin_move.rs:7:5 | LL | struct NotCopy(T); @@ -23,7 +23,7 @@ error[E0507]: cannot move out of a mutable reference LL | pin!(*&mut pointee); | ^^^^^^^^^^^^^ move occurs because value has type `b::NotCopy`, which does not implement the `Copy` trait | -help: if `b::NotCopy` implemented `Clone`, you could clone the value +note: if `b::NotCopy` implemented `Clone`, you could clone the value --> $DIR/pin_move.rs:16:5 | LL | struct NotCopy(T); diff --git a/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr b/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr index 5e447a57bfee..62f24324fcc1 100644 --- a/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr +++ b/tests/ui/suggestions/non_copy_move_out_of_tuple.stderr @@ -7,7 +7,7 @@ LL | (b,) = *tuple; | data moved here | move occurs because the place has type `NonCopy`, which does not implement the `Copy` trait | -help: if `NonCopy` implemented `Clone`, you could clone the value +note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/non_copy_move_out_of_tuple.rs:3:1 | LL | struct NonCopy; diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr index cd13592d652e..f78d3cf67862 100644 --- a/tests/ui/suggestions/option-content-move3.stderr +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -10,7 +10,7 @@ LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait | = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once -help: if `NotCopyable` implemented `Clone`, you could clone the value +note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | LL | struct NotCopyable; @@ -43,7 +43,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | fn func H, H: FnMut()>(_: F) {} | ^^^^^^^^^^^^ -help: if `NotCopyable` implemented `Clone`, you could clone the value +note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | LL | struct NotCopyable; diff --git a/tests/ui/union/union-borrow-move-parent-sibling.stderr b/tests/ui/union/union-borrow-move-parent-sibling.stderr index 5974441dd807..461ee407e2dd 100644 --- a/tests/ui/union/union-borrow-move-parent-sibling.stderr +++ b/tests/ui/union/union-borrow-move-parent-sibling.stderr @@ -59,7 +59,7 @@ error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec, Moc LL | let a = (u.x.0).0; | ^^^^^^^^^ move occurs because value has type `MockVec`, which does not implement the `Copy` trait | -help: if `MockVec` implemented `Clone`, you could clone the value +note: if `MockVec` implemented `Clone`, you could clone the value --> $DIR/union-borrow-move-parent-sibling.rs:25:1 | LL | struct MockVec { diff --git a/tests/ui/union/union-move.stderr b/tests/ui/union/union-move.stderr index 6266bb4770e0..d520fb00ea9d 100644 --- a/tests/ui/union/union-move.stderr +++ b/tests/ui/union/union-move.stderr @@ -16,7 +16,7 @@ LL | fn move_out(x: T) {} | -------- ^ this parameter takes ownership of the value | | | in this function -help: if `U1` implemented `Clone`, you could clone the value +note: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { @@ -43,7 +43,7 @@ LL | fn move_out(x: T) {} | -------- ^ this parameter takes ownership of the value | | | in this function -help: if `U1` implemented `Clone`, you could clone the value +note: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr index 2a33a88bdd56..21d8de6ae881 100644 --- a/tests/ui/variance/variance-issue-20533.stderr +++ b/tests/ui/variance/variance-issue-20533.stderr @@ -10,7 +10,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -help: if `AffineU32` implemented `Clone`, you could clone the value +note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -31,7 +31,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -help: if `AffineU32` implemented `Clone`, you could clone the value +note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -52,7 +52,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -help: if `AffineU32` implemented `Clone`, you could clone the value +note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); @@ -73,7 +73,7 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -help: if `AffineU32` implemented `Clone`, you could clone the value +note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); From c95210f013cd0e607b4932cc841f90096037f191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Feb 2026 18:30:08 +0000 Subject: [PATCH 32/81] Do not suggest manual `impl Copy` --- .../src/error_reporting/traits/suggestions.rs | 2 +- tests/ui/associated-types/issue-38821.stderr | 1 - tests/ui/consts/const-blocks/trait-error.stderr | 1 - tests/ui/derives/deriving-copyclone.stderr | 2 -- tests/ui/generic-associated-types/impl_bounds.stderr | 2 -- 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 1880465eff54..764790a75bb4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3629,7 +3629,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } err.span_note(spans, msg); - if derived { + if derived && trait_name != "Copy" { err.help(format!( "consider manually implementing `{trait_name}` to avoid undesired \ bounds", diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index fae388c98d36..07b146f8bfca 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -159,7 +159,6 @@ LL | pub enum ColumnInsertValue where ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound - = help: consider manually implementing `Copy` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 853e10e0b35a..308d71f0f4bd 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -11,7 +11,6 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Foo(T); | ^^^ - type parameter would need to implement `Copy` - = help: consider manually implementing `Copy` to avoid undesired bounds = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block | diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index 40f96919121f..20a73ffdcfbf 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -13,7 +13,6 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct B { | ^ - type parameter would need to implement `Copy` - = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | @@ -65,7 +64,6 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct B { | ^ - type parameter would need to implement `Copy` - = help: consider manually implementing `Copy` to avoid undesired bounds note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index 63c4ba900829..65e1dff479e5 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -35,7 +35,6 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Fooy(T); | ^^^^ - type parameter would need to implement `Copy` - = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 | @@ -62,7 +61,6 @@ LL | #[derive(Copy, Clone)] | ---- in this derive macro expansion LL | struct Fooy(T); | ^^^^ - type parameter would need to implement `Copy` - = help: consider manually implementing `Copy` to avoid undesired bounds note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 | From 675656188786ebb1444b5ea7baece40d8afa51ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Feb 2026 18:31:21 +0000 Subject: [PATCH 33/81] fix test after rebase --- .../derive-clone-already-present-issue-146515.rs | 5 ++--- .../derive-clone-already-present-issue-146515.stderr | 11 ++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs b/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs index 083d73711a51..78b4c017251e 100644 --- a/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs +++ b/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs @@ -2,8 +2,8 @@ use std::rc::Rc; -#[derive(Clone)] -struct ContainsRc { +#[derive(Clone)] //~ NOTE in this expansion +struct ContainsRc { //~ NOTE derive introduces an implicit `T: Clone` bound value: Rc, } @@ -14,7 +14,6 @@ fn clone_me(x: &ContainsRc) -> ContainsRc { //~| NOTE expected `ContainsRc`, found `&ContainsRc` //~| NOTE expected struct `ContainsRc<_>` //~| NOTE `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead - //~| NOTE the trait `Clone` must be implemented } fn main() {} diff --git a/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr b/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr index 516ef38f668d..6ecf4e7ca943 100644 --- a/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr +++ b/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr @@ -14,9 +14,14 @@ note: `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned | LL | x.clone() | ^ - = help: `Clone` is not implemented because the trait bound `T: Clone` is not satisfied -note: the trait `Clone` must be implemented - --> $SRC_DIR/core/src/clone.rs:LL:COL +help: `Clone` is not implemented because a trait bound is not satisfied + --> $DIR/derive-clone-already-present-issue-146515.rs:6:19 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRc { + | ^ derive introduces an implicit `T: Clone` bound + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds error: aborting due to 1 previous error From b5d9b7f6837e50d8984275f11704d8c7f8493923 Mon Sep 17 00:00:00 2001 From: usamoi Date: Sun, 1 Feb 2026 22:34:46 +0800 Subject: [PATCH 34/81] escape symbol names in global asm --- compiler/rustc_codegen_llvm/src/asm.rs | 45 ++++++++++++++++++++++-- tests/ui/asm/x86_64/global_asm_escape.rs | 17 +++++++++ tests/ui/asm/x86_64/naked_asm_escape.rs | 32 +++++++++++++++++ 3 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 tests/ui/asm/x86_64/global_asm_escape.rs create mode 100644 tests/ui/asm/x86_64/naked_asm_escape.rs diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 7f02518d6c0d..fd25fba2daac 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -399,7 +399,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { for piece in template { match *piece { InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s), - InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => { + InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => { match operands[operand_idx] { GlobalAsmOperandRef::Const { ref string } => { // Const operands get injected directly into the @@ -414,7 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::LLVMRustGetMangledName(llval, s); }) .expect("symbol is not valid UTF-8"); - template_str.push_str(&symbol); + template_str.push_str(&escape_symbol_name(self, symbol, span)); } GlobalAsmOperandRef::SymStatic { def_id } => { let llval = self @@ -428,7 +428,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::LLVMRustGetMangledName(llval, s); }) .expect("symbol is not valid UTF-8"); - template_str.push_str(&symbol); + template_str.push_str(&escape_symbol_name(self, symbol, span)); } } } @@ -1390,3 +1390,42 @@ fn llvm_fixup_output_type<'ll, 'tcx>( _ => layout.llvm_type(cx), } } + +fn escape_symbol_name<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, symbol: String, span: Span) -> String { + use rustc_target::spec::{Arch, BinaryFormat}; + if !symbol.is_empty() + && symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.')) + { + return symbol; + } + if cx.tcx.sess.target.binary_format == BinaryFormat::Xcoff { + cx.tcx.sess.dcx().span_fatal( + span, + format!( + "symbol escaping is not supported for the binary format {}", + cx.tcx.sess.target.binary_format + ), + ); + } + if cx.tcx.sess.target.arch == Arch::Nvptx64 { + cx.tcx.sess.dcx().span_fatal( + span, + format!( + "symbol escaping is not supported for the architecture {}", + cx.tcx.sess.target.arch + ), + ); + } + let mut escaped_symbol = String::new(); + escaped_symbol.push('\"'); + for c in symbol.chars() { + match c { + '\n' => escaped_symbol.push_str("\\\n"), + '"' => escaped_symbol.push_str("\\\""), + '\\' => escaped_symbol.push_str("\\\\"), + c => escaped_symbol.push(c), + } + } + escaped_symbol.push('\"'); + escaped_symbol +} diff --git a/tests/ui/asm/x86_64/global_asm_escape.rs b/tests/ui/asm/x86_64/global_asm_escape.rs new file mode 100644 index 000000000000..59214e958a85 --- /dev/null +++ b/tests/ui/asm/x86_64/global_asm_escape.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ only-x86_64-unknown-linux-gnu +//@ ignore-backends: gcc + +// https://github.com/rust-lang/rust/issues/151950 + +unsafe extern "C" { + #[link_name = "exit@GLIBC_2.2.5"] + safe fn exit(status: i32) -> !; + safe fn my_exit(status: i32) -> !; +} + +core::arch::global_asm!(".global my_exit", "my_exit:", "jmp {}", sym exit); + +fn main() { + my_exit(0); +} diff --git a/tests/ui/asm/x86_64/naked_asm_escape.rs b/tests/ui/asm/x86_64/naked_asm_escape.rs new file mode 100644 index 000000000000..57962993ef91 --- /dev/null +++ b/tests/ui/asm/x86_64/naked_asm_escape.rs @@ -0,0 +1,32 @@ +//@ build-fail +//@ only-x86_64-unknown-linux-gnu +//@ dont-check-compiler-stderr +//@ dont-check-compiler-stdout +//@ ignore-backends: gcc + +// https://github.com/rust-lang/rust/issues/151950 + +unsafe extern "C" { + #[link_name = "memset]; mov eax, 1; #"] + unsafe fn inject(); +} + +#[unsafe(export_name = "memset]; mov eax, 1; #")] +extern "C" fn inject_() {} + +#[unsafe(naked)] +extern "C" fn print_0() -> usize { + core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject) +} + +#[unsafe(naked)] +extern "C" fn print_1() -> usize { + core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject_) +} + +fn main() { + dbg!(print_0()); + dbg!(print_1()); +} + +//~? ERROR linking From 821f139a2903af53734b8359145edb426bc3f4a9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 2 Feb 2026 10:51:20 +0100 Subject: [PATCH 35/81] Revert "Revert "Use LLVM intrinsics for `madd` intrinsics"" --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 36 +++++------ .../crates/core_arch/src/x86/avx512bw.rs | 64 +++++++++---------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 26 +++++--- 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index e9463d433180..83aef753c9d9 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -1841,14 +1841,20 @@ pub const fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16())); - let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]); - let odd: i32x8 = simd_shuffle!(r, r, [1, 3, 5, 7, 9, 11, 13, 15]); - simd_add(even, odd).as_m256i() - } +pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx2")] + // unsafe fn widening_add(mad: __m256i) -> __m256i { + // _mm256_madd_epi16(mad, _mm256_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x16(), b.as_i16x16())) } } /// Vertically multiplies each unsigned 8-bit integer from `a` with the @@ -3813,6 +3819,8 @@ pub const fn _mm256_extract_epi16(a: __m256i) -> i32 { #[allow(improper_ctypes)] unsafe extern "C" { + #[link_name = "llvm.x86.avx2.pmadd.wd"] + fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; #[link_name = "llvm.x86.avx2.pmadd.ub.sw"] fn pmaddubsw(a: u8x32, b: i8x32) -> i16x16; #[link_name = "llvm.x86.avx2.mpsadbw"] @@ -4661,7 +4669,7 @@ mod tests { } #[simd_test(enable = "avx2")] - const fn test_mm256_madd_epi16() { + fn test_mm256_madd_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_madd_epi16(a, b); @@ -4669,16 +4677,6 @@ mod tests { assert_eq_m256i(r, e); } - #[target_feature(enable = "avx2")] - #[cfg_attr(test, assert_instr(vpmaddwd))] - unsafe fn test_mm256_madd_epi16_mul_one(mad: __m256i) -> __m256i { - // This is a trick used in the adler32 algorithm to get a widening addition. The - // multiplication by 1 is trivial, but must not be optimized out because then the vpmaddwd - // instruction is no longer selected. The assert_instr verifies that this is the case. - let one_v = _mm256_set1_epi16(1); - _mm256_madd_epi16(mad, one_v) - } - #[simd_test(enable = "avx2")] const fn test_mm256_inserti128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index e2d12cd97264..8e074fdcfa48 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6321,22 +6321,20 @@ pub const unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32())); - let even: i32x16 = simd_shuffle!( - r, - r, - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] - ); - let odd: i32x16 = simd_shuffle!( - r, - r, - [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] - ); - simd_add(even, odd).as_m512i() - } +pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx512bw")] + // unsafe fn widening_add(mad: __m512i) -> __m512i { + // _mm512_madd_epi16(mad, _mm512_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(vpmaddwd(a.as_i16x32(), b.as_i16x32())) } } /// Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6346,8 +6344,7 @@ pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, src.as_i32x16())) @@ -6361,8 +6358,7 @@ pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: _ #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, i32x16::ZERO)) @@ -6376,8 +6372,7 @@ pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, src.as_i32x8())) @@ -6391,8 +6386,7 @@ pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, i32x8::ZERO)) @@ -6406,8 +6400,7 @@ pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, src.as_i32x4())) @@ -6421,8 +6414,7 @@ pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m12 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +pub fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, i32x4::ZERO)) @@ -12582,6 +12574,8 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"] fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32; + #[link_name = "llvm.x86.avx512.pmaddw.d.512"] + fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16; #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; @@ -17506,7 +17500,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_madd_epi16() { + fn test_mm512_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_madd_epi16(a, b); @@ -17515,7 +17509,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_mask_madd_epi16() { + fn test_mm512_mask_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_madd_epi16(a, 0, a, b); @@ -17543,7 +17537,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_maskz_madd_epi16() { + fn test_mm512_maskz_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_madd_epi16(0, a, b); @@ -17554,7 +17548,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm256_mask_madd_epi16() { + fn test_mm256_mask_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_madd_epi16(a, 0, a, b); @@ -17574,7 +17568,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm256_maskz_madd_epi16() { + fn test_mm256_maskz_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_madd_epi16(0, a, b); @@ -17585,7 +17579,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm_mask_madd_epi16() { + fn test_mm_mask_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_madd_epi16(a, 0, a, b); @@ -17596,7 +17590,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm_maskz_madd_epi16() { + fn test_mm_maskz_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_madd_epi16(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index ecd478511b06..f339a003df4d 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -210,14 +210,20 @@ pub const fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8())); - let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]); - let odd: i32x4 = simd_shuffle!(r, r, [1, 3, 5, 7]); - simd_add(even, odd).as_m128i() - } +pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "sse2")] + // unsafe fn widening_add(mad: __m128i) -> __m128i { + // _mm_madd_epi16(mad, _mm_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `pmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -3187,6 +3193,8 @@ unsafe extern "C" { fn lfence(); #[link_name = "llvm.x86.sse2.mfence"] fn mfence(); + #[link_name = "llvm.x86.sse2.pmadd.wd"] + fn pmaddwd(a: i16x8, b: i16x8) -> i32x4; #[link_name = "llvm.x86.sse2.psad.bw"] fn psadbw(a: u8x16, b: u8x16) -> u64x2; #[link_name = "llvm.x86.sse2.psll.w"] @@ -3465,7 +3473,7 @@ mod tests { } #[simd_test(enable = "sse2")] - const fn test_mm_madd_epi16() { + fn test_mm_madd_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm_madd_epi16(a, b); From 54641efc6839b75405d19dbe20150985df0fbb8d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 2 Feb 2026 17:01:10 +0100 Subject: [PATCH 36/81] add `vpmaddwd` tests back in --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 83aef753c9d9..04a88e461f75 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -4677,6 +4677,26 @@ mod tests { assert_eq_m256i(r, e); } + #[target_feature(enable = "avx2")] + #[cfg_attr(test, assert_instr(vpmaddwd))] + unsafe fn test_mm256_madd_epi16_mul_one(v: __m256i) -> __m256i { + // This is a trick used in the adler32 algorithm to get a widening addition. The + // multiplication by 1 is trivial, but must not be optimized out because then the vpmaddwd + // instruction is no longer selected. The assert_instr verifies that this is the case. + let one_v = _mm256_set1_epi16(1); + _mm256_madd_epi16(v, one_v) + } + + #[target_feature(enable = "avx2")] + #[cfg_attr(test, assert_instr(vpmaddwd))] + unsafe fn test_mm256_madd_epi16_shl(v: __m256i) -> __m256i { + // This is a trick used in the base64 algorithm to get a widening addition. Instead of a + // multiplication, a vector shl is used. In LLVM 22 that breaks the pattern recognition + // for the automatic optimization to vpmaddwd. + let shift_value = _mm256_set1_epi32(12i32); + _mm256_madd_epi16(v, shift_value) + } + #[simd_test(enable = "avx2")] const fn test_mm256_inserti128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); From d9516977cdb8b03c21231af19f6bb7a12d821bbc Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 3 Feb 2026 20:37:23 +1100 Subject: [PATCH 37/81] Tidy up re-exports in `rustc_middle::dep_graph` --- compiler/rustc_middle/src/dep_graph/dep_node.rs | 6 ++---- compiler/rustc_middle/src/dep_graph/mod.rs | 9 +++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index f5ed0570667c..834f6b16c29a 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -2,10 +2,8 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; use rustc_hir::definitions::DefPathHash; use rustc_hir::{HirId, ItemLocalId, OwnerId}; -pub use rustc_query_system::dep_graph::DepNode; -use rustc_query_system::dep_graph::FingerprintStyle; -pub use rustc_query_system::dep_graph::dep_node::DepKind; -pub(crate) use rustc_query_system::dep_graph::{DepContext, DepNodeParams}; +use rustc_query_system::dep_graph::dep_node::DepKind; +use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams, FingerprintStyle}; use rustc_span::Symbol; use crate::mir::mono::MonoItem; diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index f28ba10d52e2..08b0fada0c06 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -8,14 +8,15 @@ use crate::ty::{self, TyCtxt}; #[macro_use] mod dep_node; -pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kind_from_label, dep_kinds, label_strs}; -pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata}; pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter}; pub use rustc_query_system::dep_graph::{ - DepContext, DepGraphQuery, DepNodeIndex, Deps, SerializedDepGraph, SerializedDepNodeIndex, - TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result, + DepContext, DepGraphQuery, DepKind, DepNode, DepNodeIndex, Deps, SerializedDepGraph, + SerializedDepNodeIndex, TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result, }; +pub use self::dep_node::{DepNodeExt, dep_kind_from_label, dep_kinds, label_strs}; +pub(crate) use self::dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata}; + pub type DepGraph = rustc_query_system::dep_graph::DepGraph; pub type DepKindVTable<'tcx> = rustc_query_system::dep_graph::DepKindVTable>; From 7b01330133c134a29dca3f9abd42e6ba92df4561 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 3 Feb 2026 20:39:03 +1100 Subject: [PATCH 38/81] Move trait impls into a `dep_node_key` submodule --- .../rustc_middle/src/dep_graph/dep_node.rs | 226 +---------------- .../src/dep_graph/dep_node_key.rs | 228 ++++++++++++++++++ compiler/rustc_middle/src/dep_graph/mod.rs | 1 + 3 files changed, 231 insertions(+), 224 deletions(-) create mode 100644 compiler/rustc_middle/src/dep_graph/dep_node_key.rs diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 834f6b16c29a..5f90d1b67d9d 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -1,9 +1,7 @@ -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; +use rustc_hir::def_id::DefId; use rustc_hir::definitions::DefPathHash; -use rustc_hir::{HirId, ItemLocalId, OwnerId}; use rustc_query_system::dep_graph::dep_node::DepKind; -use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams, FingerprintStyle}; +use rustc_query_system::dep_graph::{DepContext, DepNode, FingerprintStyle}; use rustc_span::Symbol; use crate::mir::mono::MonoItem; @@ -174,223 +172,3 @@ pub fn dep_kind_from_label(label: &str) -> DepKind { dep_kind_from_label_string(label) .unwrap_or_else(|_| panic!("Query label {label} does not exist")) } - -impl<'tcx> DepNodeParams> for () { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::Unit - } - - #[inline(always)] - fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint { - Fingerprint::ZERO - } - - #[inline(always)] - fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option { - Some(()) - } -} - -impl<'tcx> DepNodeParams> for DefId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - tcx.def_path_hash(*self).0 - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - tcx.def_path_str(*self) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx) - } -} - -impl<'tcx> DepNodeParams> for LocalDefId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - self.to_def_id().to_fingerprint(tcx) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - self.to_def_id().to_debug_str(tcx) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| id.expect_local()) - } -} - -impl<'tcx> DepNodeParams> for OwnerId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - self.to_def_id().to_fingerprint(tcx) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - self.to_def_id().to_debug_str(tcx) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() }) - } -} - -impl<'tcx> DepNodeParams> for CrateNum { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - let def_id = self.as_def_id(); - def_id.to_fingerprint(tcx) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - tcx.crate_name(*self).to_string() - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| id.krate) - } -} - -impl<'tcx> DepNodeParams> for (DefId, DefId) { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::Opaque - } - - // We actually would not need to specialize the implementation of this - // method but it's faster to combine the hashes than to instantiate a full - // hashing context and stable-hashing state. - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - let (def_id_0, def_id_1) = *self; - - let def_path_hash_0 = tcx.def_path_hash(def_id_0); - let def_path_hash_1 = tcx.def_path_hash(def_id_1); - - def_path_hash_0.0.combine(def_path_hash_1.0) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - let (def_id_0, def_id_1) = *self; - - format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1)) - } -} - -impl<'tcx> DepNodeParams> for HirId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::HirId - } - - // We actually would not need to specialize the implementation of this - // method but it's faster to combine the hashes than to instantiate a full - // hashing context and stable-hashing state. - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - let HirId { owner, local_id } = *self; - let def_path_hash = tcx.def_path_hash(owner.to_def_id()); - Fingerprint::new( - // `owner` is local, so is completely defined by the local hash - def_path_hash.local_hash(), - local_id.as_u32() as u64, - ) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - let HirId { owner, local_id } = *self; - format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32()) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { - let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split(); - let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash); - let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local(); - let local_id = local_id - .as_u64() - .try_into() - .unwrap_or_else(|_| panic!("local id should be u32, found {local_id:?}")); - Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) }) - } else { - None - } - } -} - -impl<'tcx> DepNodeParams> for ModDefId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - self.to_def_id().to_fingerprint(tcx) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - self.to_def_id().to_debug_str(tcx) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked) - } -} - -impl<'tcx> DepNodeParams> for LocalModDefId { - #[inline(always)] - fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::DefPathHash - } - - #[inline(always)] - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - self.to_def_id().to_fingerprint(tcx) - } - - #[inline(always)] - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { - self.to_def_id().to_debug_str(tcx) - } - - #[inline(always)] - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked) - } -} diff --git a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs new file mode 100644 index 000000000000..7574fc7e4a7b --- /dev/null +++ b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs @@ -0,0 +1,228 @@ +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; +use rustc_hir::definitions::DefPathHash; +use rustc_hir::{HirId, ItemLocalId, OwnerId}; +use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams, FingerprintStyle}; + +use crate::dep_graph::DepNodeExt; +use crate::ty::TyCtxt; + +impl<'tcx> DepNodeParams> for () { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Unit + } + + #[inline(always)] + fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint { + Fingerprint::ZERO + } + + #[inline(always)] + fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option { + Some(()) + } +} + +impl<'tcx> DepNodeParams> for DefId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + tcx.def_path_hash(*self).0 + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + tcx.def_path_str(*self) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx) + } +} + +impl<'tcx> DepNodeParams> for LocalDefId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + self.to_def_id().to_fingerprint(tcx) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + self.to_def_id().to_debug_str(tcx) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|id| id.expect_local()) + } +} + +impl<'tcx> DepNodeParams> for OwnerId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + self.to_def_id().to_fingerprint(tcx) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + self.to_def_id().to_debug_str(tcx) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() }) + } +} + +impl<'tcx> DepNodeParams> for CrateNum { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + let def_id = self.as_def_id(); + def_id.to_fingerprint(tcx) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + tcx.crate_name(*self).to_string() + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|id| id.krate) + } +} + +impl<'tcx> DepNodeParams> for (DefId, DefId) { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque + } + + // We actually would not need to specialize the implementation of this + // method but it's faster to combine the hashes than to instantiate a full + // hashing context and stable-hashing state. + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + let (def_id_0, def_id_1) = *self; + + let def_path_hash_0 = tcx.def_path_hash(def_id_0); + let def_path_hash_1 = tcx.def_path_hash(def_id_1); + + def_path_hash_0.0.combine(def_path_hash_1.0) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + let (def_id_0, def_id_1) = *self; + + format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1)) + } +} + +impl<'tcx> DepNodeParams> for HirId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::HirId + } + + // We actually would not need to specialize the implementation of this + // method but it's faster to combine the hashes than to instantiate a full + // hashing context and stable-hashing state. + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + let HirId { owner, local_id } = *self; + let def_path_hash = tcx.def_path_hash(owner.to_def_id()); + Fingerprint::new( + // `owner` is local, so is completely defined by the local hash + def_path_hash.local_hash(), + local_id.as_u32() as u64, + ) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + let HirId { owner, local_id } = *self; + format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32()) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { + let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split(); + let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash); + let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local(); + let local_id = local_id + .as_u64() + .try_into() + .unwrap_or_else(|_| panic!("local id should be u32, found {local_id:?}")); + Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) }) + } else { + None + } + } +} + +impl<'tcx> DepNodeParams> for ModDefId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + self.to_def_id().to_fingerprint(tcx) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + self.to_def_id().to_debug_str(tcx) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked) + } +} + +impl<'tcx> DepNodeParams> for LocalModDefId { + #[inline(always)] + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash + } + + #[inline(always)] + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { + self.to_def_id().to_fingerprint(tcx) + } + + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + self.to_def_id().to_debug_str(tcx) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked) + } +} diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 08b0fada0c06..1056fa9b4462 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -7,6 +7,7 @@ use crate::ty::{self, TyCtxt}; #[macro_use] mod dep_node; +mod dep_node_key; pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter}; pub use rustc_query_system::dep_graph::{ From 4429f0916cef234bf83327c020becd3c66e5834b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 3 Feb 2026 20:41:37 +1100 Subject: [PATCH 39/81] Rename trait `DepNodeParams` to `DepNodeKey` --- .../src/dep_graph/dep_node_key.rs | 20 +++++++++---------- compiler/rustc_middle/src/query/inner.rs | 4 ++-- compiler/rustc_query_impl/src/plumbing.rs | 2 +- .../src/dep_graph/dep_node.rs | 19 ++++++++++-------- .../rustc_query_system/src/dep_graph/mod.rs | 2 +- .../src/query/dispatcher.rs | 4 ++-- .../rustc_query_system/src/query/plumbing.rs | 2 +- compiler/rustc_span/src/def_id.rs | 2 +- 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs index 7574fc7e4a7b..e2fcd82c896a 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs @@ -2,12 +2,12 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; use rustc_hir::definitions::DefPathHash; use rustc_hir::{HirId, ItemLocalId, OwnerId}; -use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams, FingerprintStyle}; +use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeKey, FingerprintStyle}; use crate::dep_graph::DepNodeExt; use crate::ty::TyCtxt; -impl<'tcx> DepNodeParams> for () { +impl<'tcx> DepNodeKey> for () { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::Unit @@ -24,7 +24,7 @@ impl<'tcx> DepNodeParams> for () { } } -impl<'tcx> DepNodeParams> for DefId { +impl<'tcx> DepNodeKey> for DefId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash @@ -46,7 +46,7 @@ impl<'tcx> DepNodeParams> for DefId { } } -impl<'tcx> DepNodeParams> for LocalDefId { +impl<'tcx> DepNodeKey> for LocalDefId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash @@ -68,7 +68,7 @@ impl<'tcx> DepNodeParams> for LocalDefId { } } -impl<'tcx> DepNodeParams> for OwnerId { +impl<'tcx> DepNodeKey> for OwnerId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash @@ -90,7 +90,7 @@ impl<'tcx> DepNodeParams> for OwnerId { } } -impl<'tcx> DepNodeParams> for CrateNum { +impl<'tcx> DepNodeKey> for CrateNum { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash @@ -113,7 +113,7 @@ impl<'tcx> DepNodeParams> for CrateNum { } } -impl<'tcx> DepNodeParams> for (DefId, DefId) { +impl<'tcx> DepNodeKey> for (DefId, DefId) { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::Opaque @@ -140,7 +140,7 @@ impl<'tcx> DepNodeParams> for (DefId, DefId) { } } -impl<'tcx> DepNodeParams> for HirId { +impl<'tcx> DepNodeKey> for HirId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::HirId @@ -183,7 +183,7 @@ impl<'tcx> DepNodeParams> for HirId { } } -impl<'tcx> DepNodeParams> for ModDefId { +impl<'tcx> DepNodeKey> for ModDefId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash @@ -205,7 +205,7 @@ impl<'tcx> DepNodeParams> for ModDefId { } } -impl<'tcx> DepNodeParams> for LocalModDefId { +impl<'tcx> DepNodeKey> for LocalModDefId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { FingerprintStyle::DefPathHash diff --git a/compiler/rustc_middle/src/query/inner.rs b/compiler/rustc_middle/src/query/inner.rs index bc0b34b67f12..32fe0737ec12 100644 --- a/compiler/rustc_middle/src/query/inner.rs +++ b/compiler/rustc_middle/src/query/inner.rs @@ -1,7 +1,7 @@ //! Helper functions that serve as the immediate implementation of //! `tcx.$query(..)` and its variations. -use rustc_query_system::dep_graph::{DepKind, DepNodeParams}; +use rustc_query_system::dep_graph::{DepKind, DepNodeKey}; use rustc_query_system::query::{QueryCache, QueryMode, try_get_cached}; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; @@ -86,7 +86,7 @@ pub(crate) fn query_feed<'tcx, Cache>( value: Cache::Value, ) where Cache: QueryCache, - Cache::Key: DepNodeParams>, + Cache::Key: DepNodeKey>, { let format_value = query_vtable.format_value; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index d1721f1f455f..a7fde9e3ca9a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_query_system::dep_graph::{DepNodeParams, FingerprintStyle, HasDepContext}; +use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index b9d35bc5a937..e18483d0b435 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -124,7 +124,7 @@ impl DepNode { pub fn construct(tcx: Tcx, kind: DepKind, arg: &Key) -> DepNode where Tcx: super::DepContext, - Key: DepNodeParams, + Key: DepNodeKey, { let hash = arg.to_fingerprint(tcx); let dep_node = DepNode { kind, hash: hash.into() }; @@ -167,13 +167,15 @@ impl fmt::Debug for DepNode { } } -pub trait DepNodeParams: fmt::Debug + Sized { +/// Trait for query keys as seen by dependency-node tracking. +pub trait DepNodeKey: fmt::Debug + Sized { fn fingerprint_style() -> FingerprintStyle; - /// This method turns the parameters of a DepNodeConstructor into an opaque - /// Fingerprint to be used in DepNode. - /// Not all DepNodeParams support being turned into a Fingerprint (they - /// don't need to if the corresponding DepNode is anonymous). + /// This method turns a query key into an opaque `Fingerprint` to be used + /// in `DepNode`. + /// + /// Not all `DepNodeKey` impls support being turned into a `Fingerprint` + /// (they don't need to if the corresponding `DepNode` is anonymous). fn to_fingerprint(&self, _: Tcx) -> Fingerprint { panic!("Not implemented. Accidentally called on anonymous node?") } @@ -189,7 +191,8 @@ pub trait DepNodeParams: fmt::Debug + Sized { fn recover(tcx: Tcx, dep_node: &DepNode) -> Option; } -impl DepNodeParams for T +// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere. +impl DepNodeKey for T where T: for<'a> HashStable> + fmt::Debug, { @@ -239,7 +242,7 @@ pub struct DepKindVTable { /// Indicates whether and how the query key can be recovered from its hashed fingerprint. /// - /// The [`DepNodeParams`] trait determines the fingerprint style for each key type. + /// The [`DepNodeKey`] trait determines the fingerprint style for each key type. pub fingerprint_style: FingerprintStyle, /// The red/green evaluation system will try to mark a specific DepNode in the diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index c3ac1c7bc2d5..f2cb01d5e9b4 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -7,7 +7,7 @@ mod serialized; use std::panic; -pub use dep_node::{DepKind, DepKindVTable, DepNode, DepNodeParams, WorkProductId}; +pub use dep_node::{DepKind, DepKindVTable, DepNode, DepNodeKey, WorkProductId}; pub(crate) use graph::DepGraphData; pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result}; pub use query::DepGraphQuery; diff --git a/compiler/rustc_query_system/src/query/dispatcher.rs b/compiler/rustc_query_system/src/query/dispatcher.rs index bcd3d0322d07..840b09024ffa 100644 --- a/compiler/rustc_query_system/src/query/dispatcher.rs +++ b/compiler/rustc_query_system/src/query/dispatcher.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_span::ErrorGuaranteed; use super::QueryStackFrameExtra; -use crate::dep_graph::{DepKind, DepNode, DepNodeParams, HasDepContext, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepNode, DepNodeKey, HasDepContext, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; use crate::query::{CycleError, CycleErrorHandling, DepNodeIndex, QueryContext, QueryState}; @@ -33,7 +33,7 @@ pub trait QueryDispatcher<'tcx>: Copy + 'tcx { // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap, // but it isn't necessary. - type Key: DepNodeParams> + Eq + Hash + Copy + Debug; + type Key: DepNodeKey> + Eq + Hash + Copy + Debug; type Value: Copy; type Cache: QueryCache; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index fcd2e80a4fdc..32c4f6e1c847 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -18,7 +18,7 @@ use tracing::instrument; use super::{QueryDispatcher, QueryStackDeferred, QueryStackFrameExtra}; use crate::dep_graph::{ - DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams, HasDepContext, + DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeKey, HasDepContext, }; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index a0ccf8d7e798..82d455ab54f0 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -540,7 +540,7 @@ macro_rules! typed_def_id { } // N.B.: when adding new typed `DefId`s update the corresponding trait impls in -// `rustc_middle::dep_graph::def_node` for `DepNodeParams`. +// `rustc_middle::dep_graph::dep_node_key` for `DepNodeKey`. typed_def_id! { ModDefId, LocalModDefId } impl LocalModDefId { From f2fff8ee547b36dd96209a8d7d77635105a3352f Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Wed, 4 Feb 2026 07:02:48 +0000 Subject: [PATCH 40/81] Port reexport_test_harness_main. --- .../src/attributes/test_attrs.rs | 27 ++++ compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 +- .../issue-43106-gating-of-builtin-attrs.rs | 12 +- ...issue-43106-gating-of-builtin-attrs.stderr | 141 ++++++++++-------- 7 files changed, 115 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index ec7cdd3624dc..236d10d77b92 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -113,3 +113,30 @@ impl NoArgsAttributeParser for RustcVarianceOfOpaquesParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques; } + +pub(crate) struct ReexportTestHarnessMainParser; + +impl SingleAttributeParser for ReexportTestHarnessMainParser { + const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value( + args.span().unwrap_or(cx.inner_span), + Some(sym::reexport_test_harness_main), + ); + return None; + }; + + let Some(name) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + Some(AttributeKind::ReexportTestHarnessMain(name)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index fa9f5b585926..63795886785b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -188,6 +188,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6138ffc8d954..1634c726e32a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -990,6 +990,9 @@ pub enum AttributeKind { /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute) RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit }, + /// Represents `#[reexport_test_harness_main]` + ReexportTestHarnessMain(Symbol), + /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7ec1920152a5..5162c6feec31 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -87,6 +87,7 @@ impl AttributeKind { ProcMacroDerive { .. } => No, ProfilerRuntime => No, RecursionLimit { .. } => No, + ReexportTestHarnessMain(..) => No, Repr { .. } => No, RustcAllocator => No, RustcAllocatorZeroed => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4784456a59d9..2dd87391ed9a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -284,6 +284,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Pointee(..) | AttributeKind::ProfilerRuntime | AttributeKind::RecursionLimit { .. } + | AttributeKind::ReexportTestHarnessMain(..) // handled below this loop and elsewhere | AttributeKind::Repr { .. } | AttributeKind::RustcAllocator @@ -414,8 +415,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::feature | sym::register_tool | sym::rustc_no_implicit_bounds - | sym::test_runner - | sym::reexport_test_harness_main, + | sym::test_runner, .. ] => {} [name, rest@..] => { diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 9695a73c137f..83debd17777a 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -467,26 +467,26 @@ mod no_implicit_prelude { #[reexport_test_harness_main = "2900"] //~^ WARN crate-level attribute should be -//~| HELP add a `!` mod reexport_test_harness_main { +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![reexport_test_harness_main="2900"] } - //~^ WARN crate-level attribute should be + //~^ WARN the `#![reexport_test_harness_main]` attribute can only be used at the crate root #[reexport_test_harness_main = "2900"] fn f() { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[reexport_test_harness_main = "2900"] struct S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[reexport_test_harness_main = "2900"] type T = S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[reexport_test_harness_main = "2900"] impl S { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // Cannot feed "2700" to `#[macro_escape]` without signaling an error. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index d69daf45b352..482980dde3bf 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -186,22 +186,6 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 - | -LL | #[reexport_test_harness_main = "2900"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 - | -LL | #![warn(unused_attributes, unknown_lints)] - | ^^^^^^^^^^^^^^^^^ -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:1 | @@ -217,6 +201,11 @@ LL | | } | |_- not an `extern` block | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 + | +LL | #![warn(unused_attributes, unknown_lints)] + | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1 @@ -245,56 +234,6 @@ LL | #![feature(rust1)] | = note: `#[warn(stable_features)]` on by default -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 - | -LL | mod inner { #![reexport_test_harness_main="2900"] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 - | -LL | #[reexport_test_harness_main = "2900"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 - | -LL | #[reexport_test_harness_main = "2900"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 - | -LL | #[reexport_test_harness_main = "2900"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 - | -LL | #[reexport_test_harness_main = "2900"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] impl S { } - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | @@ -771,6 +710,76 @@ LL | #[no_implicit_prelude] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_implicit_prelude]` can be applied to crates and modules +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 + | +LL | #[reexport_test_harness_main = "2900"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:1 + | +LL | / mod reexport_test_harness_main { +LL | | +LL | | mod inner { #![reexport_test_harness_main="2900"] } +... | +LL | | } + | |_^ + +warning: the `#![reexport_test_harness_main]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 + | +LL | mod inner { #![reexport_test_harness_main="2900"] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:44 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:44 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:44 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:44 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^ + warning: `#[macro_escape]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5 | From b902f89f92429eef8cff9aa8431a99624a71e2b7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 4 Feb 2026 21:19:38 +1100 Subject: [PATCH 41/81] Remove panicking default impl of `DepNodeKey::to_fingerprint` There don't appear to be any trait impls relying on this default body. --- compiler/rustc_query_system/src/dep_graph/dep_node.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index e18483d0b435..5df50b2864b2 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -173,12 +173,7 @@ pub trait DepNodeKey: fmt::Debug + Sized { /// This method turns a query key into an opaque `Fingerprint` to be used /// in `DepNode`. - /// - /// Not all `DepNodeKey` impls support being turned into a `Fingerprint` - /// (they don't need to if the corresponding `DepNode` is anonymous). - fn to_fingerprint(&self, _: Tcx) -> Fingerprint { - panic!("Not implemented. Accidentally called on anonymous node?") - } + fn to_fingerprint(&self, _: Tcx) -> Fingerprint; fn to_debug_str(&self, tcx: Tcx) -> String; From 212c8c3811ad37c5554f69790a1d468affc7b6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Mon, 2 Feb 2026 23:58:36 +0100 Subject: [PATCH 42/81] Remove dummy loads --- .../src/builder/gpu_offload.rs | 26 +++++-------------- tests/codegen-llvm/gpu_offload/gpu_host.rs | 4 +-- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 402861eda870..16ab18a568e8 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -347,7 +347,6 @@ pub(crate) struct OffloadKernelGlobals<'ll> { pub offload_sizes: &'ll llvm::Value, pub memtransfer_types: &'ll llvm::Value, pub region_id: &'ll llvm::Value, - pub offload_entry: &'ll llvm::Value, } fn gen_tgt_data_mappers<'ll>( @@ -468,8 +467,12 @@ pub(crate) fn gen_define_handling<'ll>( let c_section_name = CString::new("llvm_offload_entries").unwrap(); llvm::set_section(offload_entry, &c_section_name); - let result = - OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id, offload_entry }; + cx.add_compiler_used_global(offload_entry); + + let result = OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id }; + + // FIXME(Sa4dUs): use this global for constant offload sizes + cx.add_compiler_used_global(result.offload_sizes); cx.offload_kernel_cache.borrow_mut().insert(symbol, result); @@ -532,8 +535,7 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( offload_dims: &OffloadKernelDims<'ll>, ) { let cx = builder.cx; - let OffloadKernelGlobals { offload_sizes, offload_entry, memtransfer_types, region_id } = - offload_data; + let OffloadKernelGlobals { memtransfer_types, region_id, .. } = offload_data; let OffloadKernelDims { num_workgroups, threads_per_block, workgroup_dims, thread_dims } = offload_dims; @@ -548,20 +550,6 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( let num_args = types.len() as u64; let bb = builder.llbb(); - // FIXME(Sa4dUs): dummy loads are a temp workaround, we should find a proper way to prevent these - // variables from being optimized away - for val in [offload_sizes, offload_entry] { - unsafe { - let dummy = llvm::LLVMBuildLoad2( - &builder.llbuilder, - llvm::LLVMTypeOf(val), - val, - b"dummy\0".as_ptr() as *const _, - ); - llvm::LLVMSetVolatile(dummy, llvm::TRUE); - } - } - // Step 0) unsafe { llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, builder.llfn()); diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index d0bc34ec66b2..e12d7c792ae7 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -55,9 +55,7 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 // CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 -// CHECK: %dummy = load volatile ptr, ptr @.offload_sizes.[[K]], align 8 -// CHECK-NEXT: %dummy1 = load volatile ptr, ptr @.offloading.entry.[[K]], align 8 -// CHECK-NEXT: call void @__tgt_init_all_rtls() +// CHECK: call void @__tgt_init_all_rtls() // CHECK-NEXT: store ptr %x, ptr %.offload_baseptrs, align 8 // CHECK-NEXT: store ptr %x, ptr %.offload_ptrs, align 8 // CHECK-NEXT: store i64 1024, ptr %.offload_sizes, align 8 From 9dab26a9ab2b31088eebabd167ae27c43938c7b7 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 16:16:16 +0100 Subject: [PATCH 43/81] Convert to inline diagnostics in `rustc_expand` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_expand/Cargo.toml | 1 - compiler/rustc_expand/messages.ftl | 207 -------------- compiler/rustc_expand/src/config.rs | 7 +- compiler/rustc_expand/src/errors.rs | 267 +++++++++++-------- compiler/rustc_expand/src/expand.rs | 5 +- compiler/rustc_expand/src/lib.rs | 2 - compiler/rustc_expand/src/mbe/diagnostics.rs | 8 +- 9 files changed, 171 insertions(+), 328 deletions(-) delete mode 100644 compiler/rustc_expand/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612..171080f65797 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3879,7 +3879,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_lexer", "rustc_lint_defs", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc61..744fa69025aa 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -121,7 +121,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, rustc_const_eval::DEFAULT_LOCALE_RESOURCE, rustc_errors::DEFAULT_LOCALE_RESOURCE, - rustc_expand::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index a18506c42afc..12b0c384a8ae 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -16,7 +16,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl deleted file mode 100644 index 851d78e0b105..000000000000 --- a/compiler/rustc_expand/messages.ftl +++ /dev/null @@ -1,207 +0,0 @@ -expand_attributes_on_expressions_experimental = - attributes on expressions are experimental - .help_outer_doc = `///` is used for outer documentation comments; for a plain comment, use `//` - .help_inner_doc = `//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !` - -expand_cfg_attr_no_attributes = `#[cfg_attr]` does not expand to any attributes - -expand_count_repetition_misplaced = - `count` can not be placed inside the innermost repetition - -expand_crate_name_in_cfg_attr = - `crate_name` within an `#![cfg_attr]` attribute is forbidden - -expand_crate_type_in_cfg_attr = - `crate_type` within an `#![cfg_attr]` attribute is forbidden - -expand_custom_attribute_panicked = - custom attribute panicked - .help = message: {$message} - -expand_duplicate_matcher_binding = duplicate matcher binding - .label = duplicate binding - .label2 = previous binding - -expand_empty_delegation_mac = - empty {$kind} delegation is not supported - -expand_expected_paren_or_brace = - expected `(` or `{"{"}`, found `{$token}` - -expand_explain_doc_comment_inner = - inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match - -expand_explain_doc_comment_outer = - outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match - -expand_expr_repeat_no_syntax_vars = - attempted to repeat an expression containing no syntax variables matched as repeating at this depth - -expand_feature_not_allowed = - the feature `{$name}` is not in the list of allowed features - -expand_feature_removed = - feature has been removed - .label = feature has been removed - .note = removed in {$removed_rustc_version}{$pull_note} - .reason = {$reason} - -expand_file_modules_in_proc_macro_input_are_unstable = - file modules in proc macro input are unstable - -expand_glob_delegation_outside_impls = - glob delegation is only supported in impls - -expand_glob_delegation_traitless_qpath = - qualified path without a trait in glob delegation - -expand_incomplete_parse = - macro expansion ignores {$descr} and any tokens following - .label = caused by the macro expansion here - .note = the usage of `{$macro_path}!` is likely invalid in {$kind_name} context - .suggestion_add_semi = you might be missing a semicolon here - -expand_invalid_cfg_expected_syntax = expected syntax is - -expand_invalid_cfg_multiple_predicates = multiple `cfg` predicates are specified -expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses -expand_invalid_cfg_no_predicate = `cfg` predicate is not specified -expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal - -expand_invalid_fragment_specifier = - invalid fragment specifier `{$fragment}` - .help = {$help} - -expand_macro_args_bad_delim = `{$rule_kw}` rule argument matchers require parentheses -expand_macro_args_bad_delim_sugg = the delimiters should be `(` and `)` - -expand_macro_body_stability = - macros cannot have body stability attributes - .label = invalid body stability attribute - .label2 = body stability attribute affects this macro - -expand_macro_call_unused_doc_comment = unused doc comment - .label = rustdoc does not generate documentation for macro invocations - .help = to document an item produced by a macro, the macro must produce the documentation as part of its expansion - -expand_macro_const_stability = - macros cannot have const stability attributes - .label = invalid const stability attribute - .label2 = const stability attribute affects this macro - -expand_macro_expands_to_match_arm = macros cannot expand to match arms - -expand_malformed_feature_attribute = - malformed `feature` attribute input - .expected = expected just one word - -expand_meta_var_dif_seq_matchers = {$msg} - -expand_metavar_still_repeating = variable `{$ident}` is still repeating at this depth - .label = expected repetition - -expand_metavariable_wrong_operator = meta-variable repeats with different Kleene operator - .binder_label = expected repetition - .occurrence_label = conflicting repetition - -expand_missing_fragment_specifier = missing fragment specifier - .note = fragment specifiers must be provided - .suggestion_add_fragspec = try adding a specifier here - .valid = {$valid} - -expand_module_circular = - circular modules: {$modules} - -expand_module_file_not_found = - file not found for module `{$name}` - .help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}" - .note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead - -expand_module_in_block = - cannot declare a file module inside a block unless it has a path attribute - .help = maybe `use` the module `{$name}` instead of redeclaring it - .note = file modules are usually placed outside of blocks, at the top level of the file - -expand_module_multiple_candidates = - file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}" - .help = delete or rename one of them to remove the ambiguity - -expand_must_repeat_once = - this must repeat at least once - -expand_mve_extra_tokens = - unexpected trailing tokens - .label = for this metavariable expression - .range = the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments - .exact = the `{$name}` metavariable expression takes {$min_or_exact_args -> - [zero] no arguments - [one] a single argument - *[other] {$min_or_exact_args} arguments - } - .suggestion = try removing {$extra_count -> - [one] this token - *[other] these tokens - } - -expand_mve_missing_paren = - expected `(` - .label = for this this metavariable expression - .unexpected = unexpected token - .note = metavariable expressions use function-like parentheses syntax - .suggestion = try adding parentheses - -expand_mve_unrecognized_expr = - unrecognized metavariable expression - .label = not a valid metavariable expression - .note = valid metavariable expressions are {$valid_expr_list} - -expand_mve_unrecognized_var = - variable `{$key}` is not recognized in meta-variable expression - -expand_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro - .suggestion = use pat_param to preserve semantics - -expand_proc_macro_back_compat = using an old version of `{$crate_name}` - .note = older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives - -expand_proc_macro_derive_panicked = - proc-macro derive panicked - .help = message: {$message} - -expand_proc_macro_derive_tokens = - proc-macro derive produced unparsable tokens - -expand_proc_macro_panicked = - proc macro panicked - .help = message: {$message} - -expand_recursion_limit_reached = - recursion limit reached while expanding `{$descr}` - .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) - -expand_remove_expr_not_supported = - removing an expression is not supported in this position - -expand_remove_node_not_supported = - removing {$descr} is not supported in this position - -expand_resolve_relative_path = - cannot resolve relative path in non-file source `{$path}` - -expand_trace_macro = trace_macro - -expand_trailing_semi_macro = trailing semicolon in macro used in expression position - .note1 = macro invocations at the end of a block are treated as expressions - .note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}` - -expand_unknown_macro_variable = unknown macro variable `{$name}` - -expand_unsupported_key_value = - key-value macro attributes are not supported - -expand_unused_builtin_attribute = unused attribute `{$attr_name}` - .note = the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}` - .suggestion = remove the attribute - -expand_wrong_fragment_kind = - non-{$kind} macro in {$kind} position: {$name} diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 1e1f98aef1b1..c9d0319a97c5 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -15,6 +15,7 @@ use rustc_attr_parsing::{ AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg, }; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; +use rustc_errors::inline_fluent; use rustc_feature::{ ACCEPTED_LANG_FEATURES, EnabledLangFeature, EnabledLibFeature, Features, REMOVED_LANG_FEATURES, UNSTABLE_LANG_FEATURES, @@ -432,14 +433,14 @@ impl<'a> StripUnconfigured<'a> { &self.sess, sym::stmt_expr_attributes, attr.span, - crate::fluent_generated::expand_attributes_on_expressions_experimental, + inline_fluent!("attributes on expressions are experimental"), ); if attr.is_doc_comment() { err.help(if attr.style == AttrStyle::Outer { - crate::fluent_generated::expand_help_outer_doc + inline_fluent!("`///` is used for outer documentation comments; for a plain comment, use `//`") } else { - crate::fluent_generated::expand_help_inner_doc + inline_fluent!("`//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !`") }); } diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 9f9764e060d1..e64bfc136d16 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -7,32 +7,34 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol}; #[derive(LintDiagnostic)] -#[diag(expand_cfg_attr_no_attributes)] +#[diag("`#[cfg_attr]` does not expand to any attributes")] pub(crate) struct CfgAttrNoAttributes; #[derive(Diagnostic)] -#[diag(expand_expr_repeat_no_syntax_vars)] +#[diag( + "attempted to repeat an expression containing no syntax variables matched as repeating at this depth" +)] pub(crate) struct NoSyntaxVarsExprRepeat { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_must_repeat_once)] +#[diag("this must repeat at least once")] pub(crate) struct MustRepeatOnce { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_count_repetition_misplaced)] +#[diag("`count` can not be placed inside the innermost repetition")] pub(crate) struct CountRepetitionMisplaced { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_metavar_still_repeating)] +#[diag("variable `{$ident}` is still repeating at this depth")] pub(crate) struct MacroVarStillRepeating { #[primary_span] pub span: Span, @@ -40,24 +42,24 @@ pub(crate) struct MacroVarStillRepeating { } #[derive(LintDiagnostic)] -#[diag(expand_metavar_still_repeating)] +#[diag("variable `{$ident}` is still repeating at this depth")] pub(crate) struct MetaVarStillRepeatingLint { - #[label] + #[label("expected repetition")] pub label: Span, pub ident: MacroRulesNormalizedIdent, } #[derive(LintDiagnostic)] -#[diag(expand_metavariable_wrong_operator)] +#[diag("meta-variable repeats with different Kleene operator")] pub(crate) struct MetaVariableWrongOperator { - #[label(expand_binder_label)] + #[label("expected repetition")] pub binder: Span, - #[label(expand_occurrence_label)] + #[label("conflicting repetition")] pub occurrence: Span, } #[derive(Diagnostic)] -#[diag(expand_meta_var_dif_seq_matchers)] +#[diag("{$msg}")] pub(crate) struct MetaVarsDifSeqMatchers { #[primary_span] pub span: Span, @@ -65,13 +67,13 @@ pub(crate) struct MetaVarsDifSeqMatchers { } #[derive(LintDiagnostic)] -#[diag(expand_unknown_macro_variable)] +#[diag("unknown macro variable `{$name}`")] pub(crate) struct UnknownMacroVariable { pub name: MacroRulesNormalizedIdent, } #[derive(Diagnostic)] -#[diag(expand_resolve_relative_path)] +#[diag("cannot resolve relative path in non-file source `{$path}`")] pub(crate) struct ResolveRelativePath { #[primary_span] pub span: Span, @@ -79,31 +81,31 @@ pub(crate) struct ResolveRelativePath { } #[derive(Diagnostic)] -#[diag(expand_macro_const_stability)] +#[diag("macros cannot have const stability attributes")] pub(crate) struct MacroConstStability { #[primary_span] - #[label] + #[label("invalid const stability attribute")] pub span: Span, - #[label(expand_label2)] + #[label("const stability attribute affects this macro")] pub head_span: Span, } #[derive(Diagnostic)] -#[diag(expand_macro_body_stability)] +#[diag("macros cannot have body stability attributes")] pub(crate) struct MacroBodyStability { #[primary_span] - #[label] + #[label("invalid body stability attribute")] pub span: Span, - #[label(expand_label2)] + #[label("body stability attribute affects this macro")] pub head_span: Span, } #[derive(Diagnostic)] -#[diag(expand_feature_removed, code = E0557)] -#[note] +#[diag("feature has been removed", code = E0557)] +#[note("removed in {$removed_rustc_version}{$pull_note}")] pub(crate) struct FeatureRemoved<'a> { #[primary_span] - #[label] + #[label("feature has been removed")] pub span: Span, #[subdiagnostic] pub reason: Option>, @@ -112,13 +114,13 @@ pub(crate) struct FeatureRemoved<'a> { } #[derive(Subdiagnostic)] -#[note(expand_reason)] +#[note("{$reason}")] pub(crate) struct FeatureRemovedReason<'a> { pub reason: &'a str, } #[derive(Diagnostic)] -#[diag(expand_feature_not_allowed, code = E0725)] +#[diag("the feature `{$name}` is not in the list of allowed features", code = E0725)] pub(crate) struct FeatureNotAllowed { #[primary_span] pub span: Span, @@ -126,8 +128,10 @@ pub(crate) struct FeatureNotAllowed { } #[derive(Diagnostic)] -#[diag(expand_recursion_limit_reached)] -#[help] +#[diag("recursion limit reached while expanding `{$descr}`")] +#[help( + "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)" +)] pub(crate) struct RecursionLimitReached { #[primary_span] pub span: Span, @@ -137,7 +141,7 @@ pub(crate) struct RecursionLimitReached { } #[derive(Diagnostic)] -#[diag(expand_malformed_feature_attribute, code = E0556)] +#[diag("malformed `feature` attribute input", code = E0556)] pub(crate) struct MalformedFeatureAttribute { #[primary_span] pub span: Span, @@ -147,12 +151,16 @@ pub(crate) struct MalformedFeatureAttribute { #[derive(Subdiagnostic)] pub(crate) enum MalformedFeatureAttributeHelp { - #[label(expand_expected)] + #[label("expected just one word")] Label { #[primary_span] span: Span, }, - #[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion( + "expected just one word", + code = "{suggestion}", + applicability = "maybe-incorrect" + )] Suggestion { #[primary_span] span: Span, @@ -161,7 +169,7 @@ pub(crate) enum MalformedFeatureAttributeHelp { } #[derive(Diagnostic)] -#[diag(expand_remove_expr_not_supported)] +#[diag("removing an expression is not supported in this position")] pub(crate) struct RemoveExprNotSupported { #[primary_span] pub span: Span, @@ -169,32 +177,32 @@ pub(crate) struct RemoveExprNotSupported { #[derive(Diagnostic)] pub(crate) enum InvalidCfg { - #[diag(expand_invalid_cfg_no_parens)] + #[diag("`cfg` is not followed by parentheses")] NotFollowedByParens { #[primary_span] #[suggestion( - expand_invalid_cfg_expected_syntax, + "expected syntax is", code = "cfg(/* predicate */)", applicability = "has-placeholders" )] span: Span, }, - #[diag(expand_invalid_cfg_no_predicate)] + #[diag("`cfg` predicate is not specified")] NoPredicate { #[primary_span] #[suggestion( - expand_invalid_cfg_expected_syntax, + "expected syntax is", code = "cfg(/* predicate */)", applicability = "has-placeholders" )] span: Span, }, - #[diag(expand_invalid_cfg_multiple_predicates)] + #[diag("multiple `cfg` predicates are specified")] MultiplePredicates { #[primary_span] span: Span, }, - #[diag(expand_invalid_cfg_predicate_literal)] + #[diag("`cfg` predicate key cannot be a literal")] PredicateLiteral { #[primary_span] span: Span, @@ -202,7 +210,7 @@ pub(crate) enum InvalidCfg { } #[derive(Diagnostic)] -#[diag(expand_wrong_fragment_kind)] +#[diag("non-{$kind} macro in {$kind} position: {$name}")] pub(crate) struct WrongFragmentKind<'a> { #[primary_span] pub span: Span, @@ -211,28 +219,28 @@ pub(crate) struct WrongFragmentKind<'a> { } #[derive(Diagnostic)] -#[diag(expand_unsupported_key_value)] +#[diag("key-value macro attributes are not supported")] pub(crate) struct UnsupportedKeyValue { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_incomplete_parse)] -#[note] +#[diag("macro expansion ignores {$descr} and any tokens following")] +#[note("the usage of `{$macro_path}!` is likely invalid in {$kind_name} context")] pub(crate) struct IncompleteParse<'a> { #[primary_span] pub span: Span, pub descr: String, - #[label] + #[label("caused by the macro expansion here")] pub label_span: Span, pub macro_path: &'a ast::Path, pub kind_name: &'a str, - #[note(expand_macro_expands_to_match_arm)] + #[note("macros cannot expand to match arms")] pub expands_to_match_arm: bool, #[suggestion( - expand_suggestion_add_semi, + "you might be missing a semicolon here", style = "verbose", code = ";", applicability = "maybe-incorrect" @@ -241,7 +249,7 @@ pub(crate) struct IncompleteParse<'a> { } #[derive(Diagnostic)] -#[diag(expand_remove_node_not_supported)] +#[diag("removing {$descr} is not supported in this position")] pub(crate) struct RemoveNodeNotSupported { #[primary_span] pub span: Span, @@ -249,7 +257,7 @@ pub(crate) struct RemoveNodeNotSupported { } #[derive(Diagnostic)] -#[diag(expand_module_circular)] +#[diag("circular modules: {$modules}")] pub(crate) struct ModuleCircular { #[primary_span] pub span: Span, @@ -257,8 +265,8 @@ pub(crate) struct ModuleCircular { } #[derive(Diagnostic)] -#[diag(expand_module_in_block)] -#[note] +#[diag("cannot declare a file module inside a block unless it has a path attribute")] +#[note("file modules are usually placed outside of blocks, at the top level of the file")] pub(crate) struct ModuleInBlock { #[primary_span] pub span: Span, @@ -267,7 +275,7 @@ pub(crate) struct ModuleInBlock { } #[derive(Subdiagnostic)] -#[help(expand_help)] +#[help("maybe `use` the module `{$name}` instead of redeclaring it")] pub(crate) struct ModuleInBlockName { #[primary_span] pub span: Span, @@ -275,9 +283,11 @@ pub(crate) struct ModuleInBlockName { } #[derive(Diagnostic)] -#[diag(expand_module_file_not_found, code = E0583)] -#[help] -#[note] +#[diag("file not found for module `{$name}`", code = E0583)] +#[help("to create the module `{$name}`, create file \"{$default_path}\" or \"{$secondary_path}\"")] +#[note( + "if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead" +)] pub(crate) struct ModuleFileNotFound { #[primary_span] pub span: Span, @@ -287,8 +297,8 @@ pub(crate) struct ModuleFileNotFound { } #[derive(Diagnostic)] -#[diag(expand_module_multiple_candidates, code = E0761)] -#[help] +#[diag("file for module `{$name}` found at both \"{$default_path}\" and \"{$secondary_path}\"", code = E0761)] +#[help("delete or rename one of them to remove the ambiguity")] pub(crate) struct ModuleMultipleCandidates { #[primary_span] pub span: Span, @@ -298,14 +308,14 @@ pub(crate) struct ModuleMultipleCandidates { } #[derive(Diagnostic)] -#[diag(expand_trace_macro)] +#[diag("trace_macro")] pub(crate) struct TraceMacro { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_proc_macro_panicked)] +#[diag("proc macro panicked")] pub(crate) struct ProcMacroPanicked { #[primary_span] pub span: Span, @@ -314,13 +324,13 @@ pub(crate) struct ProcMacroPanicked { } #[derive(Subdiagnostic)] -#[help(expand_help)] +#[help("message: {$message}")] pub(crate) struct ProcMacroPanickedHelp { pub message: String, } #[derive(Diagnostic)] -#[diag(expand_proc_macro_derive_panicked)] +#[diag("proc-macro derive panicked")] pub(crate) struct ProcMacroDerivePanicked { #[primary_span] pub span: Span, @@ -329,13 +339,13 @@ pub(crate) struct ProcMacroDerivePanicked { } #[derive(Subdiagnostic)] -#[help(expand_help)] +#[help("message: {$message}")] pub(crate) struct ProcMacroDerivePanickedHelp { pub message: String, } #[derive(Diagnostic)] -#[diag(expand_custom_attribute_panicked)] +#[diag("custom attribute panicked")] pub(crate) struct CustomAttributePanicked { #[primary_span] pub span: Span, @@ -344,46 +354,46 @@ pub(crate) struct CustomAttributePanicked { } #[derive(Subdiagnostic)] -#[help(expand_help)] +#[help("message: {$message}")] pub(crate) struct CustomAttributePanickedHelp { pub message: String, } #[derive(Diagnostic)] -#[diag(expand_proc_macro_derive_tokens)] +#[diag("proc-macro derive produced unparsable tokens")] pub(crate) struct ProcMacroDeriveTokens { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_duplicate_matcher_binding)] +#[diag("duplicate matcher binding")] pub(crate) struct DuplicateMatcherBinding { #[primary_span] - #[label] + #[label("duplicate binding")] pub span: Span, - #[label(expand_label2)] + #[label("previous binding")] pub prev: Span, } #[derive(LintDiagnostic)] -#[diag(expand_duplicate_matcher_binding)] +#[diag("duplicate matcher binding")] pub(crate) struct DuplicateMatcherBindingLint { - #[label] + #[label("duplicate binding")] pub span: Span, - #[label(expand_label2)] + #[label("previous binding")] pub prev: Span, } #[derive(Diagnostic)] -#[diag(expand_missing_fragment_specifier)] -#[note] -#[help(expand_valid)] +#[diag("missing fragment specifier")] +#[note("fragment specifiers must be provided")] +#[help("{$valid}")] pub(crate) struct MissingFragmentSpecifier { #[primary_span] pub span: Span, #[suggestion( - expand_suggestion_add_fragspec, + "try adding a specifier here", style = "verbose", code = ":spec", applicability = "maybe-incorrect" @@ -393,8 +403,8 @@ pub(crate) struct MissingFragmentSpecifier { } #[derive(Diagnostic)] -#[diag(expand_invalid_fragment_specifier)] -#[help] +#[diag("invalid fragment specifier `{$fragment}`")] +#[help("{$help}")] pub(crate) struct InvalidFragmentSpecifier { #[primary_span] pub span: Span, @@ -403,7 +413,7 @@ pub(crate) struct InvalidFragmentSpecifier { } #[derive(Diagnostic)] -#[diag(expand_expected_paren_or_brace)] +#[diag("expected `(` or `{\"{\"}`, found `{$token}`")] pub(crate) struct ExpectedParenOrBrace<'a> { #[primary_span] pub span: Span, @@ -411,7 +421,7 @@ pub(crate) struct ExpectedParenOrBrace<'a> { } #[derive(Diagnostic)] -#[diag(expand_empty_delegation_mac)] +#[diag("empty {$kind} delegation is not supported")] pub(crate) struct EmptyDelegationMac { #[primary_span] pub span: Span, @@ -419,28 +429,28 @@ pub(crate) struct EmptyDelegationMac { } #[derive(Diagnostic)] -#[diag(expand_glob_delegation_outside_impls)] +#[diag("glob delegation is only supported in impls")] pub(crate) struct GlobDelegationOutsideImpls { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_crate_name_in_cfg_attr)] +#[diag("`crate_name` within an `#![cfg_attr]` attribute is forbidden")] pub(crate) struct CrateNameInCfgAttr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_crate_type_in_cfg_attr)] +#[diag("`crate_type` within an `#![cfg_attr]` attribute is forbidden")] pub(crate) struct CrateTypeInCfgAttr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(expand_glob_delegation_traitless_qpath)] +#[diag("qualified path without a trait in glob delegation")] pub(crate) struct GlobDelegationTraitlessQpath { #[primary_span] pub span: Span, @@ -449,8 +459,10 @@ pub(crate) struct GlobDelegationTraitlessQpath { // This used to be the `proc_macro_back_compat` lint (#83125). It was later // turned into a hard error. #[derive(Diagnostic)] -#[diag(expand_proc_macro_back_compat)] -#[note] +#[diag("using an old version of `{$crate_name}`")] +#[note( + "older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives" +)] pub(crate) struct ProcMacroBackCompat { pub crate_name: String, pub fixed_version: String, @@ -461,20 +473,35 @@ mod metavar_exprs { use super::*; #[derive(Diagnostic, Default)] - #[diag(expand_mve_extra_tokens)] + #[diag("unexpected trailing tokens")] pub(crate) struct MveExtraTokens { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion( + "try removing {$extra_count -> + [one] this token + *[other] these tokens + }", + code = "", + applicability = "machine-applicable" + )] pub span: Span, - #[label] + #[label("for this metavariable expression")] pub ident_span: Span, pub extra_count: usize, // The rest is only used for specific diagnostics and can be default if neither // `note` is `Some`. - #[note(expand_exact)] + #[note( + "the `{$name}` metavariable expression takes {$min_or_exact_args -> + [zero] no arguments + [one] a single argument + *[other] {$min_or_exact_args} arguments + }" + )] pub exact_args_note: Option<()>, - #[note(expand_range)] + #[note( + "the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments" + )] pub range_args_note: Option<()>, pub min_or_exact_args: usize, pub max_args: usize, @@ -482,30 +509,34 @@ mod metavar_exprs { } #[derive(Diagnostic)] - #[note] - #[diag(expand_mve_missing_paren)] + #[note("metavariable expressions use function-like parentheses syntax")] + #[diag("expected `(`")] pub(crate) struct MveMissingParen { #[primary_span] - #[label] + #[label("for this this metavariable expression")] pub ident_span: Span, - #[label(expand_unexpected)] + #[label("unexpected token")] pub unexpected_span: Option, - #[suggestion(code = "( /* ... */ )", applicability = "has-placeholders")] + #[suggestion( + "try adding parentheses", + code = "( /* ... */ )", + applicability = "has-placeholders" + )] pub insert_span: Option, } #[derive(Diagnostic)] - #[note] - #[diag(expand_mve_unrecognized_expr)] + #[note("valid metavariable expressions are {$valid_expr_list}")] + #[diag("unrecognized metavariable expression")] pub(crate) struct MveUnrecognizedExpr { #[primary_span] - #[label] + #[label("not a valid metavariable expression")] pub span: Span, pub valid_expr_list: &'static str, } #[derive(Diagnostic)] - #[diag(expand_mve_unrecognized_var)] + #[diag("variable `{$key}` is not recognized in meta-variable expression")] pub(crate) struct MveUnrecognizedVar { #[primary_span] pub span: Span, @@ -514,7 +545,7 @@ mod metavar_exprs { } #[derive(Diagnostic)] -#[diag(expand_macro_args_bad_delim)] +#[diag("`{$rule_kw}` rule argument matchers require parentheses")] pub(crate) struct MacroArgsBadDelim { #[primary_span] pub span: Span, @@ -524,7 +555,10 @@ pub(crate) struct MacroArgsBadDelim { } #[derive(Subdiagnostic)] -#[multipart_suggestion(expand_macro_args_bad_delim_sugg, applicability = "machine-applicable")] +#[multipart_suggestion( + "the delimiters should be `(` and `)`", + applicability = "machine-applicable" +)] pub(crate) struct MacroArgsBadDelimSugg { #[suggestion_part(code = "(")] pub open: Span, @@ -533,37 +567,54 @@ pub(crate) struct MacroArgsBadDelimSugg { } #[derive(LintDiagnostic)] -#[diag(expand_macro_call_unused_doc_comment)] -#[help] +#[diag("unused doc comment")] +#[help( + "to document an item produced by a macro, the macro must produce the documentation as part of its expansion" +)] pub(crate) struct MacroCallUnusedDocComment { - #[label] + #[label("rustdoc does not generate documentation for macro invocations")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(expand_or_patterns_back_compat)] +#[diag( + "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro" +)] pub(crate) struct OrPatternsBackCompat { - #[suggestion(code = "{suggestion}", applicability = "machine-applicable")] + #[suggestion( + "use pat_param to preserve semantics", + code = "{suggestion}", + applicability = "machine-applicable" + )] pub span: Span, pub suggestion: String, } #[derive(LintDiagnostic)] -#[diag(expand_trailing_semi_macro)] +#[diag("trailing semicolon in macro used in expression position")] pub(crate) struct TrailingMacro { - #[note(expand_note1)] - #[note(expand_note2)] + #[note("macro invocations at the end of a block are treated as expressions")] + #[note( + "to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`" + )] pub is_trailing: bool, pub name: Ident, } #[derive(LintDiagnostic)] -#[diag(expand_unused_builtin_attribute)] +#[diag("unused attribute `{$attr_name}`")] pub(crate) struct UnusedBuiltinAttribute { - #[note] + #[note( + "the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`" + )] pub invoc_span: Span, pub attr_name: Symbol, pub macro_name: String, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the attribute", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub attr_span: Span, } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 449dc95ea372..da678ff70346 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -19,7 +19,7 @@ use rustc_attr_parsing::{ }; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::PResult; +use rustc_errors::{PResult, inline_fluent}; use rustc_feature::Features; use rustc_hir::Target; use rustc_hir::def::MacroKinds; @@ -42,7 +42,6 @@ use crate::errors::{ RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind, }; -use crate::fluent_generated; use crate::mbe::diagnostics::annotate_err_with_kind; use crate::module::{ DirOwnership, ParsedExternalMod, mod_dir_path, mod_file_path_from_attr, parse_external_mod, @@ -1052,7 +1051,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.sess, sym::proc_macro_hygiene, item.span, - fluent_generated::expand_file_modules_in_proc_macro_input_are_unstable, + inline_fluent!("file modules in proc macro input are unstable"), ) .emit(); } diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 89540a9a5c5b..96f17418b8d2 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -26,5 +26,3 @@ pub mod proc_macro; pub fn provide(providers: &mut rustc_middle::query::Providers) { providers.derive_macro_expansion = proc_macro::provide_derive_macro_expansion; } - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index f5edaf50edd5..df6903dc4937 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -302,12 +302,16 @@ pub(crate) fn annotate_err_with_kind(err: &mut Diag<'_>, kind: AstFragmentKind, #[derive(Subdiagnostic)] enum ExplainDocComment { - #[label(expand_explain_doc_comment_inner)] + #[label( + "inner doc comments expand to `#![doc = \"...\"]`, which is what this macro attempted to match" + )] Inner { #[primary_span] span: Span, }, - #[label(expand_explain_doc_comment_outer)] + #[label( + "outer doc comments expand to `#[doc = \"...\"]`, which is what this macro attempted to match" + )] Outer { #[primary_span] span: Span, From 8d09ba7ae54d4431d10eb09eae4153208fd3d3a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 4 Feb 2026 14:37:15 +0100 Subject: [PATCH 44/81] Convert to inline diagnostics in `rustc_ast_lowering` --- Cargo.lock | 2 - compiler/rustc_ast_lowering/Cargo.toml | 1 - compiler/rustc_ast_lowering/messages.ftl | 191 ------------------ compiler/rustc_ast_lowering/src/asm.rs | 12 +- compiler/rustc_ast_lowering/src/errors.rs | 226 +++++++++++++--------- compiler/rustc_ast_lowering/src/expr.rs | 7 +- compiler/rustc_ast_lowering/src/lib.rs | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - 9 files changed, 141 insertions(+), 302 deletions(-) delete mode 100644 compiler/rustc_ast_lowering/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612..e9cdc493451d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3490,7 +3490,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -3775,7 +3774,6 @@ dependencies = [ "libc", "rustc_abi", "rustc_ast", - "rustc_ast_lowering", "rustc_ast_passes", "rustc_ast_pretty", "rustc_borrowck", diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 6ac258155fe9..c00bac5d3c5a 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -15,7 +15,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl deleted file mode 100644 index 0cd5c4f303de..000000000000 --- a/compiler/rustc_ast_lowering/messages.ftl +++ /dev/null @@ -1,191 +0,0 @@ -ast_lowering_abi_specified_multiple_times = - `{$prev_name}` ABI specified multiple times - .label = previously specified here - .note = these ABIs are equivalent on the current target - -ast_lowering_arbitrary_expression_in_pattern = - arbitrary expressions aren't allowed in patterns - .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression - .const_block_in_pattern_help = use a named `const`-item or an `if`-guard (`x if x == const {"{ ... }"}`) instead - -ast_lowering_argument = argument - -ast_lowering_assoc_ty_binding_in_dyn = - associated type bounds are not allowed in `dyn` types - .suggestion = use `impl Trait` to introduce a type instead - -ast_lowering_assoc_ty_parentheses = - parenthesized generic arguments cannot be used in associated type constraints - -ast_lowering_async_bound_not_on_trait = - `async` bound modifier only allowed on trait, not `{$descr}` - -ast_lowering_async_bound_only_for_fn_traits = - `async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits - -ast_lowering_async_coroutines_not_supported = - `async` coroutines are not yet supported - -ast_lowering_att_syntax_only_x86 = - the `att_syntax` option is only supported on x86 - -ast_lowering_await_only_in_async_fn_and_blocks = - `await` is only allowed inside `async` functions and blocks - .label = only allowed inside `async` functions and blocks - -ast_lowering_bad_return_type_notation_inputs = - argument types not allowed with return type notation - .suggestion = remove the input types - -ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..` - .suggestion = use the correct syntax by adding `..` to the arguments - -ast_lowering_bad_return_type_notation_output = - return type not allowed with return type notation -ast_lowering_bad_return_type_notation_output_suggestion = use the right argument notation and remove the return type - -ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet - -ast_lowering_clobber_abi_not_supported = - `clobber_abi` is not supported on this target - -ast_lowering_closure_cannot_be_static = closures cannot be static - -ast_lowering_coroutine_too_many_parameters = - too many parameters for a coroutine (expected 0 or 1 parameters) - -ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs - .label = default fields are only supported on structs - -ast_lowering_delegation_cycle_in_signature_resolution = encountered a cycle during delegation signature resolution -ast_lowering_delegation_unresolved_callee = failed to resolve delegation callee -ast_lowering_does_not_support_modifiers = - the `{$class_name}` register class does not support template modifiers - -ast_lowering_extra_double_dot = - `..` can only be used once per {$ctx} pattern - .label = can only be used once per {$ctx} pattern - -ast_lowering_functional_record_update_destructuring_assignment = - functional record updates are not allowed in destructuring assignments - .suggestion = consider removing the trailing pattern - -ast_lowering_generic_param_default_in_binder = - defaults for generic parameters are not allowed in `for<...>` binders - -ast_lowering_generic_type_with_parentheses = - parenthesized type parameters may only be used with a `Fn` trait - .label = only `Fn` traits may use parentheses - -ast_lowering_inclusive_range_with_no_end = inclusive range with no end - -ast_lowering_inline_asm_unsupported_target = - inline assembly is unsupported on this target - -ast_lowering_invalid_abi = - invalid ABI: found `{$abi}` - .label = invalid ABI - .note = invoke `{$command}` for a full list of supported calling conventions - -ast_lowering_invalid_abi_clobber_abi = - invalid ABI for `clobber_abi` - .note = the following ABIs are supported on this target: {$supported_abis} - -ast_lowering_invalid_abi_suggestion = there's a similarly named valid ABI `{$suggestion}` - -ast_lowering_invalid_asm_template_modifier_const = - asm template modifiers are not allowed for `const` arguments - -ast_lowering_invalid_asm_template_modifier_label = - asm template modifiers are not allowed for `label` arguments - -ast_lowering_invalid_asm_template_modifier_reg_class = - invalid asm template modifier for this register class - -ast_lowering_invalid_asm_template_modifier_sym = - asm template modifiers are not allowed for `sym` arguments - -ast_lowering_invalid_legacy_const_generic_arg = - invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items - -ast_lowering_invalid_legacy_const_generic_arg_suggestion = - try using a const generic argument instead - -ast_lowering_invalid_register = - invalid register `{$reg}`: {$error} - -ast_lowering_invalid_register_class = - invalid register class `{$reg_class}`: unknown register class - .note = the following register classes are supported on this target: {$supported_register_classes} - -ast_lowering_match_arm_with_no_body = - `match` arm with no body - .suggestion = add a body after the pattern - -ast_lowering_misplaced_double_dot = - `..` patterns are not allowed here - .note = only allowed in tuple, tuple struct, and slice patterns - -ast_lowering_misplaced_impl_trait = - `impl Trait` is not allowed in {$position} - .note = `impl Trait` is only allowed in arguments and return types of functions and methods - -ast_lowering_never_pattern_with_body = - a never pattern is always unreachable - .label = this will never be executed - .suggestion = remove this expression - -ast_lowering_never_pattern_with_guard = - a guard on a never pattern will never be run - .suggestion = remove this guard - -ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait` - -ast_lowering_previously_used_here = previously used here - -ast_lowering_register1 = register `{$reg1_name}` - -ast_lowering_register2 = register `{$reg2_name}` - -ast_lowering_register_class_only_clobber = - register class `{$reg_class_name}` can only be used as a clobber, not as an input or output -ast_lowering_register_class_only_clobber_stable = - register class `{$reg_class_name}` can only be used as a clobber in stable - -ast_lowering_register_conflict = - register `{$reg1_name}` conflicts with register `{$reg2_name}` - .help = use `lateout` instead of `out` to avoid conflict - -ast_lowering_remove_parentheses = remove these parentheses - -ast_lowering_sub_tuple_binding = - `{$ident_name} @` is not allowed in a {$ctx} - .label = this is only allowed in slice patterns - .help = remove this and bind each tuple field independently - -ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields - -ast_lowering_support_modifiers = - the `{$class_name}` register class supports the following template modifiers: {$modifiers} - -ast_lowering_template_modifier = template modifier - -ast_lowering_this_not_async = this is not `async` - -ast_lowering_underscore_expr_lhs_assign = - in expressions, `_` can only be used on the left-hand side of an assignment - .label = `_` not allowed here - -ast_lowering_union_default_field_values = unions cannot have default field values - -ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture -ast_lowering_unstable_inline_assembly_label_operand_with_outputs = - using both label and output operands for inline assembly is unstable -ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable - -ast_lowering_use_angle_brackets = use angle brackets instead - -ast_lowering_yield = yield syntax is experimental -ast_lowering_yield_in_closure = - `yield` can only be used in `#[coroutine]` closures, or `gen` blocks - .suggestion = use `#[coroutine]` to make this closure a coroutine diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 36fcd4b924c8..fc1f198e8b2a 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -3,6 +3,7 @@ use std::fmt::Write; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_errors::inline_fluent; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_session::parse::feature_err; @@ -19,8 +20,7 @@ use super::errors::{ RegisterConflict, }; use crate::{ - AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, - ResolverAstLoweringExt, fluent_generated as fluent, + AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt, }; impl<'a, 'hir> LoweringContext<'a, 'hir> { @@ -67,7 +67,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &self.tcx.sess, sym::asm_experimental_arch, sp, - fluent::ast_lowering_unstable_inline_assembly, + inline_fluent!("inline assembly is not stable yet on this architecture"), ) .emit(); } @@ -84,7 +84,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &self.tcx.sess, sym::asm_unwind, sp, - fluent::ast_lowering_unstable_may_unwind, + inline_fluent!("the `may_unwind` option is unstable"), ) .emit(); } @@ -499,7 +499,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { sess, sym::asm_goto_with_outputs, *op_sp, - fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs, + inline_fluent!( + "using both label and output operands for inline assembly is unstable" + ), ) .emit(); } diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 88e69e67d8a5..1eb72727df66 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -4,17 +4,17 @@ use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; #[derive(Diagnostic)] -#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)] +#[diag("parenthesized type parameters may only be used with a `Fn` trait", code = E0214)] pub(crate) struct GenericTypeWithParentheses { #[primary_span] - #[label] + #[label("only `Fn` traits may use parentheses")] pub span: Span, #[subdiagnostic] pub sub: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")] +#[multipart_suggestion("use angle brackets instead", applicability = "maybe-incorrect")] pub(crate) struct UseAngleBrackets { #[suggestion_part(code = "<")] pub open_param: Span, @@ -23,11 +23,11 @@ pub(crate) struct UseAngleBrackets { } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_abi, code = E0703)] -#[note] +#[diag("invalid ABI: found `{$abi}`", code = E0703)] +#[note("invoke `{$command}` for a full list of supported calling conventions")] pub(crate) struct InvalidAbi { #[primary_span] - #[label] + #[label("invalid ABI")] pub span: Span, pub abi: Symbol, pub command: String, @@ -36,16 +36,16 @@ pub(crate) struct InvalidAbi { } #[derive(Diagnostic)] -#[diag(ast_lowering_default_field_in_tuple)] +#[diag("default fields are not supported in tuple structs")] pub(crate) struct TupleStructWithDefault { #[primary_span] - #[label] + #[label("default fields are only supported on structs")] pub span: Span, } #[derive(Subdiagnostic)] #[suggestion( - ast_lowering_invalid_abi_suggestion, + "there's a similarly named valid ABI `{$suggestion}`", code = "\"{suggestion}\"", applicability = "maybe-incorrect", style = "verbose" @@ -57,7 +57,7 @@ pub(crate) struct InvalidAbiSuggestion { } #[derive(Diagnostic)] -#[diag(ast_lowering_assoc_ty_parentheses)] +#[diag("parenthesized generic arguments cannot be used in associated type constraints")] pub(crate) struct AssocTyParentheses { #[primary_span] pub span: Span, @@ -67,12 +67,12 @@ pub(crate) struct AssocTyParentheses { #[derive(Subdiagnostic)] pub(crate) enum AssocTyParenthesesSub { - #[multipart_suggestion(ast_lowering_remove_parentheses)] + #[multipart_suggestion("remove these parentheses")] Empty { #[suggestion_part(code = "")] parentheses_span: Span, }, - #[multipart_suggestion(ast_lowering_use_angle_brackets)] + #[multipart_suggestion("use angle brackets instead")] NotEmpty { #[suggestion_part(code = "<")] open_param: Span, @@ -82,8 +82,8 @@ pub(crate) enum AssocTyParenthesesSub { } #[derive(Diagnostic)] -#[diag(ast_lowering_misplaced_impl_trait, code = E0562)] -#[note] +#[diag("`impl Trait` is not allowed in {$position}", code = E0562)] +#[note("`impl Trait` is only allowed in arguments and return types of functions and methods")] pub(crate) struct MisplacedImplTrait<'a> { #[primary_span] pub span: Span, @@ -91,97 +91,106 @@ pub(crate) struct MisplacedImplTrait<'a> { } #[derive(Diagnostic)] -#[diag(ast_lowering_assoc_ty_binding_in_dyn)] +#[diag("associated type bounds are not allowed in `dyn` types")] pub(crate) struct MisplacedAssocTyBinding { #[primary_span] pub span: Span, - #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "use `impl Trait` to introduce a type instead", + code = " = impl", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggestion: Option, } #[derive(Diagnostic)] -#[diag(ast_lowering_underscore_expr_lhs_assign)] +#[diag("in expressions, `_` can only be used on the left-hand side of an assignment")] pub(crate) struct UnderscoreExprLhsAssign { #[primary_span] - #[label] + #[label("`_` not allowed here")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)] +#[diag("`await` is only allowed inside `async` functions and blocks", code = E0728)] pub(crate) struct AwaitOnlyInAsyncFnAndBlocks { #[primary_span] - #[label] + #[label("only allowed inside `async` functions and blocks")] pub await_kw_span: Span, - #[label(ast_lowering_this_not_async)] + #[label("this is not `async`")] pub item_span: Option, } #[derive(Diagnostic)] -#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)] +#[diag("too many parameters for a coroutine (expected 0 or 1 parameters)", code = E0628)] pub(crate) struct CoroutineTooManyParameters { #[primary_span] pub fn_decl_span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_closure_cannot_be_static, code = E0697)] +#[diag("closures cannot be static", code = E0697)] pub(crate) struct ClosureCannotBeStatic { #[primary_span] pub fn_decl_span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_functional_record_update_destructuring_assignment)] +#[diag("functional record updates are not allowed in destructuring assignments")] pub(crate) struct FunctionalRecordUpdateDestructuringAssignment { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion( + "consider removing the trailing pattern", + code = "", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)] +#[diag("`async` coroutines are not yet supported", code = E0727)] pub(crate) struct AsyncCoroutinesNotSupported { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)] +#[diag("inline assembly is unsupported on this target", code = E0472)] pub(crate) struct InlineAsmUnsupportedTarget { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_att_syntax_only_x86)] +#[diag("the `att_syntax` option is only supported on x86")] pub(crate) struct AttSyntaxOnlyX86 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_abi_specified_multiple_times)] +#[diag("`{$prev_name}` ABI specified multiple times")] pub(crate) struct AbiSpecifiedMultipleTimes { #[primary_span] pub abi_span: Span, pub prev_name: Symbol, - #[label] + #[label("previously specified here")] pub prev_span: Span, - #[note] + #[note("these ABIs are equivalent on the current target")] pub equivalent: bool, } #[derive(Diagnostic)] -#[diag(ast_lowering_clobber_abi_not_supported)] +#[diag("`clobber_abi` is not supported on this target")] pub(crate) struct ClobberAbiNotSupported { #[primary_span] pub abi_span: Span, } #[derive(Diagnostic)] -#[note] -#[diag(ast_lowering_invalid_abi_clobber_abi)] +#[note("the following ABIs are supported on this target: {$supported_abis}")] +#[diag("invalid ABI for `clobber_abi`")] pub(crate) struct InvalidAbiClobberAbi { #[primary_span] pub abi_span: Span, @@ -189,7 +198,7 @@ pub(crate) struct InvalidAbiClobberAbi { } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_register)] +#[diag("invalid register `{$reg}`: {$error}")] pub(crate) struct InvalidRegister<'a> { #[primary_span] pub op_span: Span, @@ -198,8 +207,10 @@ pub(crate) struct InvalidRegister<'a> { } #[derive(Diagnostic)] -#[note] -#[diag(ast_lowering_invalid_register_class)] +#[note( + "the following register classes are supported on this target: {$supported_register_classes}" +)] +#[diag("invalid register class `{$reg_class}`: unknown register class")] pub(crate) struct InvalidRegisterClass { #[primary_span] pub op_span: Span, @@ -208,12 +219,12 @@ pub(crate) struct InvalidRegisterClass { } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_asm_template_modifier_reg_class)] +#[diag("invalid asm template modifier for this register class")] pub(crate) struct InvalidAsmTemplateModifierRegClass { #[primary_span] - #[label(ast_lowering_template_modifier)] + #[label("template modifier")] pub placeholder_span: Span, - #[label(ast_lowering_argument)] + #[label("argument")] pub op_span: Span, #[subdiagnostic] pub sub: InvalidAsmTemplateModifierRegClassSub, @@ -221,44 +232,48 @@ pub(crate) struct InvalidAsmTemplateModifierRegClass { #[derive(Subdiagnostic)] pub(crate) enum InvalidAsmTemplateModifierRegClassSub { - #[note(ast_lowering_support_modifiers)] + #[note( + "the `{$class_name}` register class supports the following template modifiers: {$modifiers}" + )] SupportModifier { class_name: Symbol, modifiers: String }, - #[note(ast_lowering_does_not_support_modifiers)] + #[note("the `{$class_name}` register class does not support template modifiers")] DoesNotSupportModifier { class_name: Symbol }, } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_asm_template_modifier_const)] +#[diag("asm template modifiers are not allowed for `const` arguments")] pub(crate) struct InvalidAsmTemplateModifierConst { #[primary_span] - #[label(ast_lowering_template_modifier)] + #[label("template modifier")] pub placeholder_span: Span, - #[label(ast_lowering_argument)] + #[label("argument")] pub op_span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_asm_template_modifier_sym)] +#[diag("asm template modifiers are not allowed for `sym` arguments")] pub(crate) struct InvalidAsmTemplateModifierSym { #[primary_span] - #[label(ast_lowering_template_modifier)] + #[label("template modifier")] pub placeholder_span: Span, - #[label(ast_lowering_argument)] + #[label("argument")] pub op_span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_asm_template_modifier_label)] +#[diag("asm template modifiers are not allowed for `label` arguments")] pub(crate) struct InvalidAsmTemplateModifierLabel { #[primary_span] - #[label(ast_lowering_template_modifier)] + #[label("template modifier")] pub placeholder_span: Span, - #[label(ast_lowering_argument)] + #[label("argument")] pub op_span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_register_class_only_clobber)] +#[diag( + "register class `{$reg_class_name}` can only be used as a clobber, not as an input or output" +)] pub(crate) struct RegisterClassOnlyClobber { #[primary_span] pub op_span: Span, @@ -266,7 +281,7 @@ pub(crate) struct RegisterClassOnlyClobber { } #[derive(Diagnostic)] -#[diag(ast_lowering_register_class_only_clobber_stable)] +#[diag("register class `{$reg_class_name}` can only be used as a clobber in stable")] pub(crate) struct RegisterClassOnlyClobberStable { #[primary_span] pub op_span: Span, @@ -274,27 +289,27 @@ pub(crate) struct RegisterClassOnlyClobberStable { } #[derive(Diagnostic)] -#[diag(ast_lowering_register_conflict)] +#[diag("register `{$reg1_name}` conflicts with register `{$reg2_name}`")] pub(crate) struct RegisterConflict<'a> { #[primary_span] - #[label(ast_lowering_register1)] + #[label("register `{$reg1_name}`")] pub op_span1: Span, - #[label(ast_lowering_register2)] + #[label("register `{$reg2_name}`")] pub op_span2: Span, pub reg1_name: &'a str, pub reg2_name: &'a str, - #[help] + #[help("use `lateout` instead of `out` to avoid conflict")] pub in_out: Option, } #[derive(Diagnostic)] -#[help] -#[diag(ast_lowering_sub_tuple_binding)] +#[help("remove this and bind each tuple field independently")] +#[diag("`{$ident_name} @` is not allowed in a {$ctx}")] pub(crate) struct SubTupleBinding<'a> { #[primary_span] - #[label] + #[label("this is only allowed in slice patterns")] #[suggestion( - ast_lowering_sub_tuple_binding_suggestion, + "if you don't need to use the contents of {$ident}, discard the tuple's remaining fields", style = "verbose", code = "..", applicability = "maybe-incorrect" @@ -306,63 +321,67 @@ pub(crate) struct SubTupleBinding<'a> { } #[derive(Diagnostic)] -#[diag(ast_lowering_extra_double_dot)] +#[diag("`..` can only be used once per {$ctx} pattern")] pub(crate) struct ExtraDoubleDot<'a> { #[primary_span] - #[label] + #[label("can only be used once per {$ctx} pattern")] pub span: Span, - #[label(ast_lowering_previously_used_here)] + #[label("previously used here")] pub prev_span: Span, pub ctx: &'a str, } #[derive(Diagnostic)] -#[note] -#[diag(ast_lowering_misplaced_double_dot)] +#[note("only allowed in tuple, tuple struct, and slice patterns")] +#[diag("`..` patterns are not allowed here")] pub(crate) struct MisplacedDoubleDot { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_match_arm_with_no_body)] +#[diag("`match` arm with no body")] pub(crate) struct MatchArmWithNoBody { #[primary_span] pub span: Span, - #[suggestion(code = " => todo!(),", applicability = "has-placeholders")] + #[suggestion( + "add a body after the pattern", + code = " => todo!(),", + applicability = "has-placeholders" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_never_pattern_with_body)] +#[diag("a never pattern is always unreachable")] pub(crate) struct NeverPatternWithBody { #[primary_span] - #[label] - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[label("this will never be executed")] + #[suggestion("remove this expression", code = "", applicability = "maybe-incorrect")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_never_pattern_with_guard)] +#[diag("a guard on a never pattern will never be run")] pub(crate) struct NeverPatternWithGuard { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[suggestion("remove this guard", code = "", applicability = "maybe-incorrect")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_arbitrary_expression_in_pattern)] +#[diag("arbitrary expressions aren't allowed in patterns")] pub(crate) struct ArbitraryExpressionInPattern { #[primary_span] pub span: Span, - #[note(ast_lowering_pattern_from_macro_note)] + #[note("the `expr` fragment specifier forces the metavariable's content to be an expression")] pub pattern_from_macro_note: bool, - #[help(ast_lowering_const_block_in_pattern_help)] + #[help("use a named `const`-item or an `if`-guard (`x if x == const {\"{ ... }\"}`) instead")] pub const_block_in_pattern_help: bool, } #[derive(Diagnostic)] -#[diag(ast_lowering_inclusive_range_with_no_end)] +#[diag("inclusive range with no end")] pub(crate) struct InclusiveRangeWithNoEnd { #[primary_span] pub span: Span, @@ -370,7 +389,7 @@ pub(crate) struct InclusiveRangeWithNoEnd { #[derive(Subdiagnostic)] #[multipart_suggestion( - ast_lowering_bad_return_type_notation_output_suggestion, + "use the right argument notation and remove the return type", applicability = "machine-applicable", style = "verbose" )] @@ -384,26 +403,36 @@ pub(crate) struct RTNSuggestion { #[derive(Diagnostic)] pub(crate) enum BadReturnTypeNotation { - #[diag(ast_lowering_bad_return_type_notation_inputs)] + #[diag("argument types not allowed with return type notation")] Inputs { #[primary_span] - #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the input types", + code = "(..)", + applicability = "machine-applicable", + style = "verbose" + )] span: Span, }, - #[diag(ast_lowering_bad_return_type_notation_output)] + #[diag("return type not allowed with return type notation")] Output { #[primary_span] span: Span, #[subdiagnostic] suggestion: RTNSuggestion, }, - #[diag(ast_lowering_bad_return_type_notation_needs_dots)] + #[diag("return type notation arguments must be elided with `..`")] NeedsDots { #[primary_span] - #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "use the correct syntax by adding `..` to the arguments", + code = "(..)", + applicability = "machine-applicable", + style = "verbose" + )] span: Span, }, - #[diag(ast_lowering_bad_return_type_notation_position)] + #[diag("return type notation not allowed in this position yet")] Position { #[primary_span] span: Span, @@ -411,14 +440,14 @@ pub(crate) enum BadReturnTypeNotation { } #[derive(Diagnostic)] -#[diag(ast_lowering_generic_param_default_in_binder)] +#[diag("defaults for generic parameters are not allowed in `for<...>` binders")] pub(crate) struct GenericParamDefaultInBinder { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_async_bound_not_on_trait)] +#[diag("`async` bound modifier only allowed on trait, not `{$descr}`")] pub(crate) struct AsyncBoundNotOnTrait { #[primary_span] pub span: Span, @@ -426,30 +455,37 @@ pub(crate) struct AsyncBoundNotOnTrait { } #[derive(Diagnostic)] -#[diag(ast_lowering_async_bound_only_for_fn_traits)] +#[diag("`async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits")] pub(crate) struct AsyncBoundOnlyForFnTraits { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_no_precise_captures_on_apit)] +#[diag("`use<...>` precise capturing syntax not allowed in argument-position `impl Trait`")] pub(crate) struct NoPreciseCapturesOnApit { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_yield_in_closure)] +#[diag("`yield` can only be used in `#[coroutine]` closures, or `gen` blocks")] pub(crate) struct YieldInClosure { #[primary_span] pub span: Span, - #[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "use `#[coroutine]` to make this closure a coroutine", + code = "#[coroutine] ", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggestion: Option, } #[derive(Diagnostic)] -#[diag(ast_lowering_invalid_legacy_const_generic_arg)] +#[diag( + "invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items" +)] pub(crate) struct InvalidLegacyConstGenericArg { #[primary_span] pub span: Span, @@ -459,7 +495,7 @@ pub(crate) struct InvalidLegacyConstGenericArg { #[derive(Subdiagnostic)] #[multipart_suggestion( - ast_lowering_invalid_legacy_const_generic_arg_suggestion, + "try using a const generic argument instead", applicability = "maybe-incorrect" )] pub(crate) struct UseConstGenericArg { @@ -472,21 +508,21 @@ pub(crate) struct UseConstGenericArg { } #[derive(Diagnostic)] -#[diag(ast_lowering_union_default_field_values)] +#[diag("unions cannot have default field values")] pub(crate) struct UnionWithDefault { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_delegation_unresolved_callee)] +#[diag("failed to resolve delegation callee")] pub(crate) struct UnresolvedDelegationCallee { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_lowering_delegation_cycle_in_signature_resolution)] +#[diag("encountered a cycle during delegation signature resolution")] pub(crate) struct CycleInDelegationSignatureResolution { #[primary_span] pub span: Span, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 9fbfeb7a11e6..051bebfbec00 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use rustc_ast::*; use rustc_ast_pretty::pprust::expr_to_string; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_errors::inline_fluent; use rustc_hir as hir; use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; @@ -28,9 +29,7 @@ use super::{ GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt, }; use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure}; -use crate::{ - AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated, -}; +use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope}; struct WillCreateDefIdsVisitor {} @@ -1703,7 +1702,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &self.tcx.sess, sym::yield_expr, span, - fluent_generated::ast_lowering_yield, + inline_fluent!("yield syntax is experimental"), ) .emit(); } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8c6ee9d6bc63..e4f431fd2431 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -88,8 +88,6 @@ mod pat; mod path; pub mod stability; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering, diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d184b6c8947c..f2b972da9789 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -9,7 +9,6 @@ anstyle = "1.0.13" jiff = { version = "0.2.5", default-features = false, features = ["std"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_borrowck = { path = "../rustc_borrowck" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc61..a37f0f92697b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -114,7 +114,6 @@ pub fn default_translator() -> Translator { pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ // tidy-alphabetical-start - rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, From caaca04e681adac08929fbae6a98893f80b2e0f2 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 4 Feb 2026 09:29:07 -0600 Subject: [PATCH 45/81] bootstrap: exclude hexagon-unknown-qurt from llvm-libunwind default Hexagon Linux targets (hexagon-unknown-linux-musl) use in-tree llvm-libunwind for stack unwinding. However, hexagon-unknown-qurt uses libc_eh from the Hexagon SDK instead. --- src/bootstrap/src/core/config/config.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 07405a0309fe..61eef3c01592 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1859,11 +1859,17 @@ impl Config { .get(&target) .and_then(|t| t.llvm_libunwind) .or(self.llvm_libunwind_default) - .unwrap_or(if target.contains("fuchsia") || target.contains("hexagon") { - LlvmLibunwind::InTree - } else { - LlvmLibunwind::No - }) + .unwrap_or( + if target.contains("fuchsia") + || (target.contains("hexagon") && !target.contains("qurt")) + { + // Fuchsia and Hexagon Linux use in-tree llvm-libunwind. + // Hexagon QuRT uses libc_eh from the Hexagon SDK instead. + LlvmLibunwind::InTree + } else { + LlvmLibunwind::No + }, + ) } pub fn split_debuginfo(&self, target: TargetSelection) -> SplitDebuginfo { From 78b55fc337e0ff9eb5f83aef0031abee0c8996b3 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Wed, 4 Feb 2026 23:29:18 +0800 Subject: [PATCH 46/81] Fix incorrect RSS on systems with non-4K page size `get_resident_set_size` computed RSS by multiplying the number of pages from `/proc/self/statm` with a hard-coded 4096-byte page size. This produces incorrect results on systems where the runtime page size is not 4 KiB. Use `sysconf(_SC_PAGESIZE)` to determine the actual page size at runtime so the RSS reported in `-Z time-passes` output is accurate across platforms. --- compiler/rustc_data_structures/src/profiling.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 4a9551a60cf9..b04caa69adfb 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -995,12 +995,14 @@ cfg_select! { } unix => { pub fn get_resident_set_size() -> Option { + use libc::{sysconf, _SC_PAGESIZE}; let field = 1; let contents = fs::read("/proc/self/statm").ok()?; let contents = String::from_utf8(contents).ok()?; let s = contents.split_whitespace().nth(field)?; let npages = s.parse::().ok()?; - Some(npages * 4096) + // SAFETY: `sysconf(_SC_PAGESIZE)` has no side effects and is safe to call. + Some(npages * unsafe { sysconf(_SC_PAGESIZE) } as usize) } } _ => { From 34c6ae0d488f34be9f9d3576a8dae675d5e30d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 4 Feb 2026 16:41:21 +0100 Subject: [PATCH 47/81] Fix GitHub CI summary in CodeBuild --- src/ci/docker/run.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 691b8b8deb81..6c35105225c0 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -359,11 +359,11 @@ docker \ rust-ci \ "${command[@]}" -if isCI; then - cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}" -fi - if [ -f /.dockerenv ]; then rm -rf $objdir docker cp checkout:/checkout/obj $objdir fi + +if isCI; then + cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}" +fi From ef00ebfdec7d9d257ef19dc9d6d17bf64df0373d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:17:25 +0000 Subject: [PATCH 48/81] Remove is_ctfe_mir_available query It isn't called anywhere anymore. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 ---- compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 1 - compiler/rustc_middle/src/queries.rs | 5 ----- compiler/rustc_mir_transform/src/lib.rs | 1 - 4 files changed, 11 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index c7423386a771..bd5b3893e4e8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1298,10 +1298,6 @@ impl<'a> CrateMetadataRef<'a> { } } - fn is_ctfe_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { - self.root.tables.mir_for_ctfe.get((self, tcx), id).is_some() - } - fn is_item_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { self.root.tables.optimized_mir.get((self, tcx), id).is_some() } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index b1f3bafd92fb..c6c87534851c 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -324,7 +324,6 @@ provide! { tcx, def_id, other, cdata, inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(tcx, def_id.index)) } is_mir_available => { cdata.is_item_mir_available(tcx, def_id.index) } - is_ctfe_mir_available => { cdata.is_ctfe_mir_available(tcx, def_id.index) } cross_crate_inlinable => { table_direct } dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index ca8e5e90318d..de2298914438 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1588,11 +1588,6 @@ rustc_queries! { separate_provide_extern } - query is_ctfe_mir_available(key: DefId) -> bool { - desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } query is_mir_available(key: DefId) -> bool { desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 0e6a1a414e45..96ec7f1e9bdc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -231,7 +231,6 @@ pub fn provide(providers: &mut Providers) { optimized_mir, check_liveness: liveness::check_liveness, is_mir_available, - is_ctfe_mir_available: is_mir_available, mir_callgraph_cyclic: inline::cycle::mir_callgraph_cyclic, mir_inliner_callees: inline::cycle::mir_inliner_callees, promoted_mir, From 1e6f7845ed334829c8a0caed8640c9bfb708de22 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:21:52 +0000 Subject: [PATCH 49/81] Avoid encoding optimized MIR for constructors We only use mir_for_ctfe for them anyway in instance_mir. This does prevent MIR inlining of constructor calls, but constructor calls that are inlinable during MIR optimizations are rare anyway given that MIR building already inlines all direct calls to constructors. --- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++------ compiler/rustc_monomorphize/src/collector.rs | 4 +++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 471c19ed4d4e..2905eb819b24 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1102,12 +1102,8 @@ fn should_encode_mir( def_id: LocalDefId, ) -> (bool, bool) { match tcx.def_kind(def_id) { - // Constructors - DefKind::Ctor(_, _) => { - let mir_opt_base = tcx.sess.opts.output_types.should_codegen() - || tcx.sess.opts.unstable_opts.always_encode_mir; - (true, mir_opt_base) - } + // instance_mir uses mir_for_ctfe rather than optimized_mir for constructors + DefKind::Ctor(_, _) => (true, false), // Constants DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst | DefKind::Const => { (true, false) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 81d46e3b5b0d..3362038ed091 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1084,7 +1084,9 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> return false; } - if !tcx.is_mir_available(def_id) { + // See comment in should_encode_mir in rustc_metadata for why we don't report + // an error for constructors. + if !tcx.is_mir_available(def_id) && !matches!(tcx.def_kind(def_id), DefKind::Ctor(..)) { tcx.dcx().emit_fatal(NoOptimizedMir { span: tcx.def_span(def_id), crate_name: tcx.crate_name(def_id.krate), From 05921d41e9ffeda1a5e3a2147818e4e5c9824279 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:23:29 +0000 Subject: [PATCH 50/81] Only call generics_of query in should_encode_mir when necessary --- compiler/rustc_metadata/src/rmeta/encoder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2905eb819b24..30f8a753b9b7 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1113,11 +1113,10 @@ fn should_encode_mir( DefKind::SyntheticCoroutineBody => (false, true), // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { - let generics = tcx.generics_of(def_id); let opt = tcx.sess.opts.unstable_opts.always_encode_mir || (tcx.sess.opts.output_types.should_codegen() && reachable_set.contains(&def_id) - && (generics.requires_monomorphization(tcx) + && (tcx.generics_of(def_id).requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id))); // The function has a `const` modifier or is in a `const trait`. let is_const_fn = tcx.is_const_fn(def_id.to_def_id()); From 607ac4bb840bc4b533b0758755a41b22a17d36b9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 4 Feb 2026 17:09:57 +0100 Subject: [PATCH 51/81] Remove rustdoc GUI flaky test --- tests/rustdoc-gui/globals.goml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 tests/rustdoc-gui/globals.goml diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml deleted file mode 100644 index 7fd9c5bfb6f2..000000000000 --- a/tests/rustdoc-gui/globals.goml +++ /dev/null @@ -1,20 +0,0 @@ -// Make sure search stores its data in `window` -// It needs to use a global to avoid racing on search-index.js and search.js -// https://github.com/rust-lang/rust/pull/118961 -include: "utils.goml" - -// URL query -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa" -wait-for: "#search-tabs" -wait-for-window-property-false: {"searchIndex": null} - -// Form input -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -call-function: ("perform-search", {"query": "Foo"}) -wait-for-window-property-false: {"searchIndex": null} - -// source sidebar -go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" -click: "#sidebar-button" -wait-for: "#src-sidebar details" -assert-window-property: {"searchIndex": null} From d445a2aabb70d0c0280eaf2523c54dc1d51d5d0f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 17:23:35 +0100 Subject: [PATCH 52/81] Convert to inline diagnostics in `rustc_codegen_ssa` --- Cargo.lock | 1 - compiler/rustc_codegen_ssa/Cargo.toml | 1 - compiler/rustc_codegen_ssa/messages.ftl | 397 ----------------- compiler/rustc_codegen_ssa/src/back/apple.rs | 12 +- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 443 ++++++++++--------- compiler/rustc_codegen_ssa/src/lib.rs | 2 - compiler/rustc_driver_impl/src/lib.rs | 1 - 8 files changed, 252 insertions(+), 607 deletions(-) delete mode 100644 compiler/rustc_codegen_ssa/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612..32fa08784bed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3673,7 +3673,6 @@ dependencies = [ "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hashes", "rustc_hir", diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 3d045a02fef1..864220635120 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -18,7 +18,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl deleted file mode 100644 index a49f411a7df6..000000000000 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ /dev/null @@ -1,397 +0,0 @@ -codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender - -codegen_ssa_aarch64_softfloat_neon = enabling the `neon` target feature on the current target is unsound due to ABI issues - -codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} - -codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work - -codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} - -codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty - -codegen_ssa_bpf_staticlib_not_supported = linking static libraries is not supported for BPF - -codegen_ssa_cgu_not_recorded = - CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded - -codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. - -codegen_ssa_compiler_builtins_cannot_call = - `compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}` - -codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} - -codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} - -codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C target-cpu` - -codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} - -codegen_ssa_dlltool_fail_import_library = - dlltool could not create import library with {$dlltool_path} {$dlltool_args}: - {$stdout} - {$stderr} - -codegen_ssa_dynamic_linking_with_lto = - cannot prefer dynamic linking when performing LTO - .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO - -codegen_ssa_error_calling_dlltool = - error calling dlltool '{$dlltool_path}': {$error} - -codegen_ssa_error_creating_import_library = - error creating import library for {$lib_name}: {$error} - -codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} - -codegen_ssa_error_writing_def_file = - error writing .DEF file: {$error} - -codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified - -codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error} - -codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err} - -codegen_ssa_failed_to_write = failed to write {$path}: {$error} - -codegen_ssa_feature_not_valid = the feature named `{$feature}` is not valid for this target - .label = `{$feature}` is not valid for this target - .help = consider removing the leading `+` in the feature name - -codegen_ssa_field_associated_value_expected = associated value expected for `{$name}` - -codegen_ssa_forbidden_ctarget_feature = - target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason} - .note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -codegen_ssa_forbidden_ctarget_feature_issue = for more information, see issue #116344 - -codegen_ssa_forbidden_target_feature_attr = - target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason} - -codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced - -codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced - -codegen_ssa_incorrect_cgu_reuse_type = - CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> - [one] {"at least "} - *[other] {""} - }`{$expected_reuse}` - -codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. - -codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` - -codegen_ssa_invalid_monomorphization_cast_wide_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}` - -codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type - -codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type - -codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}` - -codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}` - -codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` - -codegen_ssa_invalid_monomorphization_mask_wrong_element_type = invalid monomorphization of `{$name}` intrinsic: expected mask element type to be an integer, found `{$ty}` - -codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` - -codegen_ssa_invalid_monomorphization_non_scalable_type = invalid monomorphization of `{$name}` intrinsic: expected non-scalable type, found scalable type `{$ty}` -codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}` - -codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}` - -codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len}) - -codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` - -codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}` - -codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}` - -codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}` - -codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64 - -codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} - -codegen_ssa_link_exe_status_stack_buffer_overrun = 0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN` - .abort_note = this may have been caused by a program abort and not a stack buffer overrun - .event_log_note = consider checking the Application Event Log for Windows Error Reporting events to see the fail fast error code - -codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error - -codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker - -codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} - -codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker - -codegen_ssa_linker_not_found = linker `{$linker_path}` not found - .note = {$error} - -codegen_ssa_linker_output = {$inner} - -codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker - -codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} - -codegen_ssa_lto_disallowed = lto can only be run for executables, cdylibs and static library outputs - -codegen_ssa_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto` - -codegen_ssa_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto` - -codegen_ssa_malformed_cgu_name = - found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case). - -codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload - -codegen_ssa_missing_features = add the missing features in a `target_feature` attribute - -codegen_ssa_missing_query_depgraph = - found CGU-reuse attribute but `-Zquery-dep-graph` was not specified - -codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found - -codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions - -codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times - .help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point - -codegen_ssa_no_field = no field `{$name}` - -codegen_ssa_no_module_named = - no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names} - -codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} - -codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't - -codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} - .note = {$output} - -codegen_ssa_read_file = failed to read file: {$message} - -codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer - -codegen_ssa_requires_rust_abi = `#[track_caller]` requires Rust ABI - -codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error} - -codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`) - -codegen_ssa_rlib_missing_format = could not find formats for rlibs - -codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}` - -codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file - -codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected - -codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot - -codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time - -codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link - -codegen_ssa_static_library_native_artifacts = link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. - -codegen_ssa_static_library_native_artifacts_to_file = native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms. - -codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status} - .note = {$output} - -codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} - -codegen_ssa_target_feature_disable_or_enable = - the target features {$features} must all be either enabled or disabled together - -codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method - .label = cannot be applied to safe trait method - .label_def = not an `unsafe` function - -codegen_ssa_thorin_decompress_data = failed to decompress compressed section - -codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit}) - -codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data - -codegen_ssa_thorin_gimli_read = {$error} -codegen_ssa_thorin_gimli_write = {$error} - -codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format} - -codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object - -codegen_ssa_thorin_io = {$error} -codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id}) - -codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found - -codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}` - -codegen_ssa_thorin_mixed_input_encodings = input objects have mixed encodings - -codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections - -codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package - -codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset} - -codegen_ssa_thorin_no_compilation_units = input object has no compilation units - -codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit - -codegen_ssa_thorin_not_output_object_created = no output object was created from inputs - -codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier) - -codegen_ssa_thorin_object_read = {$error} -codegen_ssa_thorin_object_write = {$error} -codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section - -codegen_ssa_thorin_parse_archive_member = failed to parse archive member - -codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section - -codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file - -codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind - -codegen_ssa_thorin_parse_input_object_file = failed to parse input object file - -codegen_ssa_thorin_parse_unit = failed to parse unit - -codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations - -codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute - -codegen_ssa_thorin_parse_unit_header = failed to parse unit header - -codegen_ssa_thorin_read_input_failure = failed to read input file - -codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset} - -codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index - -codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index - -codegen_ssa_thorin_section_without_name = section without name at offset {$offset} - -codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section - -codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit - -codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index - -codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset} - -codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}` - .note = {$error} - .command_note = {$command_formatted} - -codegen_ssa_unable_to_run = unable to run `{$util}`: {$error} - -codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} - -codegen_ssa_unable_to_write_debugger_visualizer = unable to write debugger visualizer file `{$path}`: {$error} - -codegen_ssa_unknown_archive_kind = - don't know how to build archive of type: {$kind} - -codegen_ssa_unknown_ctarget_feature = - unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}` - .note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future - .possible_feature = you might have meant: `{$rust_feature}` - .consider_filing_feature_request = consider filing a feature request - -codegen_ssa_unknown_ctarget_feature_prefix = - unknown feature specified for `-Ctarget-feature`: `{$feature}` - .note = features must begin with a `+` to enable or `-` to disable it - -codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified - -codegen_ssa_unstable_ctarget_feature = - unstable feature specified for `-Ctarget-feature`: `{$feature}` - .note = this feature is not stably supported; its behavior can change in the future - -codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target - -codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib) - -codegen_ssa_version_script_write_failure = failed to write version script: {$error} - -codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload - -codegen_ssa_xcrun_about = - the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file - -codegen_ssa_xcrun_command_line_tools_insufficient = - when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode - -codegen_ssa_xcrun_failed_invoking = invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error} - -codegen_ssa_xcrun_found_developer_dir = found active developer directory at "{$developer_dir}" - -# `xcrun` already outputs a message about missing Xcode installation, so we only augment it with details about env vars. -codegen_ssa_xcrun_no_developer_dir = - pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable - -codegen_ssa_xcrun_sdk_path_warning = output of `xcrun` while finding {$sdk_name}.sdk - .note = {$stderr} - -codegen_ssa_xcrun_unsuccessful = failed running `{$command_formatted}` to find {$sdk_name}.sdk - .note = {$stdout}{$stderr} diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index 23808ade6c85..3ed5793d10c5 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use std::process::Command; use itertools::Itertools; +use rustc_errors::inline_fluent; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::Session; pub(super) use rustc_target::spec::apple::OSVersion; @@ -10,7 +11,6 @@ use rustc_target::spec::{Arch, Env, Os, Target}; use tracing::debug; use crate::errors::{XcrunError, XcrunSdkPathWarning}; -use crate::fluent_generated as fluent; #[cfg(test)] mod tests; @@ -185,19 +185,21 @@ pub(super) fn get_sdk_root(sess: &Session) -> Option { // FIXME(madsmtm): Make this a lint, to allow deny warnings to work. // (Or fix ). let mut diag = sess.dcx().create_warn(err); - diag.note(fluent::codegen_ssa_xcrun_about); + diag.note(inline_fluent!("the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file")); // Recognize common error cases, and give more Rust-specific error messages for those. if let Some(developer_dir) = xcode_select_developer_dir() { diag.arg("developer_dir", &developer_dir); - diag.note(fluent::codegen_ssa_xcrun_found_developer_dir); + diag.note(inline_fluent!( + "found active developer directory at \"{$developer_dir}\"" + )); if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") { if sdk_name != "MacOSX" { - diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient); + diag.help(inline_fluent!("when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode")); } } } else { - diag.help(fluent::codegen_ssa_xcrun_no_developer_dir); + diag.help(inline_fluent!("pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable")); } diag.emit(); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db86e2f..9029c798b64f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -662,7 +662,7 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out } #[derive(LintDiagnostic)] -#[diag(codegen_ssa_linker_output)] +#[diag("{$inner}")] /// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just /// end up with inconsistent languages within the same diagnostic. struct LinkerOutput { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 6a97de4c2b13..742e05973ee5 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -9,6 +9,7 @@ use std::process::ExitStatus; use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, + inline_fluent, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::layout::LayoutError; @@ -17,10 +18,14 @@ use rustc_span::{Span, Symbol}; use crate::assert_module_sources::CguReuse; use crate::back::command::Command; -use crate::fluent_generated as fluent; #[derive(Diagnostic)] -#[diag(codegen_ssa_incorrect_cgu_reuse_type)] +#[diag( + "CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> + [one] {\"at least \"} + *[other] {\"\"} + }`{$expected_reuse}`" +)] pub(crate) struct IncorrectCguReuseType<'a> { #[primary_span] pub span: Span, @@ -31,14 +36,14 @@ pub(crate) struct IncorrectCguReuseType<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_cgu_not_recorded)] +#[diag("CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded")] pub(crate) struct CguNotRecorded<'a> { pub cgu_user_name: &'a str, pub cgu_name: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_reuse_kind)] +#[diag("unknown cgu-reuse-kind `{$kind}` specified")] pub(crate) struct UnknownReuseKind { #[primary_span] pub span: Span, @@ -46,14 +51,16 @@ pub(crate) struct UnknownReuseKind { } #[derive(Diagnostic)] -#[diag(codegen_ssa_missing_query_depgraph)] +#[diag("found CGU-reuse attribute but `-Zquery-dep-graph` was not specified")] pub(crate) struct MissingQueryDepGraph { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_malformed_cgu_name)] +#[diag( + "found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case)." +)] pub(crate) struct MalformedCguName { #[primary_span] pub span: Span, @@ -62,7 +69,7 @@ pub(crate) struct MalformedCguName { } #[derive(Diagnostic)] -#[diag(codegen_ssa_no_module_named)] +#[diag("no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}")] pub(crate) struct NoModuleNamed<'a> { #[primary_span] pub span: Span, @@ -72,7 +79,7 @@ pub(crate) struct NoModuleNamed<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_field_associated_value_expected)] +#[diag("associated value expected for `{$name}`")] pub(crate) struct FieldAssociatedValueExpected { #[primary_span] pub span: Span, @@ -80,7 +87,7 @@ pub(crate) struct FieldAssociatedValueExpected { } #[derive(Diagnostic)] -#[diag(codegen_ssa_no_field)] +#[diag("no field `{$name}`")] pub(crate) struct NoField { #[primary_span] pub span: Span, @@ -88,56 +95,56 @@ pub(crate) struct NoField { } #[derive(Diagnostic)] -#[diag(codegen_ssa_lib_def_write_failure)] +#[diag("failed to write lib.def file: {$error}")] pub(crate) struct LibDefWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_version_script_write_failure)] +#[diag("failed to write version script: {$error}")] pub(crate) struct VersionScriptWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_symbol_file_write_failure)] +#[diag("failed to write symbols file: {$error}")] pub(crate) struct SymbolFileWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ld64_unimplemented_modifier)] +#[diag("`as-needed` modifier not implemented yet for ld64")] pub(crate) struct Ld64UnimplementedModifier; #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_unsupported_modifier)] +#[diag("`as-needed` modifier not supported for current linker")] pub(crate) struct LinkerUnsupportedModifier; #[derive(Diagnostic)] -#[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)] +#[diag("exporting symbols not implemented yet for L4Bender")] pub(crate) struct L4BenderExportingSymbolsUnimplemented; #[derive(Diagnostic)] -#[diag(codegen_ssa_no_natvis_directory)] +#[diag("error enumerating natvis directory: {$error}")] pub(crate) struct NoNatvisDirectory { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_no_saved_object_file)] +#[diag("cached cgu {$cgu_name} should have an object file, but doesn't")] pub(crate) struct NoSavedObjectFile<'a> { pub cgu_name: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_requires_rust_abi, code = E0737)] +#[diag("`#[track_caller]` requires Rust ABI", code = E0737)] pub(crate) struct RequiresRustAbi { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_copy_path_buf)] +#[diag("unable to copy {$source_file} to {$output_path}: {$error}")] pub(crate) struct CopyPathBuf { pub source_file: PathBuf, pub output_path: PathBuf, @@ -146,7 +153,7 @@ pub(crate) struct CopyPathBuf { // Reports Paths using `Debug` implementation rather than Path's `Display` implementation. #[derive(Diagnostic)] -#[diag(codegen_ssa_copy_path)] +#[diag("could not copy {$from} to {$to}: {$error}")] pub struct CopyPath<'a> { from: DebugArgPath<'a>, to: DebugArgPath<'a>, @@ -168,38 +175,42 @@ impl IntoDiagArg for DebugArgPath<'_> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_binary_output_to_tty)] +#[diag( + "option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty" +)] pub struct BinaryOutputToTty { pub shorthand: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ignoring_emit_path)] +#[diag("ignoring emit path because multiple .{$extension} files were produced")] pub struct IgnoringEmitPath { pub extension: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ignoring_output)] +#[diag("ignoring -o because multiple .{$extension} files were produced")] pub struct IgnoringOutput { pub extension: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_create_temp_dir)] +#[diag("couldn't create a temp dir: {$error}")] pub(crate) struct CreateTempDir { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_add_native_library)] +#[diag("failed to add native library {$library_path}: {$error}")] pub(crate) struct AddNativeLibrary { pub library_path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_external_func_decl)] +#[diag( + "multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions" +)] pub(crate) struct MultipleExternalFuncDecl<'a> { #[primary_span] pub span: Span, @@ -209,16 +220,18 @@ pub(crate) struct MultipleExternalFuncDecl<'a> { #[derive(Diagnostic)] pub enum LinkRlibError { - #[diag(codegen_ssa_rlib_missing_format)] + #[diag("could not find formats for rlibs")] MissingFormat, - #[diag(codegen_ssa_rlib_only_rmeta_found)] + #[diag("could not find rlib for: `{$crate_name}`, found rmeta (metadata) file")] OnlyRmetaFound { crate_name: Symbol }, - #[diag(codegen_ssa_rlib_not_found)] + #[diag("could not find rlib for: `{$crate_name}`")] NotFound { crate_name: Symbol }, - #[diag(codegen_ssa_rlib_incompatible_dependency_formats)] + #[diag( + "`{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)" + )] IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String }, } @@ -228,122 +241,122 @@ impl Diagnostic<'_, G> for ThorinErrorWrapper { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { let build = |msg| Diag::new(dcx, level, msg); match self.0 { - thorin::Error::ReadInput(_) => build(fluent::codegen_ssa_thorin_read_input_failure), + thorin::Error::ReadInput(_) => build(inline_fluent!("failed to read input file")), thorin::Error::ParseFileKind(_) => { - build(fluent::codegen_ssa_thorin_parse_input_file_kind) + build(inline_fluent!("failed to parse input file kind")) } thorin::Error::ParseObjectFile(_) => { - build(fluent::codegen_ssa_thorin_parse_input_object_file) + build(inline_fluent!("failed to parse input object file")) } thorin::Error::ParseArchiveFile(_) => { - build(fluent::codegen_ssa_thorin_parse_input_archive_file) + build(inline_fluent!("failed to parse input archive file")) } thorin::Error::ParseArchiveMember(_) => { - build(fluent::codegen_ssa_thorin_parse_archive_member) + build(inline_fluent!("failed to parse archive member")) } - thorin::Error::InvalidInputKind => build(fluent::codegen_ssa_thorin_invalid_input_kind), - thorin::Error::DecompressData(_) => build(fluent::codegen_ssa_thorin_decompress_data), + thorin::Error::InvalidInputKind => build(inline_fluent!("input is not an archive or elf object")), + thorin::Error::DecompressData(_) => build(inline_fluent!("failed to decompress compressed section")), thorin::Error::NamelessSection(_, offset) => { - build(fluent::codegen_ssa_thorin_section_without_name) + build(inline_fluent!("section without name at offset {$offset}")) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::RelocationWithInvalidSymbol(section, offset) => { - build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol) + build(inline_fluent!("relocation with invalid symbol for section `{$section}` at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::MultipleRelocations(section, offset) => { - build(fluent::codegen_ssa_thorin_multiple_relocations) + build(inline_fluent!("multiple relocations for section `{$section}` at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::UnsupportedRelocation(section, offset) => { - build(fluent::codegen_ssa_thorin_unsupported_relocation) + build(inline_fluent!("unsupported relocation for section {$section} at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } - thorin::Error::MissingDwoName(id) => build(fluent::codegen_ssa_thorin_missing_dwo_name) + thorin::Error::MissingDwoName(id) => build(inline_fluent!("missing path attribute to DWARF object ({$id})")) .with_arg("id", format!("0x{id:08x}")), thorin::Error::NoCompilationUnits => { - build(fluent::codegen_ssa_thorin_no_compilation_units) + build(inline_fluent!("input object has no compilation units")) } - thorin::Error::NoDie => build(fluent::codegen_ssa_thorin_no_die), + thorin::Error::NoDie => build(inline_fluent!("no top-level debugging information entry in compilation/type unit")), thorin::Error::TopLevelDieNotUnit => { - build(fluent::codegen_ssa_thorin_top_level_die_not_unit) + build(inline_fluent!("top-level debugging information entry is not a compilation/type unit")) } thorin::Error::MissingRequiredSection(section) => { - build(fluent::codegen_ssa_thorin_missing_required_section) + build(inline_fluent!("input object missing required section `{$section}`")) .with_arg("section", section) } thorin::Error::ParseUnitAbbreviations(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_abbreviations) + build(inline_fluent!("failed to parse unit abbreviations")) } thorin::Error::ParseUnitAttribute(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_attribute) + build(inline_fluent!("failed to parse unit attribute")) } thorin::Error::ParseUnitHeader(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_header) + build(inline_fluent!("failed to parse unit header")) } - thorin::Error::ParseUnit(_) => build(fluent::codegen_ssa_thorin_parse_unit), + thorin::Error::ParseUnit(_) => build(inline_fluent!("failed to parse unit")), thorin::Error::IncompatibleIndexVersion(section, format, actual) => { - build(fluent::codegen_ssa_thorin_incompatible_index_version) + build(inline_fluent!("incompatible `{$section}` index version: found version {$actual}, expected version {$format}")) .with_arg("section", section) .with_arg("actual", actual) .with_arg("format", format) } thorin::Error::OffsetAtIndex(_, index) => { - build(fluent::codegen_ssa_thorin_offset_at_index).with_arg("index", index) + build(inline_fluent!("read offset at index {$index} of `.debug_str_offsets.dwo` section")).with_arg("index", index) } thorin::Error::StrAtOffset(_, offset) => { - build(fluent::codegen_ssa_thorin_str_at_offset) + build(inline_fluent!("read string at offset {$offset} of `.debug_str.dwo` section")) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::ParseIndex(_, section) => { - build(fluent::codegen_ssa_thorin_parse_index).with_arg("section", section) + build(inline_fluent!("failed to parse `{$section}` index section")).with_arg("section", section) } thorin::Error::UnitNotInIndex(unit) => { - build(fluent::codegen_ssa_thorin_unit_not_in_index) + build(inline_fluent!("unit {$unit} from input package is not in its index")) .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::RowNotInIndex(_, row) => { - build(fluent::codegen_ssa_thorin_row_not_in_index).with_arg("row", row) + build(inline_fluent!("row {$row} found in index's hash table not present in index")).with_arg("row", row) } - thorin::Error::SectionNotInRow => build(fluent::codegen_ssa_thorin_section_not_in_row), - thorin::Error::EmptyUnit(unit) => build(fluent::codegen_ssa_thorin_empty_unit) + thorin::Error::SectionNotInRow => build(inline_fluent!("section not found in unit's row in index")), + thorin::Error::EmptyUnit(unit) => build(inline_fluent!("unit {$unit} in input DWARF object with no data")) .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MultipleDebugInfoSection => { - build(fluent::codegen_ssa_thorin_multiple_debug_info_section) + build(inline_fluent!("multiple `.debug_info.dwo` sections")) } thorin::Error::MultipleDebugTypesSection => { - build(fluent::codegen_ssa_thorin_multiple_debug_types_section) + build(inline_fluent!("multiple `.debug_types.dwo` sections in a package")) } - thorin::Error::NotSplitUnit => build(fluent::codegen_ssa_thorin_not_split_unit), - thorin::Error::DuplicateUnit(unit) => build(fluent::codegen_ssa_thorin_duplicate_unit) + thorin::Error::NotSplitUnit => build(inline_fluent!("regular compilation unit in object (missing dwo identifier)")), + thorin::Error::DuplicateUnit(unit) => build(inline_fluent!("duplicate split compilation unit ({$unit})")) .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MissingReferencedUnit(unit) => { - build(fluent::codegen_ssa_thorin_missing_referenced_unit) + build(inline_fluent!("unit {$unit} referenced by executable was not found")) .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::NoOutputObjectCreated => { - build(fluent::codegen_ssa_thorin_not_output_object_created) + build(inline_fluent!("no output object was created from inputs")) } thorin::Error::MixedInputEncodings => { - build(fluent::codegen_ssa_thorin_mixed_input_encodings) + build(inline_fluent!("input objects have mixed encodings")) } thorin::Error::Io(e) => { - build(fluent::codegen_ssa_thorin_io).with_arg("error", format!("{e}")) + build(inline_fluent!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::ObjectRead(e) => { - build(fluent::codegen_ssa_thorin_object_read).with_arg("error", format!("{e}")) + build(inline_fluent!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::ObjectWrite(e) => { - build(fluent::codegen_ssa_thorin_object_write).with_arg("error", format!("{e}")) + build(inline_fluent!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::GimliRead(e) => { - build(fluent::codegen_ssa_thorin_gimli_read).with_arg("error", format!("{e}")) + build(inline_fluent!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::GimliWrite(e) => { - build(fluent::codegen_ssa_thorin_gimli_write).with_arg("error", format!("{e}")) + build(inline_fluent!("{$error}")).with_arg("error", format!("{e}")) } _ => unimplemented!("Untranslated thorin error"), } @@ -361,7 +374,11 @@ pub(crate) struct LinkingFailed<'a> { impl Diagnostic<'_, G> for LinkingFailed<'_> { fn into_diag(mut self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("linking with `{$linker_path}` failed: {$exit_status}"), + ); diag.arg("linker_path", format!("{}", self.linker_path.display())); diag.arg("exit_status", format!("{}", self.exit_status)); @@ -470,11 +487,11 @@ impl Diagnostic<'_, G> for LinkingFailed<'_> { // Trying to match an error from OS linkers // which by now we have no way to translate. if contains_undefined_ref { - diag.note(fluent::codegen_ssa_extern_funcs_not_found) - .note(fluent::codegen_ssa_specify_libraries_to_link); + diag.note(inline_fluent!("some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified")) + .note(inline_fluent!("use the `-l` flag to specify native libraries to link")); if rustc_session::utils::was_invoked_from_cargo() { - diag.note(fluent::codegen_ssa_use_cargo_directive); + diag.note(inline_fluent!("use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)")); } } diag @@ -482,7 +499,7 @@ impl Diagnostic<'_, G> for LinkingFailed<'_> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_link_exe_unexpected_error)] +#[diag("`link.exe` returned an unexpected error")] pub(crate) struct LinkExeUnexpectedError; pub(crate) struct LinkExeStatusStackBufferOverrun; @@ -490,41 +507,43 @@ pub(crate) struct LinkExeStatusStackBufferOverrun; impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for LinkExeStatusStackBufferOverrun { fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { let mut diag = - Diag::new(dcx, level, fluent::codegen_ssa_link_exe_status_stack_buffer_overrun); - diag.note(fluent::codegen_ssa_abort_note); - diag.note(fluent::codegen_ssa_event_log_note); + Diag::new(dcx, level, inline_fluent!("0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN`")); + diag.note(inline_fluent!( + "this may have been caused by a program abort and not a stack buffer overrun" + )); + diag.note(inline_fluent!("consider checking the Application Event Log for Windows Error Reporting events to see the fail fast error code")); diag } } #[derive(Diagnostic)] -#[diag(codegen_ssa_repair_vs_build_tools)] +#[diag("the Visual Studio build tools may need to be repaired using the Visual Studio installer")] pub(crate) struct RepairVSBuildTools; #[derive(Diagnostic)] -#[diag(codegen_ssa_missing_cpp_build_tool_component)] +#[diag("or a necessary component may be missing from the \"C++ build tools\" workload")] pub(crate) struct MissingCppBuildToolComponent; #[derive(Diagnostic)] -#[diag(codegen_ssa_select_cpp_build_tool_workload)] +#[diag("in the Visual Studio installer, ensure the \"C++ build tools\" workload is selected")] pub(crate) struct SelectCppBuildToolWorkload; #[derive(Diagnostic)] -#[diag(codegen_ssa_visual_studio_not_installed)] +#[diag("you may need to install Visual Studio build tools with the \"C++ build tools\" workload")] pub(crate) struct VisualStudioNotInstalled; #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_not_found)] -#[note] +#[diag("linker `{$linker_path}` not found")] +#[note("{$error}")] pub(crate) struct LinkerNotFound { pub linker_path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_exe_linker)] -#[note] -#[note(codegen_ssa_command_note)] +#[diag("could not exec the linker `{$linker_path}`")] +#[note("{$error}")] +#[note("{$command_formatted}")] pub(crate) struct UnableToExeLinker { pub linker_path: PathBuf, pub error: Error, @@ -532,42 +551,46 @@ pub(crate) struct UnableToExeLinker { } #[derive(Diagnostic)] -#[diag(codegen_ssa_msvc_missing_linker)] +#[diag("the msvc targets depend on the msvc linker but `link.exe` was not found")] pub(crate) struct MsvcMissingLinker; #[derive(Diagnostic)] -#[diag(codegen_ssa_self_contained_linker_missing)] +#[diag( + "the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot" +)] pub(crate) struct SelfContainedLinkerMissing; #[derive(Diagnostic)] -#[diag(codegen_ssa_check_installed_visual_studio)] +#[diag( + "please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option." +)] pub(crate) struct CheckInstalledVisualStudio; #[derive(Diagnostic)] -#[diag(codegen_ssa_insufficient_vs_code_product)] +#[diag("VS Code is a different product, and is not sufficient.")] pub(crate) struct InsufficientVSCodeProduct; #[derive(Diagnostic)] -#[diag(codegen_ssa_cpu_required)] +#[diag("target requires explicitly specifying a cpu with `-C target-cpu`")] pub(crate) struct CpuRequired; #[derive(Diagnostic)] -#[diag(codegen_ssa_processing_dymutil_failed)] -#[note] +#[diag("processing debug info with `dsymutil` failed: {$status}")] +#[note("{$output}")] pub(crate) struct ProcessingDymutilFailed { pub status: ExitStatus, pub output: String, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_run_dsymutil)] +#[diag("unable to run `dsymutil`: {$error}")] pub(crate) struct UnableToRunDsymutil { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_stripping_debug_info_failed)] -#[note] +#[diag("stripping debug info with `{$util}` failed: {$status}")] +#[note("{$output}")] pub(crate) struct StrippingDebugInfoFailed<'a> { pub util: &'a str, pub status: ExitStatus, @@ -575,53 +598,57 @@ pub(crate) struct StrippingDebugInfoFailed<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_run)] +#[diag("unable to run `{$util}`: {$error}")] pub(crate) struct UnableToRun<'a> { pub util: &'a str, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_file_stem)] +#[diag("couldn't extract file stem from specified linker")] pub(crate) struct LinkerFileStem; #[derive(Diagnostic)] -#[diag(codegen_ssa_static_library_native_artifacts)] +#[diag( + "link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms." +)] pub(crate) struct StaticLibraryNativeArtifacts; #[derive(Diagnostic)] -#[diag(codegen_ssa_static_library_native_artifacts_to_file)] +#[diag( + "native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms." +)] pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> { pub path: &'a Path, } #[derive(Diagnostic)] -#[diag(codegen_ssa_link_script_unavailable)] +#[diag("can only use link script when linking with GNU-like linker")] pub(crate) struct LinkScriptUnavailable; #[derive(Diagnostic)] -#[diag(codegen_ssa_link_script_write_failure)] +#[diag("failed to write link script to {$path}: {$error}")] pub(crate) struct LinkScriptWriteFailure { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_failed_to_write)] +#[diag("failed to write {$path}: {$error}")] pub(crate) struct FailedToWrite { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_write_debugger_visualizer)] +#[diag("unable to write debugger visualizer file `{$path}`: {$error}")] pub(crate) struct UnableToWriteDebuggerVisualizer { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_rlib_archive_build_failure)] +#[diag("failed to build archive from rlib at `{$path}`: {$error}")] pub(crate) struct RlibArchiveBuildFailure { pub path: PathBuf, pub error: Error, @@ -630,68 +657,70 @@ pub(crate) struct RlibArchiveBuildFailure { #[derive(Diagnostic)] // Public for ArchiveBuilderBuilder::extract_bundled_libs pub enum ExtractBundledLibsError<'a> { - #[diag(codegen_ssa_extract_bundled_libs_open_file)] + #[diag("failed to open file '{$rlib}': {$error}")] OpenFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_mmap_file)] + #[diag("failed to mmap file '{$rlib}': {$error}")] MmapFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_parse_archive)] + #[diag("failed to parse archive '{$rlib}': {$error}")] ParseArchive { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_read_entry)] + #[diag("failed to read entry '{$rlib}': {$error}")] ReadEntry { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_archive_member)] + #[diag("failed to get data from archive member '{$rlib}': {$error}")] ArchiveMember { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_convert_name)] + #[diag("failed to convert name '{$rlib}': {$error}")] ConvertName { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_write_file)] + #[diag("failed to write file '{$rlib}': {$error}")] WriteFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_write_file)] + #[diag("failed to write file '{$rlib}': {$error}")] ExtractSection { rlib: &'a Path, error: Box }, } #[derive(Diagnostic)] -#[diag(codegen_ssa_read_file)] +#[diag("failed to read file: {$message}")] pub(crate) struct ReadFileError { pub message: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unsupported_link_self_contained)] +#[diag("option `-C link-self-contained` is not supported on this target")] pub(crate) struct UnsupportedLinkSelfContained; #[derive(Diagnostic)] -#[diag(codegen_ssa_archive_build_failure)] +#[diag("failed to build archive at `{$path}`: {$error}")] pub(crate) struct ArchiveBuildFailure { pub path: PathBuf, pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_archive_kind)] +#[diag("don't know how to build archive of type: {$kind}")] pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_bpf_staticlib_not_supported)] +#[diag("linking static libraries is not supported for BPF")] pub(crate) struct BpfStaticlibNotSupported; #[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_main_functions)] -#[help] +#[diag("entry symbol `main` declared multiple times")] +#[help( + "did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point" +)] pub(crate) struct MultipleMainFunctions { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_shuffle_indices_evaluation)] +#[diag("could not evaluate shuffle_indices at compile time")] pub(crate) struct ShuffleIndicesEvaluation { #[primary_span] pub span: Span, @@ -699,7 +728,7 @@ pub(crate) struct ShuffleIndicesEvaluation { #[derive(Diagnostic)] pub enum InvalidMonomorphization<'tcx> { - #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`", code = E0511)] BasicIntegerType { #[primary_span] span: Span, @@ -707,7 +736,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}`", code = E0511)] BasicIntegerOrPtrType { #[primary_span] span: Span, @@ -715,7 +744,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`", code = E0511)] BasicFloatType { #[primary_span] span: Span, @@ -723,14 +752,14 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = E0511)] + #[diag("invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}`", code = E0511)] FloatToIntUnchecked { #[primary_span] span: Span, ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}`", code = E0511)] FloatingPointVector { #[primary_span] span: Span, @@ -739,7 +768,7 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)] FloatingPointType { #[primary_span] span: Span, @@ -747,14 +776,14 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`", code = E0511)] UnrecognizedIntrinsic { #[primary_span] span: Span, name: Symbol, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`", code = E0511)] SimdArgument { #[primary_span] span: Span, @@ -762,7 +791,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`", code = E0511)] SimdInput { #[primary_span] span: Span, @@ -770,7 +799,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`", code = E0511)] SimdFirst { #[primary_span] span: Span, @@ -778,7 +807,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`", code = E0511)] SimdSecond { #[primary_span] span: Span, @@ -786,7 +815,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`", code = E0511)] SimdThird { #[primary_span] span: Span, @@ -794,7 +823,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`", code = E0511)] SimdReturn { #[primary_span] span: Span, @@ -802,7 +831,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`", code = E0511)] InvalidBitmask { #[primary_span] span: Span, @@ -812,7 +841,7 @@ pub enum InvalidMonomorphization<'tcx> { expected_bytes: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}", code = E0511)] ReturnLengthInputType { #[primary_span] span: Span, @@ -823,7 +852,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}", code = E0511)] SecondArgumentLength { #[primary_span] span: Span, @@ -834,7 +863,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}", code = E0511)] ThirdArgumentLength { #[primary_span] span: Span, @@ -845,7 +874,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`", code = E0511)] ReturnIntegerType { #[primary_span] span: Span, @@ -854,7 +883,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}`", code = E0511)] SimdShuffle { #[primary_span] span: Span, @@ -862,7 +891,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_return_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}", code = E0511)] ReturnLength { #[primary_span] span: Span, @@ -872,7 +901,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_element, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`", code = E0511)] ReturnElement { #[primary_span] span: Span, @@ -883,7 +912,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len})", code = E0511)] SimdIndexOutOfBounds { #[primary_span] span: Span, @@ -892,7 +921,7 @@ pub enum InvalidMonomorphization<'tcx> { total_len: u128, }, - #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`", code = E0511)] InsertedType { #[primary_span] span: Span, @@ -902,7 +931,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_return_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`", code = E0511)] ReturnType { #[primary_span] span: Span, @@ -912,7 +941,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`", code = E0511)] ExpectedReturnType { #[primary_span] span: Span, @@ -921,7 +950,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`", code = E0511)] MismatchedLengths { #[primary_span] span: Span, @@ -930,7 +959,7 @@ pub enum InvalidMonomorphization<'tcx> { v_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_mask_wrong_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected mask element type to be an integer, found `{$ty}`", code = E0511)] MaskWrongElementType { #[primary_span] span: Span, @@ -938,7 +967,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`", code = E0511)] CannotReturn { #[primary_span] span: Span, @@ -948,7 +977,7 @@ pub enum InvalidMonomorphization<'tcx> { expected_bytes: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`", code = E0511)] ExpectedElementType { #[primary_span] span: Span, @@ -960,7 +989,7 @@ pub enum InvalidMonomorphization<'tcx> { mutability: ExpectedPointerMutability, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`", code = E0511)] UnsupportedSymbolOfSize { #[primary_span] span: Span, @@ -972,7 +1001,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`", code = E0511)] UnsupportedSymbol { #[primary_span] span: Span, @@ -983,7 +1012,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_cast_wide_pointer, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}`", code = E0511)] CastWidePointer { #[primary_span] span: Span, @@ -991,7 +1020,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`", code = E0511)] ExpectedPointer { #[primary_span] span: Span, @@ -999,7 +1028,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`", code = E0511)] ExpectedUsize { #[primary_span] span: Span, @@ -1007,7 +1036,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`", code = E0511)] UnsupportedCast { #[primary_span] span: Span, @@ -1018,7 +1047,7 @@ pub enum InvalidMonomorphization<'tcx> { out_elem: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`", code = E0511)] UnsupportedOperation { #[primary_span] span: Span, @@ -1027,7 +1056,7 @@ pub enum InvalidMonomorphization<'tcx> { in_elem: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type", code = E0511)] ExpectedVectorElementType { #[primary_span] span: Span, @@ -1036,7 +1065,7 @@ pub enum InvalidMonomorphization<'tcx> { vector_type: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_non_scalable_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected non-scalable type, found scalable type `{$ty}`", code = E0511)] NonScalableType { #[primary_span] span: Span, @@ -1060,17 +1089,17 @@ impl IntoDiagArg for ExpectedPointerMutability { } #[derive(Diagnostic)] -#[diag(codegen_ssa_target_feature_safe_trait)] +#[diag("`#[target_feature(..)]` cannot be applied to safe trait method")] pub(crate) struct TargetFeatureSafeTrait { #[primary_span] - #[label] + #[label("cannot be applied to safe trait method")] pub span: Span, - #[label(codegen_ssa_label_def)] + #[label("not an `unsafe` function")] pub def: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_forbidden_target_feature_attr)] +#[diag("target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason}")] pub struct ForbiddenTargetFeatureAttr<'a> { #[primary_span] pub span: Span, @@ -1079,7 +1108,7 @@ pub struct ForbiddenTargetFeatureAttr<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_failed_to_get_layout)] +#[diag("failed to get layout for {$ty}: {$err}")] pub struct FailedToGetLayout<'tcx> { #[primary_span] pub span: Span, @@ -1088,7 +1117,11 @@ pub struct FailedToGetLayout<'tcx> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_dlltool_fail_import_library)] +#[diag( + "dlltool could not create import library with {$dlltool_path} {$dlltool_args}: +{$stdout} +{$stderr}" +)] pub(crate) struct DlltoolFailImportLibrary<'a> { pub dlltool_path: Cow<'a, str>, pub dlltool_args: String, @@ -1097,26 +1130,28 @@ pub(crate) struct DlltoolFailImportLibrary<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_writing_def_file)] +#[diag("error writing .DEF file: {$error}")] pub(crate) struct ErrorWritingDEFFile { pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_calling_dlltool)] +#[diag("error calling dlltool '{$dlltool_path}': {$error}")] pub(crate) struct ErrorCallingDllTool<'a> { pub dlltool_path: Cow<'a, str>, pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_creating_remark_dir)] +#[diag("failed to create remark directory: {$error}")] pub(crate) struct ErrorCreatingRemarkDir { pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_compiler_builtins_cannot_call)] +#[diag( + "`compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}`" +)] pub struct CompilerBuiltinsCannotCall { pub caller: String, pub callee: String, @@ -1125,23 +1160,23 @@ pub struct CompilerBuiltinsCannotCall { } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_creating_import_library)] +#[diag("error creating import library for {$lib_name}: {$error}")] pub(crate) struct ErrorCreatingImportLibrary<'a> { pub lib_name: &'a str, pub error: String, } #[derive(Diagnostic)] -#[diag(codegen_ssa_aix_strip_not_used)] +#[diag("using host's `strip` binary to cross-compile to AIX which is not guaranteed to work")] pub(crate) struct AixStripNotUsed; #[derive(Diagnostic, Debug)] pub(crate) enum XcrunError { - #[diag(codegen_ssa_xcrun_failed_invoking)] + #[diag("invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error}")] FailedInvoking { sdk_name: &'static str, command_formatted: String, error: std::io::Error }, - #[diag(codegen_ssa_xcrun_unsuccessful)] - #[note] + #[diag("failed running `{$command_formatted}` to find {$sdk_name}.sdk")] + #[note("{$stdout}{$stderr}")] Unsuccessful { sdk_name: &'static str, command_formatted: String, @@ -1151,35 +1186,37 @@ pub(crate) enum XcrunError { } #[derive(Diagnostic, Debug)] -#[diag(codegen_ssa_xcrun_sdk_path_warning)] -#[note] +#[diag("output of `xcrun` while finding {$sdk_name}.sdk")] +#[note("{$stderr}")] pub(crate) struct XcrunSdkPathWarning { pub sdk_name: &'static str, pub stderr: String, } #[derive(LintDiagnostic)] -#[diag(codegen_ssa_aarch64_softfloat_neon)] +#[diag("enabling the `neon` target feature on the current target is unsound due to ABI issues")] pub(crate) struct Aarch64SoftfloatNeon; #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_ctarget_feature_prefix)] -#[note] +#[diag("unknown feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note("features must begin with a `+` to enable or `-` to disable it")] pub(crate) struct UnknownCTargetFeaturePrefix<'a> { pub feature: &'a str, } #[derive(Subdiagnostic)] pub(crate) enum PossibleFeature<'a> { - #[help(codegen_ssa_possible_feature)] + #[help("you might have meant: `{$rust_feature}`")] Some { rust_feature: &'a str }, - #[help(codegen_ssa_consider_filing_feature_request)] + #[help("consider filing a feature request")] None, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_ctarget_feature)] -#[note] +#[diag("unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note( + "it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future" +)] pub(crate) struct UnknownCTargetFeature<'a> { pub feature: &'a str, #[subdiagnostic] @@ -1187,16 +1224,18 @@ pub(crate) struct UnknownCTargetFeature<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_unstable_ctarget_feature)] -#[note] +#[diag("unstable feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note("this feature is not stably supported; its behavior can change in the future")] pub(crate) struct UnstableCTargetFeature<'a> { pub feature: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_forbidden_ctarget_feature)] -#[note] -#[note(codegen_ssa_forbidden_ctarget_feature_issue)] +#[diag("target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}")] +#[note( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] +#[note("for more information, see issue #116344 ")] pub(crate) struct ForbiddenCTargetFeature<'a> { pub feature: &'a str, pub enabled: &'a str, @@ -1210,12 +1249,18 @@ pub struct TargetFeatureDisableOrEnable<'a> { } #[derive(Subdiagnostic)] -#[help(codegen_ssa_missing_features)] +#[help("add the missing features in a `target_feature` attribute")] pub struct MissingFeatures; impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_target_feature_disable_or_enable); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!( + "the target features {$features} must all be either enabled or disabled together" + ), + ); if let Some(span) = self.span { diag.span(span); }; @@ -1228,29 +1273,29 @@ impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_ } #[derive(Diagnostic)] -#[diag(codegen_ssa_feature_not_valid)] +#[diag("the feature named `{$feature}` is not valid for this target")] pub(crate) struct FeatureNotValid<'a> { pub feature: &'a str, #[primary_span] - #[label] + #[label("`{$feature}` is not valid for this target")] pub span: Span, - #[help] + #[help("consider removing the leading `+` in the feature name")] pub plus_hint: bool, } #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_disallowed)] +#[diag("lto can only be run for executables, cdylibs and static library outputs")] pub(crate) struct LtoDisallowed; #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_dylib)] +#[diag("lto cannot be used for `dylib` crate type without `-Zdylib-lto`")] pub(crate) struct LtoDylib; #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_proc_macro)] +#[diag("lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`")] pub(crate) struct LtoProcMacro; #[derive(Diagnostic)] -#[diag(codegen_ssa_dynamic_linking_with_lto)] -#[note] +#[diag("cannot prefer dynamic linking when performing LTO")] +#[note("only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO")] pub(crate) struct DynamicLinkingWithLTO; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 5cca916c17b6..e3934065b0f7 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -55,8 +55,6 @@ pub mod size_of_val; pub mod target_features; pub mod traits; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub struct ModuleCodegen { /// The name of the module. When the crate may be saved between /// compilations, incremental compilation requires that name be diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc61..80edfa789acb 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -118,7 +118,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, - rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, rustc_const_eval::DEFAULT_LOCALE_RESOURCE, rustc_errors::DEFAULT_LOCALE_RESOURCE, rustc_expand::DEFAULT_LOCALE_RESOURCE, From 40695f18be8e43a3b74710f9a872dc3a78557cf9 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 16:48:07 +0100 Subject: [PATCH 53/81] Convert to inline diagnostics in `rustc_mir_transform` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_mir_transform/Cargo.toml | 1 - compiler/rustc_mir_transform/messages.ftl | 114 ------------- compiler/rustc_mir_transform/src/errors.rs | 158 +++++++++++------- compiler/rustc_mir_transform/src/lib.rs | 2 - .../src/lint_tail_expr_drop_order.rs | 31 +++- 7 files changed, 121 insertions(+), 187 deletions(-) delete mode 100644 compiler/rustc_mir_transform/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 85d3fc1aa7bf..1eaeec8da2a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4347,7 +4347,6 @@ dependencies = [ "rustc_const_eval", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3b9ca5ff7288..972f0a1d2bee 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -128,7 +128,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_metadata::DEFAULT_LOCALE_RESOURCE, rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, - rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 404531eb3c91..395127edd1e0 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -13,7 +13,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_const_eval = { path = "../rustc_const_eval" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl deleted file mode 100644 index 7924c015200f..000000000000 --- a/compiler/rustc_mir_transform/messages.ftl +++ /dev/null @@ -1,114 +0,0 @@ -mir_transform_arithmetic_overflow = this arithmetic operation will overflow - -mir_transform_asm_unwind_call = call to inline assembly that may unwind - -mir_transform_const_defined_here = `const` item defined here - -mir_transform_const_modify = attempting to modify a `const` item - .note = each usage of a `const` item creates a new temporary; the original `const` item will not be modified - -mir_transform_const_mut_borrow = taking a mutable reference to a `const` item - .note = each usage of a `const` item creates a new temporary - .note2 = the mutable reference will refer to this temporary, not the original `const` item - .note3 = mutable reference created due to call to this method - -mir_transform_ffi_unwind_call = call to {$foreign -> - [true] foreign function - *[false] function pointer - } with FFI-unwind ABI - -mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer - .suggestion = cast `{$ident}` to obtain a function pointer - -mir_transform_force_inline = - `{$callee}` could not be inlined into `{$caller}` but is required to be inlined - .call = ...`{$callee}` called here - .attr = inlining due to this annotation - .caller = within `{$caller}`... - .callee = `{$callee}` defined here - .note = could not be inlined due to: {$reason} - -mir_transform_force_inline_attr = - `{$callee}` is incompatible with `#[rustc_force_inline]` - .attr = annotation here - .callee = `{$callee}` defined here - .note = incompatible due to: {$reason} - -mir_transform_force_inline_justification = - `{$callee}` is required to be inlined to: {$sym} - -mir_transform_maybe_string_interpolation = you might have meant to use string interpolation in this string literal - -mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be - .label = the value is held across this suspend point - .note = {$reason} - .help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point -mir_transform_operation_will_panic = this operation will panic at runtime - -mir_transform_string_interpolation_only_works = string interpolation only works in `format!` invocations - -mir_transform_tail_expr_drop_order = relative drop order changing in Rust 2024 - .temporaries = in Rust 2024, this temporary value will be dropped first - .observers = in Rust 2024, this local variable or temporary value will be dropped second - .note_dtors = - dropping the temporary value runs this custom `Drop` impl, which we could not prove to be side-effect free - .note_observer_dtors = - dropping the local runs this custom `Drop` impl, which we could not prove to be side-effect free - .drop_location = - now the temporary value is dropped here, before the local variables in the block or statement - .note_epilogue = most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages - .label_local_epilogue = {$is_dropped_first_edition_2024 -> - [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 - *[false] `{$name}` will be dropped later as of Edition 2024 - } - -mir_transform_tail_expr_dtor = {$dtor_kind -> - [dyn] `{$name}` may invoke a custom destructor because it contains a trait object - *[concrete] `{$name}` invokes this custom destructor - } - -mir_transform_tail_expr_local = {$is_generated_name -> - [true] this value will be stored in a temporary; let us call it `{$name}` - *[false] `{$name}` calls a custom destructor - } - -mir_transform_unaligned_packed_ref = reference to field of packed {$ty_descr} is unaligned - .note = this {$ty_descr} is {$align -> - [one] {""} - *[other] {"at most "} - }{$align}-byte aligned, but the type of this field may require higher alignment - .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -mir_transform_unconditional_recursion = function cannot return without recursing - .label = cannot return without recursing - .help = a `loop` may express intention better if this is on purpose - -mir_transform_unconditional_recursion_call_site_label = recursive call site - -mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored - -mir_transform_unused_assign = value assigned to `{$name}` is never read - .help = maybe it is overwritten before being read? - -mir_transform_unused_assign_passed = value passed to `{$name}` is never read - .help = maybe it is overwritten before being read? - -mir_transform_unused_assign_suggestion = - you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding - -mir_transform_unused_capture_maybe_capture_ref = value captured by `{$name}` is never read - .help = did you mean to capture by reference instead? - -mir_transform_unused_var_assigned_only = variable `{$name}` is assigned to, but never used - .note = consider using `_{$name}` instead - -mir_transform_unused_var_underscore = if this is intentional, prefix it with an underscore - -mir_transform_unused_variable = unused variable: `{$name}` - -mir_transform_unused_variable_args_in_macro = `{$name}` is captured in macro and introduced a unused variable - -mir_transform_unused_variable_try_ignore = try ignoring the field - -mir_transform_unused_variable_typo = you might have meant to pattern match on the similarly named {$kind} `{$item_name}` diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index d4c58f7fe05d..7407a0e022d3 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,5 +1,7 @@ use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintDiagnostic, Subdiagnostic}; +use rustc_errors::{ + Applicability, Diag, EmissionGuarantee, LintDiagnostic, Subdiagnostic, inline_fluent, +}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::AssertKind; use rustc_middle::query::Key; @@ -8,8 +10,6 @@ use rustc_session::lint::{self, Lint}; use rustc_span::def_id::DefId; use rustc_span::{Ident, Span, Symbol}; -use crate::fluent_generated as fluent; - /// Emit diagnostic for calls to `#[inline(always)]`-annotated functions with a /// `#[target_feature]` attribute where the caller enables a different set of target features. pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>( @@ -51,22 +51,22 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>( } #[derive(LintDiagnostic)] -#[diag(mir_transform_unconditional_recursion)] -#[help] +#[diag("function cannot return without recursing")] +#[help("a `loop` may express intention better if this is on purpose")] pub(crate) struct UnconditionalRecursion { - #[label] + #[label("cannot return without recursing")] pub(crate) span: Span, - #[label(mir_transform_unconditional_recursion_call_site_label)] + #[label("recursive call site")] pub(crate) call_sites: Vec, } #[derive(Diagnostic)] -#[diag(mir_transform_force_inline_attr)] -#[note] +#[diag("`{$callee}` is incompatible with `#[rustc_force_inline]`")] +#[note("incompatible due to: {$reason}")] pub(crate) struct InvalidForceInline { #[primary_span] pub attr_span: Span, - #[label(mir_transform_callee)] + #[label("`{$callee}` defined here")] pub callee_span: Span, pub callee: String, pub reason: &'static str, @@ -74,28 +74,39 @@ pub(crate) struct InvalidForceInline { #[derive(LintDiagnostic)] pub(crate) enum ConstMutate { - #[diag(mir_transform_const_modify)] - #[note] + #[diag("attempting to modify a `const` item")] + #[note( + "each usage of a `const` item creates a new temporary; the original `const` item will not be modified" + )] Modify { - #[note(mir_transform_const_defined_here)] + #[note("`const` item defined here")] konst: Span, }, - #[diag(mir_transform_const_mut_borrow)] - #[note] - #[note(mir_transform_note2)] + #[diag("taking a mutable reference to a `const` item")] + #[note("each usage of a `const` item creates a new temporary")] + #[note("the mutable reference will refer to this temporary, not the original `const` item")] MutBorrow { - #[note(mir_transform_note3)] + #[note("mutable reference created due to call to this method")] method_call: Option, - #[note(mir_transform_const_defined_here)] + #[note("`const` item defined here")] konst: Span, }, } #[derive(Diagnostic)] -#[diag(mir_transform_unaligned_packed_ref, code = E0793)] -#[note] -#[note(mir_transform_note_ub)] -#[help] +#[diag("reference to field of packed {$ty_descr} is unaligned", code = E0793)] +#[note( + "this {$ty_descr} is {$align -> + [one] {\"\"} + *[other] {\"at most \"} + }{$align}-byte aligned, but the type of this field may require higher alignment" +)] +#[note( + "creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)" +)] +#[help( + "copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)" +)] pub(crate) struct UnalignedPackedRef { #[primary_span] pub span: Span, @@ -104,7 +115,7 @@ pub(crate) struct UnalignedPackedRef { } #[derive(Diagnostic)] -#[diag(mir_transform_unknown_pass_name)] +#[diag("MIR pass `{$name}` is unknown and will be ignored")] pub(crate) struct UnknownPassName<'a> { pub(crate) name: &'a str, } @@ -123,8 +134,12 @@ pub(crate) enum AssertLintKind { impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint

{ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.primary_message(match self.lint_kind { - AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, - AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, + AssertLintKind::ArithmeticOverflow => { + inline_fluent!("this arithmetic operation will overflow") + } + AssertLintKind::UnconditionalPanic => { + inline_fluent!("this operation will panic at runtime") + } }); let label = self.assert_kind.diagnostic_message(); self.assert_kind.add_args(&mut |name, value| { @@ -144,39 +159,53 @@ impl AssertLintKind { } #[derive(LintDiagnostic)] -#[diag(mir_transform_asm_unwind_call)] +#[diag("call to inline assembly that may unwind")] pub(crate) struct AsmUnwindCall { - #[label(mir_transform_asm_unwind_call)] + #[label("call to inline assembly that may unwind")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_transform_ffi_unwind_call)] +#[diag( + "call to {$foreign -> + [true] foreign function + *[false] function pointer + } with FFI-unwind ABI" +)] pub(crate) struct FfiUnwindCall { - #[label(mir_transform_ffi_unwind_call)] + #[label( + "call to {$foreign -> + [true] foreign function + *[false] function pointer + } with FFI-unwind ABI" + )] pub span: Span, pub foreign: bool, } #[derive(LintDiagnostic)] -#[diag(mir_transform_fn_item_ref)] +#[diag("taking a reference to a function item does not give a function pointer")] pub(crate) struct FnItemRef { - #[suggestion(code = "{sugg}", applicability = "unspecified")] + #[suggestion( + "cast `{$ident}` to obtain a function pointer", + code = "{sugg}", + applicability = "unspecified" + )] pub span: Span, pub sugg: String, pub ident: Ident, } #[derive(LintDiagnostic)] -#[diag(mir_transform_unused_capture_maybe_capture_ref)] -#[help] +#[diag("value captured by `{$name}` is never read")] +#[help("did you mean to capture by reference instead?")] pub(crate) struct UnusedCaptureMaybeCaptureRef { pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(mir_transform_unused_var_assigned_only)] -#[note] +#[diag("variable `{$name}` is assigned to, but never used")] +#[note("consider using `_{$name}` instead")] pub(crate) struct UnusedVarAssignedOnly { pub name: Symbol, #[subdiagnostic] @@ -184,17 +213,20 @@ pub(crate) struct UnusedVarAssignedOnly { } #[derive(LintDiagnostic)] -#[diag(mir_transform_unused_assign)] +#[diag("value assigned to `{$name}` is never read")] pub(crate) struct UnusedAssign { pub name: Symbol, #[subdiagnostic] pub suggestion: Option, - #[help] + #[help("maybe it is overwritten before being read?")] pub help: bool, } #[derive(Subdiagnostic)] -#[multipart_suggestion(mir_transform_unused_assign_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding", + applicability = "maybe-incorrect" +)] pub(crate) struct UnusedAssignSuggestion { pub pre: &'static str, #[suggestion_part(code = "{pre}mut ")] @@ -208,14 +240,14 @@ pub(crate) struct UnusedAssignSuggestion { } #[derive(LintDiagnostic)] -#[diag(mir_transform_unused_assign_passed)] -#[help] +#[diag("value passed to `{$name}` is never read")] +#[help("maybe it is overwritten before being read?")] pub(crate) struct UnusedAssignPassed { pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(mir_transform_unused_variable)] +#[diag("unused variable: `{$name}`")] pub(crate) struct UnusedVariable { pub name: Symbol, #[subdiagnostic] @@ -226,10 +258,7 @@ pub(crate) struct UnusedVariable { #[derive(Subdiagnostic)] pub(crate) enum UnusedVariableSugg { - #[multipart_suggestion( - mir_transform_unused_variable_try_ignore, - applicability = "machine-applicable" - )] + #[multipart_suggestion("try ignoring the field", applicability = "machine-applicable")] TryIgnore { #[suggestion_part(code = "{name}: _")] shorthands: Vec, @@ -239,7 +268,7 @@ pub(crate) enum UnusedVariableSugg { }, #[multipart_suggestion( - mir_transform_unused_var_underscore, + "if this is intentional, prefix it with an underscore", applicability = "machine-applicable" )] TryPrefix { @@ -250,7 +279,7 @@ pub(crate) enum UnusedVariableSugg { typo: Option, }, - #[help(mir_transform_unused_variable_args_in_macro)] + #[help("`{$name}` is captured in macro and introduced a unused variable")] NoSugg { #[primary_span] span: Span, @@ -266,10 +295,12 @@ impl Subdiagnostic for UnusedVariableStringInterp { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.span_label( self.lit, - crate::fluent_generated::mir_transform_maybe_string_interpolation, + inline_fluent!( + "you might have meant to use string interpolation in this string literal" + ), ); diag.multipart_suggestion( - crate::fluent_generated::mir_transform_string_interpolation_only_works, + inline_fluent!("string interpolation only works in `format!` invocations"), vec![ (self.lit.shrink_to_lo(), String::from("format!(")), (self.lit.shrink_to_hi(), String::from(")")), @@ -281,7 +312,7 @@ impl Subdiagnostic for UnusedVariableStringInterp { #[derive(Subdiagnostic)] #[multipart_suggestion( - mir_transform_unused_variable_typo, + "you might have meant to pattern match on the similarly named {$kind} `{$item_name}`", style = "verbose", applicability = "maybe-incorrect" )] @@ -306,12 +337,17 @@ pub(crate) struct MustNotSupend<'a, 'tcx> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { - diag.primary_message(fluent::mir_transform_must_not_suspend); - diag.span_label(self.yield_sp, fluent::_subdiag::label); + diag.primary_message(inline_fluent!( + "{$pre}`{$def_path}`{$post} held across a suspend point, but should not be" + )); + diag.span_label( + self.yield_sp, + inline_fluent!("the value is held across this suspend point"), + ); if let Some(reason) = self.reason { diag.subdiagnostic(reason); } - diag.span_help(self.src_sp, fluent::_subdiag::help); + diag.span_help(self.src_sp, inline_fluent!("consider using a block (`{\"{ ... }\"}`) to shrink the value's scope, ending before the suspend point")); diag.arg("pre", self.pre); diag.arg("def_path", self.tcx.def_path_str(self.def_id)); diag.arg("post", self.post); @@ -319,7 +355,7 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { } #[derive(Subdiagnostic)] -#[note(mir_transform_note)] +#[note("{$reason}")] pub(crate) struct MustNotSuspendReason { #[primary_span] pub span: Span, @@ -327,17 +363,17 @@ pub(crate) struct MustNotSuspendReason { } #[derive(Diagnostic)] -#[diag(mir_transform_force_inline)] -#[note] +#[diag("`{$callee}` could not be inlined into `{$caller}` but is required to be inlined")] +#[note("could not be inlined due to: {$reason}")] pub(crate) struct ForceInlineFailure { - #[label(mir_transform_caller)] + #[label("within `{$caller}`...")] pub caller_span: Span, - #[label(mir_transform_callee)] + #[label("`{$callee}` defined here")] pub callee_span: Span, - #[label(mir_transform_attr)] + #[label("annotation here")] pub attr_span: Span, #[primary_span] - #[label(mir_transform_call)] + #[label("...`{$callee}` called here")] pub call_span: Span, pub callee: String, pub caller: String, @@ -347,7 +383,7 @@ pub(crate) struct ForceInlineFailure { } #[derive(Subdiagnostic)] -#[note(mir_transform_force_inline_justification)] +#[note("`{$callee}` is required to be inlined to: {$sym}")] pub(crate) struct ForceInlineJustification { pub sym: Symbol, } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 0e6a1a414e45..0610d90202a1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -213,8 +213,6 @@ declare_passes! { mod validate : Validator; } -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { coverage::query::provide(providers); ffi_unwind_calls::provide(&mut providers.queries); diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 61c9bbe31239..789398c58880 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use itertools::Itertools as _; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_errors::Subdiagnostic; +use rustc_errors::{Subdiagnostic, inline_fluent}; use rustc_hir::CRATE_HIR_ID; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::MixedBitSet; @@ -499,13 +499,17 @@ fn assign_observables_names( } #[derive(LintDiagnostic)] -#[diag(mir_transform_tail_expr_drop_order)] +#[diag("relative drop order changing in Rust 2024")] struct TailExprDropOrderLint<'a> { #[subdiagnostic] local_labels: Vec>, - #[label(mir_transform_drop_location)] + #[label( + "now the temporary value is dropped here, before the local variables in the block or statement" + )] drop_span: Option, - #[note(mir_transform_note_epilogue)] + #[note( + "most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages" + )] _epilogue: (), } @@ -527,19 +531,32 @@ impl Subdiagnostic for LocalLabel<'_> { diag.arg("is_generated_name", self.is_generated_name); diag.remove_arg("is_dropped_first_edition_2024"); diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024); - let msg = diag.eagerly_translate(crate::fluent_generated::mir_transform_tail_expr_local); + let msg = diag.eagerly_translate(inline_fluent!( + "{$is_generated_name -> + [true] this value will be stored in a temporary; let us call it `{$name}` + *[false] `{$name}` calls a custom destructor + }" + )); diag.span_label(self.span, msg); for dtor in self.destructors { dtor.add_to_diag(diag); } let msg = - diag.eagerly_translate(crate::fluent_generated::mir_transform_label_local_epilogue); + diag.eagerly_translate(inline_fluent!("{$is_dropped_first_edition_2024 -> + [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 + *[false] `{$name}` will be dropped later as of Edition 2024 + }")); diag.span_label(self.span, msg); } } #[derive(Subdiagnostic)] -#[note(mir_transform_tail_expr_dtor)] +#[note( + "{$dtor_kind -> + [dyn] `{$name}` may invoke a custom destructor because it contains a trait object + *[concrete] `{$name}` invokes this custom destructor + }" +)] struct DestructorLabel<'a> { #[primary_span] span: Span, From e005754c06f6a6115ae48721fcffaf62cbeeadad Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 22:23:12 +0100 Subject: [PATCH 54/81] Convert to inline diagnostics in `rustc_resolve` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_resolve/Cargo.toml | 1 - compiler/rustc_resolve/messages.ftl | 531 ------------------------- compiler/rustc_resolve/src/errors.rs | 552 +++++++++++++++----------- compiler/rustc_resolve/src/lib.rs | 2 - 6 files changed, 310 insertions(+), 778 deletions(-) delete mode 100644 compiler/rustc_resolve/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 85d3fc1aa7bf..711892bcfdd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4581,7 +4581,6 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3b9ca5ff7288..8c53d558133b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -132,7 +132,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_resolve::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index dd15e879c644..01e268d911d2 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -16,7 +16,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl deleted file mode 100644 index 4a980b2bd747..000000000000 --- a/compiler/rustc_resolve/messages.ftl +++ /dev/null @@ -1,531 +0,0 @@ -resolve_accessible_unsure = not sure whether the path is accessible or not - .note = the type may have associated items, but we are currently not checking them - -resolve_add_as_non_derive = - add as non-Derive macro - `#[{$macro_path}]` - -resolve_added_macro_use = - have you added the `#[macro_use]` on the module/import? - -resolve_ancestor_only = - visibilities can only be restricted to ancestor modules - -resolve_anonymous_lifetime_non_gat_report_error = missing lifetime in associated type - .label = this lifetime must come from the implemented type - .note = in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type - -resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here - -resolve_associated_const_with_similar_name_exists = - there is an associated constant with a similar name - -resolve_associated_fn_with_similar_name_exists = - there is an associated function with a similar name - -resolve_associated_type_with_similar_name_exists = - there is an associated type with a similar name - -resolve_attempt_to_use_non_constant_value_in_constant = - attempt to use a non-constant value in a constant - -resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion = - non-constant value - -resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion = - consider using `{$suggestion}` instead of `{$current}` - -resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion = - this would need to be a `{$suggestion}` - -resolve_attributes_starting_with_rustc_are_reserved = - attributes starting with `rustc` are reserved for use by the `rustc` compiler - -resolve_binding_in_never_pattern = - never patterns cannot contain variable bindings - .suggestion = use a wildcard `_` instead - -resolve_binding_shadows_something_unacceptable = - {$shadowing_binding}s cannot shadow {$shadowed_binding}s - .label = cannot be named the same as {$article} {$shadowed_binding} - .label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here - -resolve_binding_shadows_something_unacceptable_suggestion = - try specify the pattern arguments - -resolve_cannot_be_reexported_crate_public = - `{$ident}` is only public within the crate, and cannot be re-exported outside - -resolve_cannot_be_reexported_private = - `{$ident}` is private, and cannot be re-exported - -resolve_cannot_capture_dynamic_environment_in_fn_item = - can't capture dynamic environment in a fn item - .help = use the `|| {"{"} ... {"}"}` closure form instead - -resolve_cannot_determine_import_resolution = - cannot determine resolution for the import - .note = import resolution is stuck, try simplifying other imports - -resolve_cannot_determine_macro_resolution = - cannot determine resolution for the {$kind} `{$path}` - .note = import resolution is stuck, try simplifying macro imports - -resolve_cannot_find_builtin_macro_with_name = - cannot find a built-in macro with name `{$ident}` - -resolve_cannot_find_ident_in_this_scope = - cannot find {$expected} `{$ident}` in this scope - -resolve_cannot_glob_import_possible_crates = - cannot glob-import all possible crates - -resolve_cannot_use_through_an_import = - cannot use {$article} {$descr} through an import - .note = the {$descr} imported here - -resolve_change_import_binding = - you can use `as` to change the binding name of the import - -resolve_consider_adding_a_derive = - consider adding a derive - -resolve_consider_adding_macro_export = - consider adding a `#[macro_export]` to the macro in the imported module - -resolve_consider_declaring_with_pub = - consider declaring type or module `{$ident}` with `pub` - -resolve_consider_making_the_field_public = - { $number_of_fields -> - [one] consider making the field publicly accessible - *[other] consider making the fields publicly accessible - } - -resolve_consider_marking_as_pub = - consider marking `{$ident}` as `pub` in the imported module - -resolve_consider_marking_as_pub_crate = - in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)` - -resolve_consider_move_macro_position = - consider moving the definition of `{$ident}` before this call - - -resolve_const_not_member_of_trait = - const `{$const_}` is not a member of trait `{$trait_}` - .label = not a member of trait `{$trait_}` - -resolve_const_param_in_enum_discriminant = - const parameters may not be used in enum discriminant values - -resolve_const_param_in_non_trivial_anon_const = - const parameters may only be used as standalone arguments here, i.e. `{$name}` - -resolve_constructor_private_if_any_field_private = - a constructor is private if any of the fields is private - -resolve_elided_anonymous_lifetime_report_error = - `&` without an explicit lifetime name cannot be used here - .label = explicit lifetime name needed here - -resolve_elided_anonymous_lifetime_report_error_suggestion = - consider introducing a higher-ranked lifetime here - -resolve_expected_module_found = - expected module, found {$res} `{$path_str}` - .label = not a module - -resolve_explicit_anonymous_lifetime_report_error = - `'_` cannot be used here - .label = `'_` is a reserved lifetime name - -resolve_explicit_unsafe_traits = - unsafe traits like `{$ident}` should be implemented explicitly - -resolve_extern_crate_loading_macro_not_at_crate_root = - an `extern crate` loading macros must be at the crate root - -resolve_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition - .suggestion = convert it to a `use` - -resolve_extern_crate_self_requires_renaming = - `extern crate self;` requires renaming - .suggestion = rename the `self` crate to be able to import it - -resolve_forward_declared_generic_in_const_param_ty = - const parameter types cannot reference parameters before they are declared - .label = const parameter type cannot reference `{$param}` before it is declared - -resolve_forward_declared_generic_param = - generic parameter defaults cannot reference parameters before they are declared - .label = cannot reference `{$param}` before it is declared - -resolve_found_an_item_configured_out = - found an item that was configured out - -resolve_generic_arguments_in_macro_path = - generic arguments in macro path - -resolve_generic_params_from_outer_item = - can't use {$is_self -> - [true] `Self` - *[false] generic parameters - } from outer item - .label = use of {$is_self -> - [true] `Self` - *[false] generic parameter - } from outer item - .refer_to_type_directly = refer to the type directly here instead - .suggestion = try introducing a local generic parameter here - .note = nested items are independent from their parent item for everything except for privacy and name resolution - -resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it - -resolve_generic_params_from_outer_item_const_param = const parameter from outer item - -resolve_generic_params_from_outer_item_inner_item = {$is_self -> - [true] `Self` - *[false] generic parameter - } used in this inner {$descr} - -resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl` - -resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here - -resolve_generic_params_from_outer_item_static = a `static` is a separate item from the item that contains it - -resolve_generic_params_from_outer_item_ty_param = type parameter from outer item - -resolve_ident_bound_more_than_once_in_parameter_list = - identifier `{$identifier}` is bound more than once in this parameter list - .label = used as parameter more than once - -resolve_ident_bound_more_than_once_in_same_pattern = - identifier `{$identifier}` is bound more than once in the same pattern - .label = used in a pattern more than once - -resolve_ident_imported_here_but_it_is_desc = - `{$imported_ident}` is imported here, but it is {$imported_ident_desc} - -resolve_ident_in_scope_but_it_is_desc = - `{$imported_ident}` is in scope, but it is {$imported_ident_desc} - -resolve_implicit_elided_lifetimes_not_allowed_here = implicit elided lifetime not allowed here - -resolve_imported_crate = `$crate` may not be imported - -resolve_imported_macro_not_found = imported macro not found - -resolve_imports_cannot_refer_to = - imports cannot refer to {$what} - -resolve_indeterminate = - cannot determine resolution for the visibility - -resolve_invalid_asm_sym = - invalid `sym` operand - .label = is a local variable - .help = `sym` operands must refer to either a function or a static - -resolve_is_private = - {$ident_descr} `{$ident}` is private - .label = private {$ident_descr} - -resolve_item_was_behind_feature = - the item is gated behind the `{$feature}` feature - -resolve_item_was_cfg_out = the item is gated here - -resolve_label_with_similar_name_reachable = - a label with a similar name is reachable - -resolve_legacy_derive_helpers = derive helper attribute is used before it is introduced - .label = the attribute is introduced here - -resolve_lending_iterator_report_error = - associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type - .note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type - -resolve_lifetime_param_in_enum_discriminant = - lifetime parameters may not be used in enum discriminant values - -resolve_lifetime_param_in_non_trivial_anon_const = - lifetime parameters may not be used in const expressions - -resolve_lowercase_self = - attempt to use a non-constant value in a constant - .suggestion = try using `Self` - -resolve_macro_cannot_use_as_attr = - `{$ident}` exists, but has no `attr` rules - -resolve_macro_cannot_use_as_derive = - `{$ident}` exists, but has no `derive` rules - -resolve_macro_cannot_use_as_fn_like = - `{$ident}` exists, but has no rules for function-like invocation - -resolve_macro_defined_later = - a macro with the same name exists, but it appears later - -resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments = - macro-expanded `extern crate` items cannot shadow names passed with `--extern` - -resolve_macro_expanded_macro_exports_accessed_by_absolute_paths = macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths - .note = the macro is defined here - -resolve_macro_expected_found = - expected {$expected}, found {$found} `{$macro_path}` - .label = not {$article} {$expected} - -resolve_macro_extern_deprecated = - `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - .help = try an outer attribute: `#[macro_use]` - -resolve_macro_is_private = macro `{$ident}` is private - -resolve_macro_rule_never_used = rule #{$n} of macro `{$name}` is never used - -resolve_macro_use_deprecated = - applying the `#[macro_use]` attribute to an `extern crate` item is deprecated - .help = remove it and import macros at use sites with a `use` item instead - -resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern crate self` - -resolve_macro_use_name_already_in_use = - `{$name}` is already in scope - .note = macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560) - -resolve_method_not_member_of_trait = - method `{$method}` is not a member of trait `{$trait_}` - .label = not a member of trait `{$trait_}` - -resolve_missing_macro_rules_name = maybe you have forgotten to define a name for this `macro_rules!` - -resolve_module_only = - visibility must resolve to a module - -resolve_name_defined_multiple_time = - the name `{$name}` is defined multiple times - .note = `{$name}` must be defined only once in the {$descr} namespace of this {$container} - -resolve_name_defined_multiple_time_old_binding_definition = - previous definition of the {$old_kind} `{$name}` here - -resolve_name_defined_multiple_time_old_binding_import = - previous import of the {$old_kind} `{$name}` here - -resolve_name_defined_multiple_time_redefined = - `{$name}` redefined here - -resolve_name_defined_multiple_time_reimported = - `{$name}` reimported here - -resolve_name_is_already_used_as_generic_parameter = - the name `{$name}` is already used for a generic parameter in this item's generic parameters - .label = already used - .first_use_of_name = first use of `{$name}` - -resolve_name_reserved_in_attribute_namespace = - name `{$ident}` is reserved in attribute namespace - -resolve_note_and_refers_to_the_item_defined_here = - {$first -> - [true] {$dots -> - [true] the {$binding_descr} `{$binding_name}` is defined here... - *[false] the {$binding_descr} `{$binding_name}` is defined here - } - *[false] {$dots -> - [true] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here... - *[false] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here - } - } - -resolve_out_of_scope_macro_calls = cannot find macro `{$path}` in the current scope when looking from {$location} - .label = not found from {$location} - .help = import `macro_rules` with `use` to make it callable above its definition - -resolve_outer_ident_is_not_publicly_reexported = - {$outer_ident_descr} `{$outer_ident}` is not publicly re-exported - -resolve_param_in_enum_discriminant = - generic parameters may not be used in enum discriminant values - .label = cannot perform const operation using `{$name}` - -resolve_param_in_non_trivial_anon_const = - generic parameters may not be used in const operations - .label = cannot perform const operation using `{$name}` - -resolve_param_in_non_trivial_anon_const_help = - add `#![feature(generic_const_exprs)]` to allow generic const expressions - -resolve_param_in_ty_of_const_param = - the type of const parameters must not depend on other generic parameters - .label = the type must not depend on the parameter `{$name}` - -resolve_pattern_doesnt_bind_name = pattern doesn't bind `{$name}` - -resolve_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported - .suggestion = consider making the `extern crate` item publicly accessible - -resolve_proc_macro_derive_resolution_fallback = cannot find {$ns_descr} `{$ident}` in this scope - .label = names from parent modules are not accessible without an explicit import - -resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it - .help = you can define integration tests in a directory named `tests` - -resolve_redundant_import_visibility = glob import doesn't reexport anything with visibility `{$import_vis}` because no imported item is public enough - .note = the most public imported item is `{$max_vis}` - .help = reduce the glob import's visibility or increase visibility of imported items - -resolve_reexport_of_crate_public = - re-export of crate public `{$ident}` - -resolve_reexport_of_private = - re-export of private `{$ident}` - -resolve_reexport_private_dependency = - {$kind} `{$name}` from private dependency '{$krate}' is re-exported - -resolve_relative_2018 = - relative paths are not supported in visibilities in 2018 edition or later - .suggestion = try - -resolve_remove_surrounding_derive = - remove from the surrounding `derive()` - -resolve_remove_unnecessary_import = remove unnecessary import - -resolve_self_import_can_only_appear_once_in_the_list = - `self` import can only appear once in an import list - .label = can only appear once in an import list - -resolve_self_import_only_in_import_list_with_non_empty_prefix = - `self` import can only appear in an import list with a non-empty prefix - .label = can only appear in an import list with a non-empty prefix - -resolve_self_imports_only_allowed_within = - `self` imports are only allowed within a {"{"} {"}"} list - -resolve_self_imports_only_allowed_within_multipart_suggestion = - alternatively, use the multi-path `use` syntax to import `self` - -resolve_self_imports_only_allowed_within_suggestion = - consider importing the module directly - -resolve_self_in_const_generic_ty = - cannot use `Self` in const parameter type - -resolve_self_in_generic_param_default = - generic parameters cannot use `Self` in their defaults - -resolve_similarly_named_defined_here = - similarly named {$candidate_descr} `{$candidate}` defined here - -resolve_single_item_defined_here = - {$candidate_descr} `{$candidate}` defined here - -resolve_static_lifetime_is_reserved = invalid lifetime parameter name: `{$lifetime}` - .label = 'static is a reserved lifetime name - -resolve_suggestion_import_ident_directly = - import `{$ident}` directly - -resolve_suggestion_import_ident_through_reexport = - import `{$ident}` through the re-export - -resolve_tool_module_imported = - cannot use a tool module through an import - .note = the tool module imported here - -resolve_tool_only_accepts_identifiers = - `{$tool}` only accepts identifiers - .label = not an identifier - -resolve_tool_was_already_registered = - tool `{$tool}` was already registered - .label = already registered here - -resolve_trait_impl_duplicate = - duplicate definitions with name `{$name}`: - .label = duplicate definition - .old_span_label = previous definition here - .trait_item_span = item in trait - -resolve_trait_impl_mismatch = - item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` - .label = does not match trait - .trait_impl_mismatch_label_item = item in trait -resolve_try_using_similarly_named_label = - try using similarly named label - -resolve_type_not_member_of_trait = - type `{$type_}` is not a member of trait `{$trait_}` - .label = not a member of trait `{$trait_}` - -resolve_type_param_in_enum_discriminant = - type parameters may not be used in enum discriminant values - -resolve_type_param_in_non_trivial_anon_const = - type parameters may not be used in const expressions - -resolve_undeclared_label = - use of undeclared label `{$name}` - .label = undeclared label `{$name}` - -resolve_underscore_lifetime_is_reserved = `'_` cannot be used here - .label = `'_` is a reserved lifetime name - .help = use another lifetime specifier - -resolve_unexpected_res_change_ty_to_const_param_sugg = - you might have meant to write a const parameter here - -resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg = - if you meant to collect the rest of the slice in `{$ident}`, use the at operator - -resolve_unknown_diagnostic_attribute = unknown diagnostic attribute -resolve_unknown_diagnostic_attribute_typo_sugg = an attribute with a similar name exists - -resolve_unnamed_crate_root_import = - crate root imports need to be explicitly named: `use crate as name;` - -resolve_unreachable_label = - use of unreachable label `{$name}` - .label = unreachable label `{$name}` - .label_definition_span = unreachable label defined here - .note = labels are unreachable through functions, closures, async blocks and modules - -resolve_unreachable_label_similar_name_reachable = - a label with a similar name is reachable - -resolve_unreachable_label_similar_name_unreachable = - a label with a similar name exists but is also unreachable - -resolve_unreachable_label_suggestion_use_similarly_named = - try using similarly named label - -resolve_unreachable_label_with_similar_name_exists = - a label with a similar name exists but is unreachable - -resolve_unused_extern_crate = unused extern crate - .label = unused - .suggestion = remove the unused `extern crate` - -resolve_unused_label = unused label - -resolve_unused_macro_definition = unused macro definition: `{$name}` - -resolve_unused_macro_use = unused `#[macro_use]` import - -resolve_variable_bound_with_different_mode = - variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` - .label = bound in different ways - .first_binding_span = first binding - -resolve_variable_is_a_typo = you might have meant to use the similarly named previously used binding `{$typo}` - -resolve_variable_is_not_bound_in_all_patterns = - variable `{$name}` is not bound in all patterns - -resolve_variable_not_in_all_patterns = variable not in all patterns diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 3e5446403052..7afdbf6a469f 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,21 +1,31 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, DiagMessage, Diagnostic, ElidedLifetimeInPathSubdiag, - EmissionGuarantee, IntoDiagArg, Level, LintDiagnostic, MultiSpan, Subdiagnostic, + EmissionGuarantee, IntoDiagArg, Level, LintDiagnostic, MultiSpan, Subdiagnostic, inline_fluent, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span, Symbol}; +use crate::Res; use crate::late::PatternSource; -use crate::{Res, fluent_generated as fluent}; #[derive(Diagnostic)] -#[diag(resolve_generic_params_from_outer_item, code = E0401)] -#[note] +#[diag("can't use {$is_self -> + [true] `Self` + *[false] generic parameters + } from outer item", code = E0401)] +#[note( + "nested items are independent from their parent item for everything except for privacy and name resolution" +)] pub(crate) struct GenericParamsFromOuterItem { #[primary_span] - #[label] + #[label( + "use of {$is_self -> + [true] `Self` + *[false] generic parameter + } from outer item" + )] pub(crate) span: Span, #[subdiagnostic] pub(crate) label: Option, @@ -31,7 +41,12 @@ pub(crate) struct GenericParamsFromOuterItem { } #[derive(Subdiagnostic)] -#[label(resolve_generic_params_from_outer_item_inner_item)] +#[label( + "{$is_self -> + [true] `Self` + *[false] generic parameter + } used in this inner {$descr}" +)] pub(crate) struct GenericParamsFromOuterItemInnerItem { #[primary_span] pub(crate) span: Span, @@ -40,27 +55,27 @@ pub(crate) struct GenericParamsFromOuterItemInnerItem { #[derive(Subdiagnostic)] pub(crate) enum GenericParamsFromOuterItemStaticOrConst { - #[note(resolve_generic_params_from_outer_item_static)] + #[note("a `static` is a separate item from the item that contains it")] Static, - #[note(resolve_generic_params_from_outer_item_const)] + #[note("a `const` is a separate item from the item that contains it")] Const, } #[derive(Subdiagnostic)] pub(crate) enum GenericParamsFromOuterItemLabel { - #[label(resolve_generic_params_from_outer_item_self_ty_param)] + #[label("can't use `Self` here")] SelfTyParam(#[primary_span] Span), - #[label(resolve_generic_params_from_outer_item_self_ty_alias)] + #[label("`Self` type implicitly declared here, by this `impl`")] SelfTyAlias(#[primary_span] Span), - #[label(resolve_generic_params_from_outer_item_ty_param)] + #[label("type parameter from outer item")] TyParam(#[primary_span] Span), - #[label(resolve_generic_params_from_outer_item_const_param)] + #[label("const parameter from outer item")] ConstParam(#[primary_span] Span), } #[derive(Subdiagnostic)] #[suggestion( - resolve_suggestion, + "try introducing a local generic parameter here", code = "{snippet}", applicability = "maybe-incorrect", style = "verbose" @@ -72,7 +87,7 @@ pub(crate) struct GenericParamsFromOuterItemSugg { } #[derive(Subdiagnostic)] #[suggestion( - resolve_refer_to_type_directly, + "refer to the type directly here instead", code = "{snippet}", applicability = "maybe-incorrect", style = "verbose" @@ -84,21 +99,21 @@ pub(crate) struct UseTypeDirectly { } #[derive(Diagnostic)] -#[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)] +#[diag("the name `{$name}` is already used for a generic parameter in this item's generic parameters", code = E0403)] pub(crate) struct NameAlreadyUsedInParameterList { #[primary_span] - #[label] + #[label("already used")] pub(crate) span: Span, - #[label(resolve_first_use_of_name)] + #[label("first use of `{$name}`")] pub(crate) first_use_span: Span, pub(crate) name: Ident, } #[derive(Diagnostic)] -#[diag(resolve_method_not_member_of_trait, code = E0407)] +#[diag("method `{$method}` is not a member of trait `{$trait_}`", code = E0407)] pub(crate) struct MethodNotMemberOfTrait { #[primary_span] - #[label] + #[label("not a member of trait `{$trait_}`")] pub(crate) span: Span, pub(crate) method: Ident, pub(crate) trait_: String, @@ -108,7 +123,7 @@ pub(crate) struct MethodNotMemberOfTrait { #[derive(Subdiagnostic)] #[suggestion( - resolve_associated_fn_with_similar_name_exists, + "there is an associated function with a similar name", code = "{candidate}", applicability = "maybe-incorrect" )] @@ -119,10 +134,10 @@ pub(crate) struct AssociatedFnWithSimilarNameExists { } #[derive(Diagnostic)] -#[diag(resolve_type_not_member_of_trait, code = E0437)] +#[diag("type `{$type_}` is not a member of trait `{$trait_}`", code = E0437)] pub(crate) struct TypeNotMemberOfTrait { #[primary_span] - #[label] + #[label("not a member of trait `{$trait_}`")] pub(crate) span: Span, pub(crate) type_: Ident, pub(crate) trait_: String, @@ -132,7 +147,7 @@ pub(crate) struct TypeNotMemberOfTrait { #[derive(Subdiagnostic)] #[suggestion( - resolve_associated_type_with_similar_name_exists, + "there is an associated type with a similar name", code = "{candidate}", applicability = "maybe-incorrect" )] @@ -143,10 +158,10 @@ pub(crate) struct AssociatedTypeWithSimilarNameExists { } #[derive(Diagnostic)] -#[diag(resolve_const_not_member_of_trait, code = E0438)] +#[diag("const `{$const_}` is not a member of trait `{$trait_}`", code = E0438)] pub(crate) struct ConstNotMemberOfTrait { #[primary_span] - #[label] + #[label("not a member of trait `{$trait_}`")] pub(crate) span: Span, pub(crate) const_: Ident, pub(crate) trait_: String, @@ -156,7 +171,7 @@ pub(crate) struct ConstNotMemberOfTrait { #[derive(Subdiagnostic)] #[suggestion( - resolve_associated_const_with_similar_name_exists, + "there is an associated constant with a similar name", code = "{candidate}", applicability = "maybe-incorrect" )] @@ -167,39 +182,39 @@ pub(crate) struct AssociatedConstWithSimilarNameExists { } #[derive(Diagnostic)] -#[diag(resolve_variable_bound_with_different_mode, code = E0409)] +#[diag("variable `{$variable_name}` is bound inconsistently across alternatives separated by `|`", code = E0409)] pub(crate) struct VariableBoundWithDifferentMode { #[primary_span] - #[label] + #[label("bound in different ways")] pub(crate) span: Span, - #[label(resolve_first_binding_span)] + #[label("first binding")] pub(crate) first_binding_span: Span, pub(crate) variable_name: Ident, } #[derive(Diagnostic)] -#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = E0415)] +#[diag("identifier `{$identifier}` is bound more than once in this parameter list", code = E0415)] pub(crate) struct IdentifierBoundMoreThanOnceInParameterList { #[primary_span] - #[label] + #[label("used as parameter more than once")] pub(crate) span: Span, pub(crate) identifier: Ident, } #[derive(Diagnostic)] -#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = E0416)] +#[diag("identifier `{$identifier}` is bound more than once in the same pattern", code = E0416)] pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern { #[primary_span] - #[label] + #[label("used in a pattern more than once")] pub(crate) span: Span, pub(crate) identifier: Ident, } #[derive(Diagnostic)] -#[diag(resolve_undeclared_label, code = E0426)] +#[diag("use of undeclared label `{$name}`", code = E0426)] pub(crate) struct UndeclaredLabel { #[primary_span] - #[label] + #[label("undeclared label `{$name}`")] pub(crate) span: Span, pub(crate) name: Symbol, #[subdiagnostic] @@ -211,12 +226,12 @@ pub(crate) struct UndeclaredLabel { } #[derive(Subdiagnostic)] -#[label(resolve_label_with_similar_name_reachable)] +#[label("a label with a similar name is reachable")] pub(crate) struct LabelWithSimilarNameReachable(#[primary_span] pub(crate) Span); #[derive(Subdiagnostic)] #[suggestion( - resolve_try_using_similarly_named_label, + "try using similarly named label", code = "{ident_name}", applicability = "maybe-incorrect" )] @@ -227,38 +242,38 @@ pub(crate) struct TryUsingSimilarlyNamedLabel { } #[derive(Subdiagnostic)] -#[label(resolve_unreachable_label_with_similar_name_exists)] +#[label("a label with a similar name exists but is unreachable")] pub(crate) struct UnreachableLabelWithSimilarNameExists { #[primary_span] pub(crate) ident_span: Span, } #[derive(Diagnostic)] -#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = E0430)] +#[diag("`self` import can only appear once in an import list", code = E0430)] pub(crate) struct SelfImportCanOnlyAppearOnceInTheList { #[primary_span] - #[label] + #[label("can only appear once in an import list")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = E0431)] +#[diag("`self` import can only appear in an import list with a non-empty prefix", code = E0431)] pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix { #[primary_span] - #[label] + #[label("can only appear in an import list with a non-empty prefix")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = E0434)] -#[help] +#[diag("can't capture dynamic environment in a fn item", code = E0434)] +#[help("use the `|| {\"{\"} ... {\"}\"}` closure form instead")] pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = E0435)] +#[diag("attempt to use a non-constant value in a constant", code = E0435)] pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> { #[primary_span] pub(crate) span: Span, @@ -272,7 +287,7 @@ pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion, + "consider using `{$suggestion}` instead of `{$current}`", style = "verbose", applicability = "has-placeholders" )] @@ -287,14 +302,14 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> { } #[derive(Subdiagnostic)] -#[label(resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion)] +#[label("non-constant value")] pub(crate) struct AttemptToUseNonConstantValueInConstantLabelWithSuggestion { #[primary_span] pub(crate) span: Span, } #[derive(Subdiagnostic)] -#[label(resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion)] +#[label("this would need to be a `{$suggestion}`")] pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> { #[primary_span] pub(crate) ident_span: Span, @@ -302,7 +317,7 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> { } #[derive(Diagnostic)] -#[diag(resolve_self_imports_only_allowed_within, code = E0429)] +#[diag("`self` imports are only allowed within a {\"{\"} {\"}\"} list", code = E0429)] pub(crate) struct SelfImportsOnlyAllowedWithin { #[primary_span] pub(crate) span: Span, @@ -314,7 +329,7 @@ pub(crate) struct SelfImportsOnlyAllowedWithin { #[derive(Subdiagnostic)] #[suggestion( - resolve_self_imports_only_allowed_within_suggestion, + "consider importing the module directly", code = "", applicability = "machine-applicable" )] @@ -325,7 +340,7 @@ pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion { #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_self_imports_only_allowed_within_multipart_suggestion, + "alternatively, use the multi-path `use` syntax to import `self`", applicability = "machine-applicable" )] pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion { @@ -336,17 +351,17 @@ pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion { } #[derive(Diagnostic)] -#[diag(resolve_binding_shadows_something_unacceptable, code = E0530)] +#[diag("{$shadowing_binding}s cannot shadow {$shadowed_binding}s", code = E0530)] pub(crate) struct BindingShadowsSomethingUnacceptable<'a> { #[primary_span] - #[label] + #[label("cannot be named the same as {$article} {$shadowed_binding}")] pub(crate) span: Span, pub(crate) shadowing_binding: PatternSource, pub(crate) shadowed_binding: Res, pub(crate) article: &'a str, #[subdiagnostic] pub(crate) sub_suggestion: Option, - #[label(resolve_label_shadowed_binding)] + #[label("the {$shadowed_binding} `{$name}` is {$participle} here")] pub(crate) shadowed_binding_span: Span, pub(crate) participle: &'a str, pub(crate) name: Symbol, @@ -354,7 +369,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptable<'a> { #[derive(Subdiagnostic)] #[suggestion( - resolve_binding_shadows_something_unacceptable_suggestion, + "try specify the pattern arguments", code = "{name}(..)", applicability = "unspecified" )] @@ -365,51 +380,51 @@ pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion { } #[derive(Diagnostic)] -#[diag(resolve_forward_declared_generic_param, code = E0128)] +#[diag("generic parameter defaults cannot reference parameters before they are declared", code = E0128)] pub(crate) struct ForwardDeclaredGenericParam { #[primary_span] - #[label] + #[label("cannot reference `{$param}` before it is declared")] pub(crate) span: Span, pub(crate) param: Symbol, } #[derive(Diagnostic)] -#[diag(resolve_forward_declared_generic_in_const_param_ty)] +#[diag("const parameter types cannot reference parameters before they are declared")] pub(crate) struct ForwardDeclaredGenericInConstParamTy { #[primary_span] - #[label] + #[label("const parameter type cannot reference `{$param}` before it is declared")] pub(crate) span: Span, pub(crate) param: Symbol, } #[derive(Diagnostic)] -#[diag(resolve_param_in_ty_of_const_param, code = E0770)] +#[diag("the type of const parameters must not depend on other generic parameters", code = E0770)] pub(crate) struct ParamInTyOfConstParam { #[primary_span] - #[label] + #[label("the type must not depend on the parameter `{$name}`")] pub(crate) span: Span, pub(crate) name: Symbol, } #[derive(Diagnostic)] -#[diag(resolve_self_in_generic_param_default, code = E0735)] +#[diag("generic parameters cannot use `Self` in their defaults", code = E0735)] pub(crate) struct SelfInGenericParamDefault { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_self_in_const_generic_ty)] +#[diag("cannot use `Self` in const parameter type")] pub(crate) struct SelfInConstGenericTy { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_param_in_non_trivial_anon_const)] +#[diag("generic parameters may not be used in const operations")] pub(crate) struct ParamInNonTrivialAnonConst { #[primary_span] - #[label] + #[label("cannot perform const operation using `{$name}`")] pub(crate) span: Span, pub(crate) name: Symbol, #[subdiagnostic] @@ -419,29 +434,29 @@ pub(crate) struct ParamInNonTrivialAnonConst { } #[derive(Subdiagnostic)] -#[help(resolve_param_in_non_trivial_anon_const_help)] +#[help("add `#![feature(generic_const_exprs)]` to allow generic const expressions")] pub(crate) struct ParamInNonTrivialAnonConstHelp; #[derive(Debug)] #[derive(Subdiagnostic)] pub(crate) enum ParamKindInNonTrivialAnonConst { - #[note(resolve_type_param_in_non_trivial_anon_const)] + #[note("type parameters may not be used in const expressions")] Type, - #[help(resolve_const_param_in_non_trivial_anon_const)] + #[help("const parameters may only be used as standalone arguments here, i.e. `{$name}`")] Const { name: Symbol }, - #[note(resolve_lifetime_param_in_non_trivial_anon_const)] + #[note("lifetime parameters may not be used in const expressions")] Lifetime, } #[derive(Diagnostic)] -#[diag(resolve_unreachable_label, code = E0767)] -#[note] +#[diag("use of unreachable label `{$name}`", code = E0767)] +#[note("labels are unreachable through functions, closures, async blocks and modules")] pub(crate) struct UnreachableLabel { #[primary_span] - #[label] + #[label("unreachable label `{$name}`")] pub(crate) span: Span, pub(crate) name: Symbol, - #[label(resolve_label_definition_span)] + #[label("unreachable label defined here")] pub(crate) definition_span: Span, #[subdiagnostic] pub(crate) sub_suggestion: Option, @@ -453,7 +468,7 @@ pub(crate) struct UnreachableLabel { #[derive(Subdiagnostic)] #[suggestion( - resolve_unreachable_label_suggestion_use_similarly_named, + "try using similarly named label", code = "{ident_name}", applicability = "maybe-incorrect" )] @@ -464,104 +479,114 @@ pub(crate) struct UnreachableLabelSubSuggestion { } #[derive(Subdiagnostic)] -#[label(resolve_unreachable_label_similar_name_reachable)] +#[label("a label with a similar name is reachable")] pub(crate) struct UnreachableLabelSubLabel { #[primary_span] pub(crate) ident_span: Span, } #[derive(Subdiagnostic)] -#[label(resolve_unreachable_label_similar_name_unreachable)] +#[label("a label with a similar name exists but is also unreachable")] pub(crate) struct UnreachableLabelSubLabelUnreachable { #[primary_span] pub(crate) ident_span: Span, } #[derive(Diagnostic)] -#[diag(resolve_invalid_asm_sym)] -#[help] +#[diag("invalid `sym` operand")] +#[help("`sym` operands must refer to either a function or a static")] pub(crate) struct InvalidAsmSym { #[primary_span] - #[label] + #[label("is a local variable")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_lowercase_self)] +#[diag("attempt to use a non-constant value in a constant")] pub(crate) struct LowercaseSelf { #[primary_span] - #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")] + #[suggestion( + "try using `Self`", + code = "Self", + applicability = "maybe-incorrect", + style = "short" + )] pub(crate) span: Span, } #[derive(Debug)] #[derive(Diagnostic)] -#[diag(resolve_binding_in_never_pattern)] +#[diag("never patterns cannot contain variable bindings")] pub(crate) struct BindingInNeverPattern { #[primary_span] - #[suggestion(code = "_", applicability = "machine-applicable", style = "short")] + #[suggestion( + "use a wildcard `_` instead", + code = "_", + applicability = "machine-applicable", + style = "short" + )] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_trait_impl_duplicate, code = E0201)] +#[diag("duplicate definitions with name `{$name}`:", code = E0201)] pub(crate) struct TraitImplDuplicate { #[primary_span] - #[label] + #[label("duplicate definition")] pub(crate) span: Span, - #[label(resolve_old_span_label)] + #[label("previous definition here")] pub(crate) old_span: Span, - #[label(resolve_trait_item_span)] + #[label("item in trait")] pub(crate) trait_item_span: Span, pub(crate) name: Ident, } #[derive(Diagnostic)] -#[diag(resolve_relative_2018)] +#[diag("relative paths are not supported in visibilities in 2018 edition or later")] pub(crate) struct Relative2018 { #[primary_span] pub(crate) span: Span, - #[suggestion(code = "crate::{path_str}", applicability = "maybe-incorrect")] + #[suggestion("try", code = "crate::{path_str}", applicability = "maybe-incorrect")] pub(crate) path_span: Span, pub(crate) path_str: String, } #[derive(Diagnostic)] -#[diag(resolve_ancestor_only, code = E0742)] +#[diag("visibilities can only be restricted to ancestor modules", code = E0742)] pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span); #[derive(Diagnostic)] -#[diag(resolve_expected_module_found, code = E0577)] +#[diag("expected module, found {$res} `{$path_str}`", code = E0577)] pub(crate) struct ExpectedModuleFound { #[primary_span] - #[label] + #[label("not a module")] pub(crate) span: Span, pub(crate) res: Res, pub(crate) path_str: String, } #[derive(Diagnostic)] -#[diag(resolve_indeterminate, code = E0578)] +#[diag("cannot determine resolution for the visibility", code = E0578)] pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span); #[derive(Diagnostic)] -#[diag(resolve_tool_module_imported)] +#[diag("cannot use a tool module through an import")] pub(crate) struct ToolModuleImported { #[primary_span] pub(crate) span: Span, - #[note] + #[note("the tool module imported here")] pub(crate) import: Span, } #[derive(Diagnostic)] -#[diag(resolve_module_only)] +#[diag("visibility must resolve to a module")] pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span); #[derive(Diagnostic)] -#[diag(resolve_macro_expected_found)] +#[diag("expected {$expected}, found {$found} `{$macro_path}`")] pub(crate) struct MacroExpectedFound<'a> { #[primary_span] - #[label] + #[label("not {$article} {$expected}")] pub(crate) span: Span, pub(crate) found: &'a str, pub(crate) article: &'static str, @@ -574,60 +599,66 @@ pub(crate) struct MacroExpectedFound<'a> { } #[derive(Subdiagnostic)] -#[help(resolve_remove_surrounding_derive)] +#[help("remove from the surrounding `derive()`")] pub(crate) struct RemoveSurroundingDerive { #[primary_span] pub(crate) span: Span, } #[derive(Subdiagnostic)] -#[help(resolve_add_as_non_derive)] +#[help( + " + add as non-Derive macro + `#[{$macro_path}]`" +)] pub(crate) struct AddAsNonDerive<'a> { pub(crate) macro_path: &'a str, } #[derive(Diagnostic)] -#[diag(resolve_proc_macro_same_crate)] +#[diag("can't use a procedural macro from the same crate that defines it")] pub(crate) struct ProcMacroSameCrate { #[primary_span] pub(crate) span: Span, - #[help] + #[help("you can define integration tests in a directory named `tests`")] pub(crate) is_test: bool, } #[derive(LintDiagnostic)] -#[diag(resolve_proc_macro_derive_resolution_fallback)] +#[diag("cannot find {$ns_descr} `{$ident}` in this scope")] pub(crate) struct ProcMacroDeriveResolutionFallback { - #[label] + #[label("names from parent modules are not accessible without an explicit import")] pub span: Span, pub ns_descr: &'static str, pub ident: Symbol, } #[derive(LintDiagnostic)] -#[diag(resolve_macro_expanded_macro_exports_accessed_by_absolute_paths)] +#[diag( + "macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths" +)] pub(crate) struct MacroExpandedMacroExportsAccessedByAbsolutePaths { - #[note] + #[note("the macro is defined here")] pub definition: Span, } #[derive(Diagnostic)] -#[diag(resolve_imported_crate)] +#[diag("`$crate` may not be imported")] pub(crate) struct CrateImported { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_macro_use_extern_crate_self)] +#[diag("`#[macro_use]` is not supported on `extern crate self`")] pub(crate) struct MacroUseExternCrateSelf { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_accessible_unsure)] -#[note] +#[diag("not sure whether the path is accessible or not")] +#[note("the type may have associated items, but we are currently not checking them")] pub(crate) struct CfgAccessibleUnsure { #[primary_span] pub(crate) span: Span, @@ -635,10 +666,10 @@ pub(crate) struct CfgAccessibleUnsure { #[derive(Debug)] #[derive(Diagnostic)] -#[diag(resolve_param_in_enum_discriminant)] +#[diag("generic parameters may not be used in enum discriminant values")] pub(crate) struct ParamInEnumDiscriminant { #[primary_span] - #[label] + #[label("cannot perform const operation using `{$name}`")] pub(crate) span: Span, pub(crate) name: Symbol, #[subdiagnostic] @@ -648,16 +679,16 @@ pub(crate) struct ParamInEnumDiscriminant { #[derive(Debug)] #[derive(Subdiagnostic)] pub(crate) enum ParamKindInEnumDiscriminant { - #[note(resolve_type_param_in_enum_discriminant)] + #[note("type parameters may not be used in enum discriminant values")] Type, - #[note(resolve_const_param_in_enum_discriminant)] + #[note("const parameters may not be used in enum discriminant values")] Const, - #[note(resolve_lifetime_param_in_enum_discriminant)] + #[note("lifetime parameters may not be used in enum discriminant values")] Lifetime, } #[derive(Subdiagnostic)] -#[label(resolve_change_import_binding)] +#[label("you can use `as` to change the binding name of the import")] pub(crate) struct ChangeImportBinding { #[primary_span] pub(crate) span: Span, @@ -665,7 +696,7 @@ pub(crate) struct ChangeImportBinding { #[derive(Subdiagnostic)] #[suggestion( - resolve_change_import_binding, + "you can use `as` to change the binding name of the import", code = "{suggestion}", applicability = "maybe-incorrect" )] @@ -676,7 +707,7 @@ pub(crate) struct ChangeImportBindingSuggestion { } #[derive(Diagnostic)] -#[diag(resolve_imports_cannot_refer_to)] +#[diag("imports cannot refer to {$what}")] pub(crate) struct ImportsCannotReferTo<'a> { #[primary_span] pub(crate) span: Span, @@ -684,7 +715,7 @@ pub(crate) struct ImportsCannotReferTo<'a> { } #[derive(Diagnostic)] -#[diag(resolve_cannot_find_ident_in_this_scope)] +#[diag("cannot find {$expected} `{$ident}` in this scope")] pub(crate) struct CannotFindIdentInThisScope<'a> { #[primary_span] pub(crate) span: Span, @@ -693,7 +724,7 @@ pub(crate) struct CannotFindIdentInThisScope<'a> { } #[derive(Subdiagnostic)] -#[note(resolve_explicit_unsafe_traits)] +#[note("unsafe traits like `{$ident}` should be implemented explicitly")] pub(crate) struct ExplicitUnsafeTraits { #[primary_span] pub(crate) span: Span, @@ -701,14 +732,14 @@ pub(crate) struct ExplicitUnsafeTraits { } #[derive(Subdiagnostic)] -#[note(resolve_macro_defined_later)] +#[note("a macro with the same name exists, but it appears later")] pub(crate) struct MacroDefinedLater { #[primary_span] pub(crate) span: Span, } #[derive(Subdiagnostic)] -#[label(resolve_consider_move_macro_position)] +#[label("consider moving the definition of `{$ident}` before this call")] pub(crate) struct MacroSuggMovePosition { #[primary_span] pub(crate) span: Span, @@ -717,19 +748,19 @@ pub(crate) struct MacroSuggMovePosition { #[derive(Subdiagnostic)] pub(crate) enum MacroRulesNot { - #[label(resolve_macro_cannot_use_as_fn_like)] + #[label("`{$ident}` exists, but has no rules for function-like invocation")] Func { #[primary_span] span: Span, ident: Ident, }, - #[label(resolve_macro_cannot_use_as_attr)] + #[label("`{$ident}` exists, but has no `attr` rules")] Attr { #[primary_span] span: Span, ident: Ident, }, - #[label(resolve_macro_cannot_use_as_derive)] + #[label("`{$ident}` exists, but has no `derive` rules")] Derive { #[primary_span] span: Span, @@ -738,22 +769,18 @@ pub(crate) enum MacroRulesNot { } #[derive(Subdiagnostic)] -#[note(resolve_missing_macro_rules_name)] +#[note("maybe you have forgotten to define a name for this `macro_rules!`")] pub(crate) struct MaybeMissingMacroRulesName { #[primary_span] pub(crate) spans: MultiSpan, } #[derive(Subdiagnostic)] -#[help(resolve_added_macro_use)] +#[help("have you added the `#[macro_use]` on the module/import?")] pub(crate) struct AddedMacroUse; #[derive(Subdiagnostic)] -#[suggestion( - resolve_consider_adding_a_derive, - code = "{suggestion}", - applicability = "maybe-incorrect" -)] +#[suggestion("consider adding a derive", code = "{suggestion}", applicability = "maybe-incorrect")] pub(crate) struct ConsiderAddingADerive { #[primary_span] pub(crate) span: Span, @@ -761,15 +788,15 @@ pub(crate) struct ConsiderAddingADerive { } #[derive(Diagnostic)] -#[diag(resolve_cannot_determine_import_resolution)] +#[diag("cannot determine resolution for the import")] pub(crate) struct CannotDetermineImportResolution { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_cannot_determine_macro_resolution)] -#[note] +#[diag("cannot determine resolution for the {$kind} `{$path}`")] +#[note("import resolution is stuck, try simplifying macro imports")] pub(crate) struct CannotDetermineMacroResolution { #[primary_span] pub(crate) span: Span, @@ -778,7 +805,7 @@ pub(crate) struct CannotDetermineMacroResolution { } #[derive(Diagnostic)] -#[diag(resolve_cannot_be_reexported_private, code = E0364)] +#[diag("`{$ident}` is private, and cannot be re-exported", code = E0364)] pub(crate) struct CannotBeReexportedPrivate { #[primary_span] pub(crate) span: Span, @@ -786,7 +813,7 @@ pub(crate) struct CannotBeReexportedPrivate { } #[derive(Diagnostic)] -#[diag(resolve_cannot_be_reexported_crate_public, code = E0364)] +#[diag("`{$ident}` is only public within the crate, and cannot be re-exported outside", code = E0364)] pub(crate) struct CannotBeReexportedCratePublic { #[primary_span] pub(crate) span: Span, @@ -794,35 +821,40 @@ pub(crate) struct CannotBeReexportedCratePublic { } #[derive(Diagnostic)] -#[diag(resolve_cannot_be_reexported_private, code = E0365)] -#[note(resolve_consider_declaring_with_pub)] +#[diag("`{$ident}` is private, and cannot be re-exported", code = E0365)] +#[note("consider declaring type or module `{$ident}` with `pub`")] pub(crate) struct CannotBeReexportedPrivateNS { #[primary_span] - #[label(resolve_reexport_of_private)] + #[label("re-export of private `{$ident}`")] pub(crate) span: Span, pub(crate) ident: Ident, } #[derive(Diagnostic)] -#[diag(resolve_cannot_be_reexported_crate_public, code = E0365)] -#[note(resolve_consider_declaring_with_pub)] +#[diag("`{$ident}` is only public within the crate, and cannot be re-exported outside", code = E0365)] +#[note("consider declaring type or module `{$ident}` with `pub`")] pub(crate) struct CannotBeReexportedCratePublicNS { #[primary_span] - #[label(resolve_reexport_of_crate_public)] + #[label("re-export of crate public `{$ident}`")] pub(crate) span: Span, pub(crate) ident: Ident, } #[derive(LintDiagnostic)] -#[diag(resolve_private_extern_crate_reexport, code = E0365)] +#[diag("extern crate `{$ident}` is private and cannot be re-exported", code = E0365)] pub(crate) struct PrivateExternCrateReexport { pub ident: Ident, - #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")] + #[suggestion( + "consider making the `extern crate` item publicly accessible", + code = "pub ", + style = "verbose", + applicability = "maybe-incorrect" + )] pub sugg: Span, } #[derive(Subdiagnostic)] -#[help(resolve_consider_adding_macro_export)] +#[help("consider adding a `#[macro_export]` to the macro in the imported module")] pub(crate) struct ConsiderAddingMacroExport { #[primary_span] pub(crate) span: Span, @@ -830,7 +862,7 @@ pub(crate) struct ConsiderAddingMacroExport { #[derive(Subdiagnostic)] #[suggestion( - resolve_consider_marking_as_pub_crate, + "in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)`", code = "pub(crate)", applicability = "maybe-incorrect" )] @@ -840,7 +872,7 @@ pub(crate) struct ConsiderMarkingAsPubCrate { } #[derive(Subdiagnostic)] -#[note(resolve_consider_marking_as_pub)] +#[note("consider marking `{$ident}` as `pub` in the imported module")] pub(crate) struct ConsiderMarkingAsPub { #[primary_span] pub(crate) span: Span, @@ -848,7 +880,7 @@ pub(crate) struct ConsiderMarkingAsPub { } #[derive(Diagnostic)] -#[diag(resolve_cannot_glob_import_possible_crates)] +#[diag("cannot glob-import all possible crates")] pub(crate) struct CannotGlobImportAllCrates { #[primary_span] pub(crate) span: Span, @@ -856,7 +888,7 @@ pub(crate) struct CannotGlobImportAllCrates { #[derive(Subdiagnostic)] #[suggestion( - resolve_unexpected_res_change_ty_to_const_param_sugg, + "you might have meant to write a const parameter here", code = "const ", style = "verbose" )] @@ -869,7 +901,7 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg { #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_unexpected_res_change_ty_to_const_param_sugg, + "you might have meant to write a const parameter here", applicability = "has-placeholders", style = "verbose" )] @@ -882,7 +914,7 @@ pub(crate) struct UnexpectedResChangeTyParamToConstParamSugg { #[derive(Subdiagnostic)] #[suggestion( - resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg, + "if you meant to collect the rest of the slice in `{$ident}`, use the at operator", code = "{snippet}", applicability = "maybe-incorrect", style = "verbose" @@ -895,23 +927,27 @@ pub(crate) struct UnexpectedResUseAtOpInSlicePatWithRangeSugg { } #[derive(Diagnostic)] -#[diag(resolve_extern_crate_loading_macro_not_at_crate_root, code = E0468)] +#[diag("an `extern crate` loading macros must be at the crate root", code = E0468)] pub(crate) struct ExternCrateLoadingMacroNotAtCrateRoot { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_extern_crate_self_requires_renaming)] +#[diag("`extern crate self;` requires renaming")] pub(crate) struct ExternCrateSelfRequiresRenaming { #[primary_span] - #[suggestion(code = "extern crate self as name;", applicability = "has-placeholders")] + #[suggestion( + "rename the `self` crate to be able to import it", + code = "extern crate self as name;", + applicability = "has-placeholders" + )] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_macro_use_name_already_in_use)] -#[note] +#[diag("`{$name}` is already in scope")] +#[note("macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)")] pub(crate) struct MacroUseNameAlreadyInUse { #[primary_span] pub(crate) span: Span, @@ -919,74 +955,80 @@ pub(crate) struct MacroUseNameAlreadyInUse { } #[derive(Diagnostic)] -#[diag(resolve_imported_macro_not_found, code = E0469)] +#[diag("imported macro not found", code = E0469)] pub(crate) struct ImportedMacroNotFound { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_macro_extern_deprecated)] +#[diag("`#[macro_escape]` is a deprecated synonym for `#[macro_use]`")] pub(crate) struct MacroExternDeprecated { #[primary_span] pub(crate) span: Span, - #[help] + #[help("try an outer attribute: `#[macro_use]`")] pub inner_attribute: bool, } #[derive(Diagnostic)] -#[diag(resolve_arguments_macro_use_not_allowed)] +#[diag("arguments to `macro_use` are not allowed here")] pub(crate) struct ArgumentsMacroUseNotAllowed { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_unnamed_crate_root_import)] +#[diag("crate root imports need to be explicitly named: `use crate as name;`")] pub(crate) struct UnnamedCrateRootImport { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments)] +#[diag("macro-expanded `extern crate` items cannot shadow names passed with `--extern`")] pub(crate) struct MacroExpandedExternCrateCannotShadowExternArguments { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_elided_anonymous_lifetime_report_error, code = E0637)] +#[diag("`&` without an explicit lifetime name cannot be used here", code = E0637)] pub(crate) struct ElidedAnonymousLifetimeReportError { #[primary_span] - #[label] + #[label("explicit lifetime name needed here")] pub(crate) span: Span, #[subdiagnostic] pub(crate) suggestion: Option, } #[derive(Diagnostic)] -#[diag(resolve_lending_iterator_report_error)] +#[diag( + "associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type" +)] pub(crate) struct LendingIteratorReportError { #[primary_span] pub(crate) lifetime: Span, - #[note] + #[note( + "you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type" + )] pub(crate) ty: Span, } #[derive(Diagnostic)] -#[diag(resolve_anonymous_lifetime_non_gat_report_error)] +#[diag("missing lifetime in associated type")] pub(crate) struct AnonymousLifetimeNonGatReportError { #[primary_span] - #[label] + #[label("this lifetime must come from the implemented type")] pub(crate) lifetime: Span, - #[note] + #[note( + "in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type" + )] pub(crate) decl: MultiSpan, } #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_elided_anonymous_lifetime_report_error_suggestion, + "consider introducing a higher-ranked lifetime here", applicability = "machine-applicable" )] pub(crate) struct ElidedAnonymousLifetimeReportErrorSuggestion { @@ -997,15 +1039,15 @@ pub(crate) struct ElidedAnonymousLifetimeReportErrorSuggestion { } #[derive(Diagnostic)] -#[diag(resolve_explicit_anonymous_lifetime_report_error, code = E0637)] +#[diag("`'_` cannot be used here", code = E0637)] pub(crate) struct ExplicitAnonymousLifetimeReportError { #[primary_span] - #[label] + #[label("`'_` is a reserved lifetime name")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_implicit_elided_lifetimes_not_allowed_here, code = E0726)] +#[diag("implicit elided lifetime not allowed here", code = E0726)] pub(crate) struct ImplicitElidedLifetimeNotAllowedHere { #[primary_span] pub(crate) span: Span, @@ -1014,25 +1056,25 @@ pub(crate) struct ImplicitElidedLifetimeNotAllowedHere { } #[derive(Diagnostic)] -#[diag(resolve_underscore_lifetime_is_reserved, code = E0637)] -#[help] +#[diag("`'_` cannot be used here", code = E0637)] +#[help("use another lifetime specifier")] pub(crate) struct UnderscoreLifetimeIsReserved { #[primary_span] - #[label] + #[label("`'_` is a reserved lifetime name")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_static_lifetime_is_reserved, code = E0262)] +#[diag("invalid lifetime parameter name: `{$lifetime}`", code = E0262)] pub(crate) struct StaticLifetimeIsReserved { #[primary_span] - #[label] + #[label("'static is a reserved lifetime name")] pub(crate) span: Span, pub(crate) lifetime: Ident, } #[derive(Diagnostic)] -#[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)] +#[diag("variable `{$name}` is not bound in all patterns", code = E0408)] pub(crate) struct VariableIsNotBoundInAllPatterns { #[primary_span] pub(crate) multispan: MultiSpan, @@ -1040,7 +1082,7 @@ pub(crate) struct VariableIsNotBoundInAllPatterns { } #[derive(Subdiagnostic, Debug, Clone)] -#[label(resolve_pattern_doesnt_bind_name)] +#[label("pattern doesn't bind `{$name}`")] pub(crate) struct PatternDoesntBindName { #[primary_span] pub(crate) span: Span, @@ -1048,7 +1090,7 @@ pub(crate) struct PatternDoesntBindName { } #[derive(Subdiagnostic, Debug, Clone)] -#[label(resolve_variable_not_in_all_patterns)] +#[label("variable not in all patterns")] pub(crate) struct VariableNotInAllPatterns { #[primary_span] pub(crate) span: Span, @@ -1056,7 +1098,7 @@ pub(crate) struct VariableNotInAllPatterns { #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_variable_is_a_typo, + "you might have meant to use the similarly named previously used binding `{$typo}`", applicability = "maybe-incorrect", style = "verbose" )] @@ -1067,8 +1109,8 @@ pub(crate) struct PatternBindingTypo { } #[derive(Diagnostic)] -#[diag(resolve_name_defined_multiple_time)] -#[note] +#[diag("the name `{$name}` is defined multiple times")] +#[note("`{$name}` must be defined only once in the {$descr} namespace of this {$container}")] pub(crate) struct NameDefinedMultipleTime { #[primary_span] pub(crate) span: Span, @@ -1083,12 +1125,12 @@ pub(crate) struct NameDefinedMultipleTime { #[derive(Subdiagnostic)] pub(crate) enum NameDefinedMultipleTimeLabel { - #[label(resolve_name_defined_multiple_time_reimported)] + #[label("`{$name}` reimported here")] Reimported { #[primary_span] span: Span, }, - #[label(resolve_name_defined_multiple_time_redefined)] + #[label("`{$name}` redefined here")] Redefined { #[primary_span] span: Span, @@ -1097,13 +1139,13 @@ pub(crate) enum NameDefinedMultipleTimeLabel { #[derive(Subdiagnostic)] pub(crate) enum NameDefinedMultipleTimeOldBindingLabel { - #[label(resolve_name_defined_multiple_time_old_binding_import)] + #[label("previous import of the {$old_kind} `{$name}` here")] Import { #[primary_span] span: Span, old_kind: &'static str, }, - #[label(resolve_name_defined_multiple_time_old_binding_definition)] + #[label("previous definition of the {$old_kind} `{$name}` here")] Definition { #[primary_span] span: Span, @@ -1112,42 +1154,42 @@ pub(crate) enum NameDefinedMultipleTimeOldBindingLabel { } #[derive(Diagnostic)] -#[diag(resolve_is_private, code = E0603)] +#[diag("{$ident_descr} `{$ident}` is private", code = E0603)] pub(crate) struct IsPrivate<'a> { #[primary_span] - #[label] + #[label("private {$ident_descr}")] pub(crate) span: Span, pub(crate) ident_descr: &'a str, pub(crate) ident: Ident, } #[derive(Diagnostic)] -#[diag(resolve_generic_arguments_in_macro_path)] +#[diag("generic arguments in macro path")] pub(crate) struct GenericArgumentsInMacroPath { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_attributes_starting_with_rustc_are_reserved)] +#[diag("attributes starting with `rustc` are reserved for use by the `rustc` compiler")] pub(crate) struct AttributesStartingWithRustcAreReserved { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(resolve_cannot_use_through_an_import)] +#[diag("cannot use {$article} {$descr} through an import")] pub(crate) struct CannotUseThroughAnImport { #[primary_span] pub(crate) span: Span, pub(crate) article: &'static str, pub(crate) descr: &'static str, - #[note] + #[note("the {$descr} imported here")] pub(crate) binding_span: Option, } #[derive(Diagnostic)] -#[diag(resolve_name_reserved_in_attribute_namespace)] +#[diag("name `{$ident}` is reserved in attribute namespace")] pub(crate) struct NameReservedInAttributeNamespace { #[primary_span] pub(crate) span: Span, @@ -1155,7 +1197,7 @@ pub(crate) struct NameReservedInAttributeNamespace { } #[derive(Diagnostic)] -#[diag(resolve_cannot_find_builtin_macro_with_name)] +#[diag("cannot find a built-in macro with name `{$ident}`")] pub(crate) struct CannotFindBuiltinMacroWithName { #[primary_span] pub(crate) span: Span, @@ -1163,34 +1205,34 @@ pub(crate) struct CannotFindBuiltinMacroWithName { } #[derive(Diagnostic)] -#[diag(resolve_tool_was_already_registered)] +#[diag("tool `{$tool}` was already registered")] pub(crate) struct ToolWasAlreadyRegistered { #[primary_span] pub(crate) span: Span, pub(crate) tool: Ident, - #[label] + #[label("already registered here")] pub(crate) old_ident_span: Span, } #[derive(Diagnostic)] -#[diag(resolve_tool_only_accepts_identifiers)] +#[diag("`{$tool}` only accepts identifiers")] pub(crate) struct ToolOnlyAcceptsIdentifiers { #[primary_span] - #[label] + #[label("not an identifier")] pub(crate) span: Span, pub(crate) tool: Symbol, } #[derive(Subdiagnostic)] pub(crate) enum DefinedHere { - #[label(resolve_similarly_named_defined_here)] + #[label("similarly named {$candidate_descr} `{$candidate}` defined here")] SimilarlyNamed { #[primary_span] span: Span, candidate_descr: &'static str, candidate: Symbol, }, - #[label(resolve_single_item_defined_here)] + #[label("{$candidate_descr} `{$candidate}` defined here")] SingleItem { #[primary_span] span: Span, @@ -1200,7 +1242,7 @@ pub(crate) enum DefinedHere { } #[derive(Subdiagnostic)] -#[label(resolve_outer_ident_is_not_publicly_reexported)] +#[label("{$outer_ident_descr} `{$outer_ident}` is not publicly re-exported")] pub(crate) struct OuterIdentIsNotPubliclyReexported { #[primary_span] pub(crate) span: Span, @@ -1209,7 +1251,7 @@ pub(crate) struct OuterIdentIsNotPubliclyReexported { } #[derive(Subdiagnostic)] -#[label(resolve_constructor_private_if_any_field_private)] +#[label("a constructor is private if any of the fields is private")] pub(crate) struct ConstructorPrivateIfAnyFieldPrivate { #[primary_span] pub(crate) span: Span, @@ -1217,7 +1259,10 @@ pub(crate) struct ConstructorPrivateIfAnyFieldPrivate { #[derive(Subdiagnostic)] #[multipart_suggestion( - resolve_consider_making_the_field_public, + "{ $number_of_fields -> + [one] consider making the field publicly accessible + *[other] consider making the fields publicly accessible + }", applicability = "maybe-incorrect", style = "verbose" )] @@ -1230,7 +1275,7 @@ pub(crate) struct ConsiderMakingTheFieldPublic { #[derive(Subdiagnostic)] pub(crate) enum ImportIdent { #[suggestion( - resolve_suggestion_import_ident_through_reexport, + "import `{$ident}` through the re-export", code = "{path}", applicability = "machine-applicable", style = "verbose" @@ -1242,7 +1287,7 @@ pub(crate) enum ImportIdent { path: String, }, #[suggestion( - resolve_suggestion_import_ident_directly, + "import `{$ident}` directly", code = "{path}", applicability = "machine-applicable", style = "verbose" @@ -1256,7 +1301,18 @@ pub(crate) enum ImportIdent { } #[derive(Subdiagnostic)] -#[note(resolve_note_and_refers_to_the_item_defined_here)] +#[note( + "{$first -> + [true] {$dots -> + [true] the {$binding_descr} `{$binding_name}` is defined here... + *[false] the {$binding_descr} `{$binding_name}` is defined here + } + *[false] {$dots -> + [true] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here... + *[false] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here + } + }" +)] pub(crate) struct NoteAndRefersToTheItemDefinedHere<'a> { #[primary_span] pub(crate) span: MultiSpan, @@ -1267,7 +1323,7 @@ pub(crate) struct NoteAndRefersToTheItemDefinedHere<'a> { } #[derive(Subdiagnostic)] -#[suggestion(resolve_remove_unnecessary_import, code = "", applicability = "maybe-incorrect")] +#[suggestion("remove unnecessary import", code = "", applicability = "maybe-incorrect")] pub(crate) struct RemoveUnnecessaryImport { #[primary_span] pub(crate) span: Span, @@ -1275,7 +1331,7 @@ pub(crate) struct RemoveUnnecessaryImport { #[derive(Subdiagnostic)] #[suggestion( - resolve_remove_unnecessary_import, + "remove unnecessary import", code = "", applicability = "maybe-incorrect", style = "tool-only" @@ -1286,7 +1342,7 @@ pub(crate) struct ToolOnlyRemoveUnnecessaryImport { } #[derive(Subdiagnostic)] -#[note(resolve_ident_imported_here_but_it_is_desc)] +#[note("`{$imported_ident}` is imported here, but it is {$imported_ident_desc}")] pub(crate) struct IdentImporterHereButItIsDesc<'a> { #[primary_span] pub(crate) span: Span, @@ -1295,7 +1351,7 @@ pub(crate) struct IdentImporterHereButItIsDesc<'a> { } #[derive(Subdiagnostic)] -#[note(resolve_ident_in_scope_but_it_is_desc)] +#[note("`{$imported_ident}` is in scope, but it is {$imported_ident_desc}")] pub(crate) struct IdentInScopeButItIsDesc<'a> { pub(crate) imported_ident: Ident, pub(crate) imported_ident_desc: &'a str, @@ -1319,50 +1375,55 @@ impl Subdiagnostic for FoundItemConfigureOut { let key = "feature".into(); let value = feature.into_diag_arg(&mut None); let msg = diag.dcx.eagerly_translate_to_string( - fluent::resolve_item_was_behind_feature, + inline_fluent!("the item is gated behind the `{$feature}` feature"), [(&key, &value)].into_iter(), ); multispan.push_span_label(span, msg); } ItemWas::CfgOut { span } => { - multispan.push_span_label(span, fluent::resolve_item_was_cfg_out); + multispan.push_span_label(span, inline_fluent!("the item is gated here")); } } - diag.span_note(multispan, fluent::resolve_found_an_item_configured_out); + diag.span_note(multispan, inline_fluent!("found an item that was configured out")); } } #[derive(Diagnostic)] -#[diag(resolve_trait_impl_mismatch)] +#[diag("item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}`")] pub(crate) struct TraitImplMismatch { #[primary_span] - #[label] + #[label("does not match trait")] pub(crate) span: Span, pub(crate) name: Ident, pub(crate) kind: &'static str, pub(crate) trait_path: String, - #[label(resolve_trait_impl_mismatch_label_item)] + #[label("item in trait")] pub(crate) trait_item_span: Span, } #[derive(LintDiagnostic)] -#[diag(resolve_legacy_derive_helpers)] +#[diag("derive helper attribute is used before it is introduced")] pub(crate) struct LegacyDeriveHelpers { - #[label] + #[label("the attribute is introduced here")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(resolve_unused_extern_crate)] +#[diag("unused extern crate")] pub(crate) struct UnusedExternCrate { - #[label] + #[label("unused")] pub span: Span, - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the unused `extern crate`", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub removal_span: Span, } #[derive(LintDiagnostic)] -#[diag(resolve_reexport_private_dependency)] +#[diag("{$kind} `{$name}` from private dependency '{$krate}' is re-exported")] pub(crate) struct ReexportPrivateDependency { pub name: Symbol, pub kind: &'static str, @@ -1370,32 +1431,32 @@ pub(crate) struct ReexportPrivateDependency { } #[derive(LintDiagnostic)] -#[diag(resolve_unused_label)] +#[diag("unused label")] pub(crate) struct UnusedLabel; #[derive(LintDiagnostic)] -#[diag(resolve_unused_macro_use)] +#[diag("unused `#[macro_use]` import")] pub(crate) struct UnusedMacroUse; #[derive(LintDiagnostic)] -#[diag(resolve_macro_use_deprecated)] -#[help] +#[diag("applying the `#[macro_use]` attribute to an `extern crate` item is deprecated")] +#[help("remove it and import macros at use sites with a `use` item instead")] pub(crate) struct MacroUseDeprecated; #[derive(LintDiagnostic)] -#[diag(resolve_macro_is_private)] +#[diag("macro `{$ident}` is private")] pub(crate) struct MacroIsPrivate { pub ident: Ident, } #[derive(LintDiagnostic)] -#[diag(resolve_unused_macro_definition)] +#[diag("unused macro definition: `{$name}`")] pub(crate) struct UnusedMacroDefinition { pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(resolve_macro_rule_never_used)] +#[diag("rule #{$n} of macro `{$name}` is never used")] pub(crate) struct MacroRuleNeverUsed { pub n: usize, pub name: Symbol, @@ -1412,36 +1473,43 @@ impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { } #[derive(LintDiagnostic)] -#[diag(resolve_extern_crate_not_idiomatic)] +#[diag("`extern crate` is not idiomatic in the new edition")] pub(crate) struct ExternCrateNotIdiomatic { - #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")] + #[suggestion( + "convert it to a `use`", + style = "verbose", + code = "{code}", + applicability = "machine-applicable" + )] pub span: Span, pub code: &'static str, } #[derive(LintDiagnostic)] -#[diag(resolve_out_of_scope_macro_calls)] -#[help] +#[diag("cannot find macro `{$path}` in the current scope when looking from {$location}")] +#[help("import `macro_rules` with `use` to make it callable above its definition")] pub(crate) struct OutOfScopeMacroCalls { - #[label] + #[label("not found from {$location}")] pub span: Span, pub path: String, pub location: String, } #[derive(LintDiagnostic)] -#[diag(resolve_redundant_import_visibility)] +#[diag( + "glob import doesn't reexport anything with visibility `{$import_vis}` because no imported item is public enough" +)] pub(crate) struct RedundantImportVisibility { - #[note] + #[note("the most public imported item is `{$max_vis}`")] pub span: Span, - #[help] + #[help("reduce the glob import's visibility or increase visibility of imported items")] pub help: (), pub import_vis: String, pub max_vis: String, } #[derive(LintDiagnostic)] -#[diag(resolve_unknown_diagnostic_attribute)] +#[diag("unknown diagnostic attribute")] pub(crate) struct UnknownDiagnosticAttribute { #[subdiagnostic] pub typo: Option, @@ -1449,7 +1517,7 @@ pub(crate) struct UnknownDiagnosticAttribute { #[derive(Subdiagnostic)] #[suggestion( - resolve_unknown_diagnostic_attribute_typo_sugg, + "an attribute with a similar name exists", style = "verbose", code = "{typo_name}", applicability = "machine-applicable" diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 659b74b74df7..36ec173cc571 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -98,8 +98,6 @@ pub use macros::registered_tools_ast; use crate::ref_mut::{CmCell, CmRefCell}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - #[derive(Copy, Clone, PartialEq, Debug)] enum Determinacy { Determined, From 534b6c60e0786cb422b97c7dd7119da82505d24f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 4 Feb 2026 17:06:46 +0100 Subject: [PATCH 55/81] Convert to inline diagnostics in `rustc_metadata` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_metadata/Cargo.toml | 1 - compiler/rustc_metadata/messages.ftl | 240 ---------------------- compiler/rustc_metadata/src/errors.rs | 281 +++++++++++++++++--------- compiler/rustc_metadata/src/lib.rs | 2 - 6 files changed, 182 insertions(+), 344 deletions(-) delete mode 100644 compiler/rustc_metadata/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612..b53fc5e161ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4241,7 +4241,6 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_pretty", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc61..46d975dcc181 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -125,7 +125,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, - rustc_metadata::DEFAULT_LOCALE_RESOURCE, rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 1b40d9f684ef..3a70ee130c27 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -15,7 +15,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl deleted file mode 100644 index fac7b6c21f60..000000000000 --- a/compiler/rustc_metadata/messages.ftl +++ /dev/null @@ -1,240 +0,0 @@ -metadata_async_drop_types_in_dependency = - found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}` - .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used - -metadata_bad_panic_strategy = - the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}` - -metadata_binary_output_to_tty = - option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty - -metadata_cannot_find_crate = - can't find crate for `{$crate_name}`{$add_info} - -metadata_cant_find_crate = - can't find crate - -metadata_compiler_missing_profiler = - the compiler may have been built without the profiler runtime - -metadata_conflicting_alloc_error_handler = - the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name} - -metadata_conflicting_global_alloc = - the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name} - -metadata_consider_adding_std = - consider adding the standard library to the sysroot with `x build library --target {$locator_triple}` - -metadata_consider_building_std = - consider building the standard library from source with `cargo build -Zbuild-std` - -metadata_consider_downloading_target = - consider downloading the target with `rustup target add {$locator_triple}` - -metadata_crate_dep_multiple = - cannot satisfy dependencies so `{$crate_name}` only shows up once - .help = having upstream crates all available in one format will likely make this go away - -metadata_crate_dep_not_static = - `{$crate_name}` was unavailable as a static crate, preventing fully static linking - -metadata_crate_dep_rustc_driver = - `feature(rustc_private)` is needed to link to the compiler's `rustc_driver` library - -metadata_crate_location_unknown_type = - extern location for {$crate_name} is of an unknown type: {$path} - -metadata_crate_not_compiler_builtins = - the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]` - -metadata_crate_not_panic_runtime = - the crate `{$crate_name}` is not a panic runtime - -metadata_dl_error = - {$path}{$err} - -metadata_empty_renaming_target = - an empty renaming target was specified for library `{$lib_name}` - -metadata_extern_location_not_exist = - extern location for {$crate_name} does not exist: {$location} - -metadata_extern_location_not_file = - extern location for {$crate_name} is not a file: {$location} - -metadata_fail_create_file_encoder = - failed to create file encoder: {$err} - -metadata_fail_write_file = - failed to write to `{$path}`: {$err} - -metadata_failed_copy_to_stdout = - failed to copy {$filename} to stdout: {$err} - -metadata_failed_create_encoded_metadata = - failed to create encoded metadata from file: {$err} - -metadata_failed_create_file = - failed to create the file {$filename}: {$err} - -metadata_failed_create_tempdir = - couldn't create a temp dir: {$err} - -metadata_failed_write_error = - failed to write {$filename}: {$err} - -metadata_found_crate_versions = - the following crate versions were found:{$found_crates} - -metadata_found_staticlib = - found staticlib `{$crate_name}` instead of rlib or dylib{$add_info} - .help = please recompile that crate using --crate-type lib - -metadata_full_metadata_not_found = - only metadata stub found for `{$flavor}` dependency `{$crate_name}` - please provide path to the corresponding .rmeta file with full metadata - -metadata_global_alloc_required = - no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait - -metadata_incompatible_panic_in_drop_strategy = - the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}` - -metadata_incompatible_rustc = - found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info} - .help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first) - -metadata_incompatible_target_modifiers = - mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}` - .note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}` - .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely -metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error -metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$extern_value}` in this crate or `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}` - -metadata_incompatible_target_modifiers_help_fix_l_missed = set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}` - -metadata_incompatible_target_modifiers_help_fix_r_missed = unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}` - -metadata_incompatible_target_modifiers_l_missed = - mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}` - .note = unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}` - .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely -metadata_incompatible_target_modifiers_r_missed = - mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}` - .note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}` - .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - -metadata_incompatible_with_immediate_abort = - the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort` - -metadata_incompatible_with_immediate_abort_core = - the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort` - .help = consider building the standard library from source with `cargo build -Zbuild-std` - -metadata_install_missing_components = - maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview` - -metadata_invalid_meta_files = - found invalid metadata files for crate `{$crate_name}`{$add_info} - -metadata_lib_filename_form = - file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix} - -metadata_lib_framework_apple = - library kind `framework` is only supported on Apple targets - -metadata_lib_required = - crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form - -metadata_link_ordinal_raw_dylib = - `#[link_ordinal]` is only supported if link kind is `raw-dylib` - -metadata_missing_native_library = - could not find native static library `{$libname}`, perhaps an -L flag is missing? - -metadata_multiple_candidates = - multiple candidates for `{$flavor}` dependency `{$crate_name}` found - -metadata_multiple_renamings = - multiple renamings were specified for library `{$lib_name}` - -metadata_newer_crate_version = - found possibly newer version of crate `{$crate_name}`{$add_info} - .note = perhaps that crate needs to be recompiled? - -metadata_no_crate_with_triple = - couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info} - -metadata_no_link_mod_override = - overriding linking modifiers from command line is not supported - -metadata_no_multiple_alloc_error_handler = - cannot define multiple allocation error handlers - .label = cannot define a new allocation error handler - -metadata_no_multiple_global_alloc = - cannot define multiple global allocators - .label = cannot define a new global allocator - -metadata_no_panic_strategy = - the crate `{$crate_name}` does not have the panic strategy `{$strategy}` - -metadata_no_transitive_needs_dep = - the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}` - -metadata_non_ascii_name = - cannot load a crate with a non-ascii name `{$crate_name}` - -metadata_not_profiler_runtime = - the crate `{$crate_name}` is not a profiler runtime - -metadata_only_provide_library_name = only provide the library name `{$suggested_name}`, not the full filename - -metadata_prev_alloc_error_handler = - previous allocation error handler defined here - -metadata_prev_global_alloc = - previous global allocator defined here - -metadata_raw_dylib_malformed = - link name must be well-formed if link kind is `raw-dylib` -metadata_raw_dylib_unsupported_abi = - ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture - -metadata_renaming_no_link = - renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library - -metadata_required_panic_strategy = - the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}` - -metadata_rlib_required = - crate `{$crate_name}` required to be available in rlib format, but was not found in this form - -metadata_rustc_lib_required = - crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form - .note = only .rmeta files are distributed for `rustc_private` crates other than `rustc_driver` - .help = try adding `extern crate rustc_driver;` at the top level of this crate - -metadata_stable_crate_id_collision = - found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values - -metadata_std_required = - `std` is required by `{$current_crate}` because it does not declare `#![no_std]` - -metadata_symbol_conflicts_current = - the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two - -metadata_target_no_std_support = - the `{$locator_triple}` target may not support the standard library - -metadata_target_not_installed = - the `{$locator_triple}` target may not be installed - -metadata_two_panic_runtimes = - cannot link together two panic runtimes: {$prev_name} and {$cur_name} - -metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}` - -metadata_wasm_c_abi = - older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 8eb4fad078fe..da26f855b6c7 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -2,38 +2,43 @@ use std::io::Error; use std::path::{Path, PathBuf}; use rustc_errors::codes::*; -use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, inline_fluent}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol, sym}; use rustc_target::spec::{PanicStrategy, TargetTuple}; -use crate::fluent_generated as fluent; use crate::locator::CrateFlavor; #[derive(Diagnostic)] -#[diag(metadata_rlib_required)] +#[diag( + "crate `{$crate_name}` required to be available in rlib format, but was not found in this form" +)] pub struct RlibRequired { pub crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_lib_required)] +#[diag( + "crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form" +)] pub struct LibRequired<'a> { pub crate_name: Symbol, pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_rustc_lib_required)] -#[help] +#[diag( + "crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form" +)] +#[help("try adding `extern crate rustc_driver;` at the top level of this crate")] pub struct RustcLibRequired<'a> { pub crate_name: Symbol, pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_crate_dep_multiple)] -#[help] +#[diag("cannot satisfy dependencies so `{$crate_name}` only shows up once")] +#[help("having upstream crates all available in one format will likely make this go away")] pub struct CrateDepMultiple { pub crate_name: Symbol, #[subdiagnostic] @@ -43,32 +48,36 @@ pub struct CrateDepMultiple { } #[derive(Subdiagnostic)] -#[note(metadata_crate_dep_not_static)] +#[note("`{$crate_name}` was unavailable as a static crate, preventing fully static linking")] pub struct NonStaticCrateDep { /// It's different from `crate_name` in main Diagnostic. pub crate_name_: Symbol, } #[derive(Subdiagnostic)] -#[help(metadata_crate_dep_rustc_driver)] +#[help("`feature(rustc_private)` is needed to link to the compiler's `rustc_driver` library")] pub struct RustcDriverHelp; #[derive(Diagnostic)] -#[diag(metadata_two_panic_runtimes)] +#[diag("cannot link together two panic runtimes: {$prev_name} and {$cur_name}")] pub struct TwoPanicRuntimes { pub prev_name: Symbol, pub cur_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_bad_panic_strategy)] +#[diag( + "the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`" +)] pub struct BadPanicStrategy { pub runtime: Symbol, pub strategy: PanicStrategy, } #[derive(Diagnostic)] -#[diag(metadata_required_panic_strategy)] +#[diag( + "the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`" +)] pub struct RequiredPanicStrategy { pub crate_name: Symbol, pub found_strategy: PanicStrategy, @@ -76,17 +85,23 @@ pub struct RequiredPanicStrategy { } #[derive(Diagnostic)] -#[diag(metadata_incompatible_with_immediate_abort)] +#[diag( + "the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`" +)] pub struct IncompatibleWithImmediateAbort { pub crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_incompatible_with_immediate_abort_core)] +#[diag( + "the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`" +)] pub struct IncompatibleWithImmediateAbortCore; #[derive(Diagnostic)] -#[diag(metadata_incompatible_panic_in_drop_strategy)] +#[diag( + "the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`" +)] pub struct IncompatiblePanicInDropStrategy { pub crate_name: Symbol, pub found_strategy: PanicStrategy, @@ -94,126 +109,138 @@ pub struct IncompatiblePanicInDropStrategy { } #[derive(Diagnostic)] -#[diag(metadata_link_ordinal_raw_dylib)] +#[diag("`#[link_ordinal]` is only supported if link kind is `raw-dylib`")] pub struct LinkOrdinalRawDylib { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(metadata_lib_framework_apple)] +#[diag("library kind `framework` is only supported on Apple targets")] pub struct LibFrameworkApple; #[derive(Diagnostic)] -#[diag(metadata_empty_renaming_target)] +#[diag("an empty renaming target was specified for library `{$lib_name}`")] pub struct EmptyRenamingTarget<'a> { pub lib_name: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_renaming_no_link)] +#[diag( + "renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library" +)] pub struct RenamingNoLink<'a> { pub lib_name: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_multiple_renamings)] +#[diag("multiple renamings were specified for library `{$lib_name}`")] pub struct MultipleRenamings<'a> { pub lib_name: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_no_link_mod_override)] +#[diag("overriding linking modifiers from command line is not supported")] pub struct NoLinkModOverride { #[primary_span] pub span: Option, } #[derive(Diagnostic)] -#[diag(metadata_raw_dylib_unsupported_abi)] +#[diag("ABI not supported by `#[link(kind = \"raw-dylib\")]` on this architecture")] pub struct RawDylibUnsupportedAbi { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(metadata_fail_create_file_encoder)] +#[diag("failed to create file encoder: {$err}")] pub struct FailCreateFileEncoder { pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_fail_write_file)] +#[diag("failed to write to `{$path}`: {$err}")] pub struct FailWriteFile<'a> { pub path: &'a Path, pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_crate_not_panic_runtime)] +#[diag("the crate `{$crate_name}` is not a panic runtime")] pub struct CrateNotPanicRuntime { pub crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_crate_not_compiler_builtins)] +#[diag( + "the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]`" +)] pub struct CrateNotCompilerBuiltins { pub crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_no_panic_strategy)] +#[diag("the crate `{$crate_name}` does not have the panic strategy `{$strategy}`")] pub struct NoPanicStrategy { pub crate_name: Symbol, pub strategy: PanicStrategy, } #[derive(Diagnostic)] -#[diag(metadata_not_profiler_runtime)] +#[diag("the crate `{$crate_name}` is not a profiler runtime")] pub struct NotProfilerRuntime { pub crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_no_multiple_global_alloc)] +#[diag("cannot define multiple global allocators")] pub struct NoMultipleGlobalAlloc { #[primary_span] - #[label] + #[label("cannot define a new global allocator")] pub span2: Span, - #[label(metadata_prev_global_alloc)] + #[label("previous global allocator defined here")] pub span1: Span, } #[derive(Diagnostic)] -#[diag(metadata_no_multiple_alloc_error_handler)] +#[diag("cannot define multiple allocation error handlers")] pub struct NoMultipleAllocErrorHandler { #[primary_span] - #[label] + #[label("cannot define a new allocation error handler")] pub span2: Span, - #[label(metadata_prev_alloc_error_handler)] + #[label("previous allocation error handler defined here")] pub span1: Span, } #[derive(Diagnostic)] -#[diag(metadata_conflicting_global_alloc)] +#[diag( + "the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}" +)] pub struct ConflictingGlobalAlloc { pub crate_name: Symbol, pub other_crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_conflicting_alloc_error_handler)] +#[diag( + "the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name}" +)] pub struct ConflictingAllocErrorHandler { pub crate_name: Symbol, pub other_crate_name: Symbol, } #[derive(Diagnostic)] -#[diag(metadata_global_alloc_required)] +#[diag( + "no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait" +)] pub struct GlobalAllocRequired; #[derive(Diagnostic)] -#[diag(metadata_no_transitive_needs_dep)] +#[diag( + "the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`" +)] pub struct NoTransitiveNeedsDep<'a> { pub crate_name: Symbol, pub needs_crate_name: &'a str, @@ -221,25 +248,27 @@ pub struct NoTransitiveNeedsDep<'a> { } #[derive(Diagnostic)] -#[diag(metadata_failed_write_error)] +#[diag("failed to write {$filename}: {$err}")] pub struct FailedWriteError { pub filename: PathBuf, pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_failed_copy_to_stdout)] +#[diag("failed to copy {$filename} to stdout: {$err}")] pub struct FailedCopyToStdout { pub filename: PathBuf, pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_binary_output_to_tty)] +#[diag( + "option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty" +)] pub struct BinaryOutputToTty; #[derive(Diagnostic)] -#[diag(metadata_missing_native_library)] +#[diag("could not find native static library `{$libname}`, perhaps an -L flag is missing?")] pub struct MissingNativeLibrary<'a> { libname: &'a str, #[subdiagnostic] @@ -273,32 +302,32 @@ impl<'a> MissingNativeLibrary<'a> { } #[derive(Subdiagnostic)] -#[help(metadata_only_provide_library_name)] +#[help("only provide the library name `{$suggested_name}`, not the full filename")] pub struct SuggestLibraryName<'a> { suggested_name: &'a str, } #[derive(Diagnostic)] -#[diag(metadata_failed_create_tempdir)] +#[diag("couldn't create a temp dir: {$err}")] pub struct FailedCreateTempdir { pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_failed_create_file)] +#[diag("failed to create the file {$filename}: {$err}")] pub struct FailedCreateFile<'a> { pub filename: &'a Path, pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_failed_create_encoded_metadata)] +#[diag("failed to create encoded metadata from file: {$err}")] pub struct FailedCreateEncodedMetadata { pub err: Error, } #[derive(Diagnostic)] -#[diag(metadata_non_ascii_name)] +#[diag("cannot load a crate with a non-ascii name `{$crate_name}`")] pub struct NonAsciiName { #[primary_span] pub span: Span, @@ -306,7 +335,7 @@ pub struct NonAsciiName { } #[derive(Diagnostic)] -#[diag(metadata_extern_location_not_exist)] +#[diag("extern location for {$crate_name} does not exist: {$location}")] pub struct ExternLocationNotExist<'a> { #[primary_span] pub span: Span, @@ -315,7 +344,7 @@ pub struct ExternLocationNotExist<'a> { } #[derive(Diagnostic)] -#[diag(metadata_extern_location_not_file)] +#[diag("extern location for {$crate_name} is not a file: {$location}")] pub struct ExternLocationNotFile<'a> { #[primary_span] pub span: Span, @@ -332,7 +361,11 @@ pub(crate) struct MultipleCandidates { impl Diagnostic<'_, G> for MultipleCandidates { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::metadata_multiple_candidates); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("multiple candidates for `{$flavor}` dependency `{$crate_name}` found"), + ); diag.arg("crate_name", self.crate_name); diag.arg("flavor", self.flavor); diag.code(E0464); @@ -345,7 +378,9 @@ impl Diagnostic<'_, G> for MultipleCandidates { } #[derive(Diagnostic)] -#[diag(metadata_full_metadata_not_found)] +#[diag( + "only metadata stub found for `{$flavor}` dependency `{$crate_name}` please provide path to the corresponding .rmeta file with full metadata" +)] pub(crate) struct FullMetadataNotFound { #[primary_span] pub span: Span, @@ -354,7 +389,7 @@ pub(crate) struct FullMetadataNotFound { } #[derive(Diagnostic)] -#[diag(metadata_symbol_conflicts_current, code = E0519)] +#[diag("the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two", code = E0519)] pub struct SymbolConflictsCurrent { #[primary_span] pub span: Span, @@ -362,7 +397,7 @@ pub struct SymbolConflictsCurrent { } #[derive(Diagnostic)] -#[diag(metadata_stable_crate_id_collision)] +#[diag("found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values")] pub struct StableCrateIdCollision { #[primary_span] pub span: Span, @@ -371,7 +406,7 @@ pub struct StableCrateIdCollision { } #[derive(Diagnostic)] -#[diag(metadata_dl_error)] +#[diag("{$path}{$err}")] pub struct DlError { #[primary_span] pub span: Span, @@ -380,9 +415,9 @@ pub struct DlError { } #[derive(Diagnostic)] -#[diag(metadata_newer_crate_version, code = E0460)] -#[note] -#[note(metadata_found_crate_versions)] +#[diag("found possibly newer version of crate `{$crate_name}`{$add_info}", code = E0460)] +#[note("perhaps that crate needs to be recompiled?")] +#[note("the following crate versions were found:{$found_crates}")] pub struct NewerCrateVersion { #[primary_span] pub span: Span, @@ -392,8 +427,8 @@ pub struct NewerCrateVersion { } #[derive(Diagnostic)] -#[diag(metadata_no_crate_with_triple, code = E0461)] -#[note(metadata_found_crate_versions)] +#[diag("couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}", code = E0461)] +#[note("the following crate versions were found:{$found_crates}")] pub struct NoCrateWithTriple<'a> { #[primary_span] pub span: Span, @@ -404,9 +439,9 @@ pub struct NoCrateWithTriple<'a> { } #[derive(Diagnostic)] -#[diag(metadata_found_staticlib, code = E0462)] -#[note(metadata_found_crate_versions)] -#[help] +#[diag("found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}", code = E0462)] +#[note("the following crate versions were found:{$found_crates}")] +#[help("please recompile that crate using --crate-type lib")] pub struct FoundStaticlib { #[primary_span] pub span: Span, @@ -416,9 +451,11 @@ pub struct FoundStaticlib { } #[derive(Diagnostic)] -#[diag(metadata_incompatible_rustc, code = E0514)] -#[note(metadata_found_crate_versions)] -#[help] +#[diag("found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}", code = E0514)] +#[note("the following crate versions were found:{$found_crates}")] +#[help( + "please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)" +)] pub struct IncompatibleRustc { #[primary_span] pub span: Span, @@ -438,7 +475,11 @@ pub struct InvalidMetadataFiles { impl Diagnostic<'_, G> for InvalidMetadataFiles { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::metadata_invalid_meta_files); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("found invalid metadata files for crate `{$crate_name}`{$add_info}"), + ); diag.arg("crate_name", self.crate_name); diag.arg("add_info", self.add_info); diag.code(E0786); @@ -466,7 +507,11 @@ pub struct CannotFindCrate { impl Diagnostic<'_, G> for CannotFindCrate { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::metadata_cannot_find_crate); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("can't find crate for `{$crate_name}`{$add_info}"), + ); diag.arg("crate_name", self.crate_name); diag.arg("current_crate", self.current_crate); diag.arg("add_info", self.add_info); @@ -475,9 +520,11 @@ impl Diagnostic<'_, G> for CannotFindCrate { diag.span(self.span); if self.crate_name == sym::std || self.crate_name == sym::core { if self.missing_core { - diag.note(fluent::metadata_target_not_installed); + diag.note(inline_fluent!("the `{$locator_triple}` target may not be installed")); } else { - diag.note(fluent::metadata_target_no_std_support); + diag.note(inline_fluent!( + "the `{$locator_triple}` target may not support the standard library" + )); } let has_precompiled_std = !self.is_tier_3; @@ -485,12 +532,14 @@ impl Diagnostic<'_, G> for CannotFindCrate { if self.missing_core { if env!("CFG_RELEASE_CHANNEL") == "dev" && !self.is_ui_testing { // Note: Emits the nicer suggestion only for the dev channel. - diag.help(fluent::metadata_consider_adding_std); + diag.help(inline_fluent!("consider adding the standard library to the sysroot with `x build library --target {$locator_triple}`")); } else if has_precompiled_std { // NOTE: this suggests using rustup, even though the user may not have it installed. // That's because they could choose to install it; or this may give them a hint which // target they need to install from their distro. - diag.help(fluent::metadata_consider_downloading_target); + diag.help(inline_fluent!( + "consider downloading the target with `rustup target add {$locator_triple}`" + )); } } @@ -499,25 +548,27 @@ impl Diagnostic<'_, G> for CannotFindCrate { // If it's not a dummy, that means someone added `extern crate std` explicitly and // `#![no_std]` won't help. if !self.missing_core && self.span.is_dummy() { - diag.note(fluent::metadata_std_required); + diag.note(inline_fluent!("`std` is required by `{$current_crate}` because it does not declare `#![no_std]`")); } // Recommend -Zbuild-std even on stable builds for Tier 3 targets because // it's the recommended way to use the target, the user should switch to nightly. if self.is_nightly_build || !has_precompiled_std { - diag.help(fluent::metadata_consider_building_std); + diag.help(inline_fluent!("consider building the standard library from source with `cargo build -Zbuild-std`")); } } else if self.crate_name == self.profiler_runtime { - diag.note(fluent::metadata_compiler_missing_profiler); + diag.note(inline_fluent!( + "the compiler may have been built without the profiler runtime" + )); } else if self.crate_name.as_str().starts_with("rustc_") { - diag.help(fluent::metadata_install_missing_components); + diag.help(inline_fluent!("maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`")); } - diag.span_label(self.span, fluent::metadata_cant_find_crate); + diag.span_label(self.span, inline_fluent!("can't find crate")); diag } } #[derive(Diagnostic)] -#[diag(metadata_crate_location_unknown_type)] +#[diag("extern location for {$crate_name} is of an unknown type: {$path}")] pub struct CrateLocationUnknownType<'a> { #[primary_span] pub span: Span, @@ -526,7 +577,7 @@ pub struct CrateLocationUnknownType<'a> { } #[derive(Diagnostic)] -#[diag(metadata_lib_filename_form)] +#[diag("file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix}")] pub struct LibFilenameForm<'a> { #[primary_span] pub span: Span, @@ -535,18 +586,28 @@ pub struct LibFilenameForm<'a> { } #[derive(Diagnostic)] -#[diag(metadata_wasm_c_abi)] +#[diag( + "older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88" +)] pub(crate) struct WasmCAbi { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(metadata_incompatible_target_modifiers)] -#[help] -#[note] -#[help(metadata_incompatible_target_modifiers_help_fix)] -#[help(metadata_incompatible_target_modifiers_help_allow)] +#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")] +#[help( + "the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely" +)] +#[note( + "`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`" +)] +#[help( + "set `{$flag_name_prefixed}={$extern_value}` in this crate or `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`" +)] +#[help( + "if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error" +)] pub struct IncompatibleTargetModifiers { #[primary_span] pub span: Span, @@ -559,11 +620,19 @@ pub struct IncompatibleTargetModifiers { } #[derive(Diagnostic)] -#[diag(metadata_incompatible_target_modifiers_l_missed)] -#[help] -#[note] -#[help(metadata_incompatible_target_modifiers_help_fix_l_missed)] -#[help(metadata_incompatible_target_modifiers_help_allow)] +#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")] +#[help( + "the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely" +)] +#[note( + "unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`" +)] +#[help( + "set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`" +)] +#[help( + "if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error" +)] pub struct IncompatibleTargetModifiersLMissed { #[primary_span] pub span: Span, @@ -575,11 +644,19 @@ pub struct IncompatibleTargetModifiersLMissed { } #[derive(Diagnostic)] -#[diag(metadata_incompatible_target_modifiers_r_missed)] -#[help] -#[note] -#[help(metadata_incompatible_target_modifiers_help_fix_r_missed)] -#[help(metadata_incompatible_target_modifiers_help_allow)] +#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")] +#[help( + "the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely" +)] +#[note( + "`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`" +)] +#[help( + "unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`" +)] +#[help( + "if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error" +)] pub struct IncompatibleTargetModifiersRMissed { #[primary_span] pub span: Span, @@ -591,7 +668,9 @@ pub struct IncompatibleTargetModifiersRMissed { } #[derive(Diagnostic)] -#[diag(metadata_unknown_target_modifier_unsafe_allowed)] +#[diag( + "unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`" +)] pub struct UnknownTargetModifierUnsafeAllowed { #[primary_span] pub span: Span, @@ -599,8 +678,12 @@ pub struct UnknownTargetModifierUnsafeAllowed { } #[derive(Diagnostic)] -#[diag(metadata_async_drop_types_in_dependency)] -#[help] +#[diag( + "found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`" +)] +#[help( + "if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used" +)] pub struct AsyncDropTypesInDependency { #[primary_span] pub span: Span, @@ -609,7 +692,7 @@ pub struct AsyncDropTypesInDependency { } #[derive(Diagnostic)] -#[diag(metadata_raw_dylib_malformed)] +#[diag("link name must be well-formed if link kind is `raw-dylib`")] pub struct RawDylibMalformed { #[primary_span] pub span: Span, diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index f3b738f93d2d..22c8a0c4cd7e 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -34,5 +34,3 @@ pub use native_libs::{ try_find_native_static_library, walk_native_lib_search_dirs, }; pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const}; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } From 23e5b2499f2938cc9cab5271a5f75cc641b210bf Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 4 Feb 2026 19:20:07 +0100 Subject: [PATCH 56/81] Adopt matches-logical-or-141497.rs to LLVM HEAD After http://github.com/llvm/llvm-project/pull/178977, the and + icmp are folded to trunc. --- tests/codegen-llvm/issues/matches-logical-or-141497.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/codegen-llvm/issues/matches-logical-or-141497.rs b/tests/codegen-llvm/issues/matches-logical-or-141497.rs index 348f62096a5f..59869fd70012 100644 --- a/tests/codegen-llvm/issues/matches-logical-or-141497.rs +++ b/tests/codegen-llvm/issues/matches-logical-or-141497.rs @@ -2,7 +2,7 @@ // `f == FrameType::Inter || f == FrameType::Switch`. //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 21 +//@ min-llvm-version: 23 #![crate_type = "lib"] @@ -18,8 +18,7 @@ pub enum FrameType { #[no_mangle] pub fn is_inter_or_switch(f: FrameType) -> bool { // CHECK-NEXT: start: - // CHECK-NEXT: and i8 - // CHECK-NEXT: icmp + // CHECK-NEXT: trunc i8 %{{.*}} to i1 // CHECK-NEXT: ret matches!(f, FrameType::Inter | FrameType::Switch) } From 01c0c147c5ba624cc9eb7dcc51577bef16f6a630 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 5 Jan 2026 19:31:26 +0100 Subject: [PATCH 57/81] library/std: Rename `ON_BROKEN_PIPE_FLAG_USED` to `ON_BROKEN_PIPE_USED` This commmit is a pure rename and does not change any functionality. The `FLAG_` part of `ON_BROKEN_PIPE_FLAG_USED` comes from that the compiler flag `-Zon-broken-pipe=...` is used to enable the feature. Remove the `FLAG_` part so the name works both for the flag `-Zon-broken-pipe=...` and for the upcoming Externally Implementable Item `#[std::io::on_broken_pipe]`. This makes the diff of that PR smaller. The local variable name `sigpipe_attr_specified` comes from way back when the feature was controlled with an `fn main()` attribute called `#[unix_sigpipe = "..."]`. Rename that too. --- library/std/src/sys/pal/unix/mod.rs | 12 ++++++------ library/std/src/sys/process/unix/unix.rs | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 6127bb98f80e..0fbf37fda7fb 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -169,15 +169,15 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { pub const SIG_DFL: u8 = 3; } - let (sigpipe_attr_specified, handler) = match sigpipe { + let (on_broken_pipe_used, handler) = match sigpipe { sigpipe::DEFAULT => (false, Some(libc::SIG_IGN)), sigpipe::INHERIT => (true, None), sigpipe::SIG_IGN => (true, Some(libc::SIG_IGN)), sigpipe::SIG_DFL => (true, Some(libc::SIG_DFL)), _ => unreachable!(), }; - if sigpipe_attr_specified { - ON_BROKEN_PIPE_FLAG_USED.store(true, crate::sync::atomic::Ordering::Relaxed); + if on_broken_pipe_used { + ON_BROKEN_PIPE_USED.store(true, crate::sync::atomic::Ordering::Relaxed); } if let Some(handler) = handler { rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR); @@ -199,7 +199,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "vxworks", target_os = "vita", )))] -static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::Atomic = +static ON_BROKEN_PIPE_USED: crate::sync::atomic::Atomic = crate::sync::atomic::AtomicBool::new(false); #[cfg(not(any( @@ -211,8 +211,8 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::Atomic = target_os = "vita", target_os = "nuttx", )))] -pub(crate) fn on_broken_pipe_flag_used() -> bool { - ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed) +pub(crate) fn on_broken_pipe_used() -> bool { + ON_BROKEN_PIPE_USED.load(crate::sync::atomic::Ordering::Relaxed) } // SAFETY: must be called only once during runtime cleanup. diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 62d6e0581e6c..82ff94fb1e03 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -356,7 +356,7 @@ impl Command { // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility. // // -Zon-broken-pipe is an opportunity to change the default here. - if !crate::sys::pal::on_broken_pipe_flag_used() { + if !crate::sys::pal::on_broken_pipe_used() { #[cfg(target_os = "android")] // see issue #88585 { let mut action: libc::sigaction = mem::zeroed(); @@ -455,7 +455,7 @@ impl Command { use core::sync::atomic::{Atomic, AtomicU8, Ordering}; use crate::mem::MaybeUninit; - use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used}; + use crate::sys::{self, cvt_nz, on_broken_pipe_used}; if self.get_gid().is_some() || self.get_uid().is_some() @@ -731,7 +731,7 @@ impl Command { // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility. // // -Zon-broken-pipe is an opportunity to change the default here. - if !on_broken_pipe_flag_used() { + if !on_broken_pipe_used() { let mut default_set = MaybeUninit::::uninit(); cvt(sigemptyset(default_set.as_mut_ptr()))?; cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?; From 44a14c1f304089a3ca6bfa4dc82734bca8985b6b Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 21:36:48 +0100 Subject: [PATCH 58/81] Convert to inline diagnostics in `rustc_hir_typeck` --- Cargo.lock | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_hir_typeck/Cargo.toml | 1 - compiler/rustc_hir_typeck/messages.ftl | 315 ----------- compiler/rustc_hir_typeck/src/callee.rs | 14 +- compiler/rustc_hir_typeck/src/errors.rs | 522 ++++++++++++------ .../src/fn_ctxt/suggestions.rs | 6 +- compiler/rustc_hir_typeck/src/lib.rs | 2 - 9 files changed, 357 insertions(+), 507 deletions(-) delete mode 100644 compiler/rustc_hir_typeck/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 85d3fc1aa7bf..85fb0de46879 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3787,7 +3787,6 @@ dependencies = [ "rustc_feature", "rustc_hir_analysis", "rustc_hir_pretty", - "rustc_hir_typeck", "rustc_index", "rustc_interface", "rustc_lexer", @@ -4017,7 +4016,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index cae2e3b066ee..dec91490c96d 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -22,7 +22,6 @@ rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } -rustc_hir_typeck = { path = "../rustc_hir_typeck" } rustc_index = { path = "../rustc_index" } rustc_interface = { path = "../rustc_interface" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3b9ca5ff7288..b2e973c76868 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -123,7 +123,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_errors::DEFAULT_LOCALE_RESOURCE, rustc_expand::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, rustc_metadata::DEFAULT_LOCALE_RESOURCE, rustc_middle::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 246134665174..43db09b0eab8 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -10,7 +10,6 @@ rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl deleted file mode 100644 index 0c4b1f891ead..000000000000 --- a/compiler/rustc_hir_typeck/messages.ftl +++ /dev/null @@ -1,315 +0,0 @@ -hir_typeck_abi_cannot_be_called = - functions with the {$abi} ABI cannot be called - .note = an `extern {$abi}` function can only be called using inline assembly - -hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function - -hir_typeck_add_return_type_add = try adding a return type - -hir_typeck_add_return_type_missing_here = a return type might be missing here - -hir_typeck_address_of_temporary_taken = cannot take address of a temporary - .label = temporary value - -hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where - .note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new - -hir_typeck_as_deref_suggestion = consider using `as_deref` here -hir_typeck_base_expression_double_dot = base expression required after `..` -hir_typeck_base_expression_double_dot_add_expr = add a base expression here -hir_typeck_base_expression_double_dot_enable_default_field_values = - add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields -hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present - -hir_typeck_break_inside_closure = - `{$name}` inside of a closure - .label = cannot `{$name}` inside of a closure - .closure_label = enclosing closure - -hir_typeck_break_inside_coroutine = - `{$name}` inside `{$kind}` {$source} - .label = cannot `{$name}` inside `{$kind}` {$source} - .coroutine_label = enclosing `{$kind}` {$source} - -hir_typeck_break_non_loop = - `break` with value from a `{$kind}` loop - .label = can only break with a value inside `loop` or breakable block - .label2 = you can't `break` with a value in a `{$kind}` loop - .suggestion = use `break` on its own without a value inside this `{$kind}` loop - .break_expr_suggestion = alternatively, you might have meant to use the available loop label - - -hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> - [NONE] {""} - [implement] , perhaps you need to implement it - *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it -} - -hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool` - .suggestion = compare with zero instead - .help = compare with zero instead - .label = unsupported cast - -hir_typeck_cant_dereference = type `{$ty}` cannot be dereferenced -hir_typeck_cant_dereference_label = can't be dereferenced - -hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop` - -hir_typeck_cast_thin_pointer_to_wide_pointer = cannot cast thin pointer `{$expr_ty}` to wide pointer `{$cast_ty}` - .teach_help = Thin pointers are "simple" pointers: they are purely a reference to a - memory address. - - Wide pointers are pointers referencing "Dynamically Sized Types" (also - called DST). DST don't have a statically known size, therefore they can - only exist behind some kind of pointers that contain additional - information. Slices and trait objects are DSTs. In the case of slices, - the additional information the wide pointer holds is their size. - - To fix this error, don't try to cast directly between thin and wide - pointers. - - For more information about casts, take a look at The Book: - https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions", - -hir_typeck_cast_unknown_pointer = cannot cast {$to -> - [true] to - *[false] from - } a pointer of an unknown kind - .label_to = needs more type information - .note = the type information given here is insufficient to check whether the pointer cast is valid - .label_from = the type information given here is insufficient to check whether the pointer cast is valid - -hir_typeck_const_continue_bad_label = - `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]` - -hir_typeck_continue_labeled_block = - `continue` pointing to a labeled block - .label = labeled blocks cannot be `continue`'d - .block_label = labeled block the `continue` points to - - -hir_typeck_convert_to_str = try converting the passed type into a `&str` - -hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}` - -hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private - -hir_typeck_dependency_on_unit_never_type_fallback = this function depends on never type fallback being `()` - .note = in edition 2024, the requirement `{$obligation}` will fail - .help = specify the types explicitly - -hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` - -hir_typeck_expected_array_or_slice = expected an array or slice, found `{$ty}` -hir_typeck_expected_array_or_slice_label = pattern cannot match with input type `{$ty}` - -hir_typeck_expected_default_return_type = expected `()` because of default return type - -hir_typeck_expected_return_type = expected `{$expected}` because of return type - -hir_typeck_explicit_destructor = explicit use of destructor method - .label = explicit destructor calls not allowed - .suggestion = consider using `drop` function - -hir_typeck_field_multiply_specified_in_initializer = - field `{$ident}` specified more than once - .label = used more than once - .previous_use_label = first use of `{$ident}` - -hir_typeck_fn_item_to_variadic_function = can't pass a function item to a variadic function - .suggestion = use a function pointer instead - .help = a function item is zero-sized and needs to be cast into a function pointer to be used in FFI - .note = for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html - -hir_typeck_fru_expr = this expression does not end in a comma... -hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax -hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression -hir_typeck_fru_suggestion = - to set the remaining fields{$expr -> - [NONE]{""} - *[other] {" "}from `{$expr}` - }, separate the last named field with a comma - -hir_typeck_functional_record_update_on_non_struct = - functional record update syntax requires a struct - -hir_typeck_gpu_kernel_abi_cannot_be_called = - functions with the "gpu-kernel" ABI cannot be called - .note = an `extern "gpu-kernel"` function must be launched on the GPU by the runtime - -hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` -hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` - -hir_typeck_int_to_fat = cannot cast `{$expr_ty}` to a pointer that {$known_wide -> - [true] is - *[false] may be - } wide -hir_typeck_int_to_fat_label = creating a `{$cast_ty}` requires both an address and {$metadata} -hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` - -hir_typeck_invalid_callee = expected function, found {$found} -hir_typeck_invalid_defined = `{$path}` defined here -hir_typeck_invalid_defined_kind = {$kind} `{$path}` defined here -hir_typeck_invalid_fn_defined = `{$func}` defined here returns `{$ty}` -hir_typeck_invalid_local = `{$local_name}` has type `{$ty}` - -hir_typeck_lossy_provenance_int2ptr = - strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}` - .suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address - .help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead - -hir_typeck_lossy_provenance_ptr2int = - under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}` - .suggestion = use `.addr()` to obtain the address of a pointer - .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead - -hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty}` - -hir_typeck_naked_asm_outside_naked_fn = - the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` - -hir_typeck_naked_functions_asm_block = - naked functions must contain a single `naked_asm!` invocation - .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions - .label_non_asm = not allowed in naked functions - -hir_typeck_naked_functions_must_naked_asm = - the `asm!` macro is not allowed in naked functions - .label = consider using the `naked_asm!` macro instead - -hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function - .help = specify the type explicitly -hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference - .help = specify the type explicitly -hir_typeck_never_type_fallback_flowing_into_unsafe_method = never type fallback affects this call to an `unsafe` method - .help = specify the type explicitly -hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback affects this `unsafe` function - .help = specify the type explicitly -hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access - .help = specify the type explicitly - -hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty}`{$trait_missing_method -> - [true] {""} - *[other] {" "}in the current scope -} - -hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}` - -hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}` -hir_typeck_no_field_on_variant_enum = this enum variant... -hir_typeck_no_field_on_variant_field = ...does not have this field - -hir_typeck_no_patterns = - patterns not allowed in naked function parameters - -hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}` - -hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide - -hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}` -hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` -hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` - -hir_typeck_outside_loop = - `{$name}` outside of a loop{$is_break -> - [true] {" or labeled block"} - *[false] {""} - } - .label = cannot `{$name}` outside of a loop{$is_break -> - [true] {" or labeled block"} - *[false] {""} - } - -hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it - - -hir_typeck_params_not_allowed = - referencing function parameters is not allowed in naked functions - .help = follow the calling convention in asm block to use parameters - -hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function - .suggestion = cast the value to `{$cast_ty}` - .teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules - -hir_typeck_project_on_non_pin_project_type = cannot project on type that is not `#[pin_v2]` - .note = type defined here - .suggestion = add `#[pin_v2]` here - -hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> - [1] auto trait {$traits} - *[other] auto traits {$traits} -} to dyn bound via pointer cast - .note = this could allow UB elsewhere - .help = use `transmute` if you're sure this is sound - .label = unsupported cast - -hir_typeck_register_type_unstable = - type `{$ty}` cannot be used with this register class in stable - -hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression -hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression -hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type -hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it -hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon - -hir_typeck_replace_comma_with_semicolon = replace the comma with a semicolon to create {$descr} - -hir_typeck_return_stmt_outside_of_fn_body = - {$statement_kind} statement outside of function body - .encl_body_label = the {$statement_kind} is part of this body... - .encl_fn_label = ...not the enclosing function body - -hir_typeck_rpit_box_return_expr = if you change the return type to expect trait objects, box the returned expressions - -hir_typeck_rpit_change_return_type = you could change the return type to be a boxed trait object - -hir_typeck_rustcall_incorrect_args = - functions with the "rust-call" ABI must take a single non-self tuple argument - -hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from outer item - .label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference - .suggestion = replace `Self` with the actual type - -hir_typeck_self_ctor_from_outer_item_inner_item = `Self` used in this inner item - -hir_typeck_slicing_suggestion = consider slicing here - -hir_typeck_struct_expr_non_exhaustive = - cannot create non-exhaustive {$what} using struct expression - -hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html - -hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new` - -hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead - -hir_typeck_supertrait_item_multiple_shadowee = items from several supertraits are shadowed: {$traits} - -hir_typeck_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by a subtrait item - -hir_typeck_supertrait_item_shadower = item from `{$subtrait}` shadows a supertrait item - -hir_typeck_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait - -hir_typeck_trivial_cast = trivial {$numeric -> - [true] numeric cast - *[false] cast - }: `{$expr_ty}` as `{$cast_ty}` - .help = cast can be replaced by coercion; this might require a temporary variable - -hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns - -hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field - -hir_typeck_unlabeled_cf_in_while_condition = - `break` or `continue` with no label in the condition of a `while` loop - .label = unlabeled `{$cf_type}` in the condition of a `while` loop - -hir_typeck_unlabeled_in_labeled_block = - unlabeled `{$cf_type}` inside of a labeled block - .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label -hir_typeck_use_is_empty = - consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything - -hir_typeck_yield_expr_outside_of_coroutine = - yield expression outside of coroutine literal diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index a26b44e79dc7..d04bd6f2295a 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -2,7 +2,7 @@ use std::iter; use rustc_abi::{CanonAbi, ExternAbi}; use rustc_ast::util::parser::ExprPrecedence; -use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey, inline_fluent}; use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, HirId, LangItem}; @@ -25,8 +25,8 @@ use tracing::{debug, instrument}; use super::method::MethodCallee; use super::method::probe::ProbeScope; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; +use crate::errors; use crate::method::TreatNotYetDefinedOpaques; -use crate::{errors, fluent_generated}; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific @@ -832,12 +832,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (Some((_, kind, path)), _) => { err.arg("kind", kind); err.arg("path", path); - Some(fluent_generated::hir_typeck_invalid_defined_kind) + Some(inline_fluent!("{$kind} `{$path}` defined here")) } (_, Some(hir::QPath::Resolved(_, path))) => { self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| { err.arg("func", p); - fluent_generated::hir_typeck_invalid_fn_defined + inline_fluent!("`{$func}` defined here returns `{$ty}`") }) } _ => { @@ -846,15 +846,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // type definitions themselves, but rather variables *of* that type. Res::Local(hir_id) => { err.arg("local_name", self.tcx.hir_name(hir_id)); - Some(fluent_generated::hir_typeck_invalid_local) + Some(inline_fluent!("`{$local_name}` has type `{$ty}`")) } Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { err.arg("path", self.tcx.def_path_str(def_id)); - Some(fluent_generated::hir_typeck_invalid_defined) + Some(inline_fluent!("`{$path}` defined here")) } _ => { err.arg("path", callee_ty); - Some(fluent_generated::hir_typeck_invalid_defined) + Some(inline_fluent!("`{$path}` defined here")) } } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 0cf7f09e9376..0f330c3021c0 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -7,7 +7,7 @@ use rustc_ast::{AssignOpKind, Label}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, - EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, + EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, inline_fluent, }; use rustc_hir as hir; use rustc_hir::ExprKind; @@ -17,15 +17,15 @@ use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span, Symbol}; -use crate::{FnCtxt, fluent_generated as fluent}; +use crate::FnCtxt; #[derive(Diagnostic)] -#[diag(hir_typeck_base_expression_double_dot, code = E0797)] +#[diag("base expression required after `..`", code = E0797)] pub(crate) struct BaseExpressionDoubleDot { #[primary_span] pub span: Span, #[suggestion( - hir_typeck_base_expression_double_dot_enable_default_field_values, + "add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields", code = "#![feature(default_field_values)]\n", applicability = "machine-applicable", style = "verbose" @@ -39,7 +39,7 @@ pub(crate) struct BaseExpressionDoubleDot { #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_base_expression_double_dot_remove, + "remove the `..` as all the fields are already present", code = "", applicability = "machine-applicable", style = "verbose" @@ -51,7 +51,7 @@ pub(crate) struct BaseExpressionDoubleDotRemove { #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_base_expression_double_dot_add_expr, + "add a base expression here", code = "/* expr */", applicability = "has-placeholders", style = "verbose" @@ -62,24 +62,24 @@ pub(crate) struct BaseExpressionDoubleDotAddExpr { } #[derive(Diagnostic)] -#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)] +#[diag("field `{$ident}` specified more than once", code = E0062)] pub(crate) struct FieldMultiplySpecifiedInInitializer { #[primary_span] - #[label] + #[label("used more than once")] pub span: Span, - #[label(hir_typeck_previous_use_label)] + #[label("first use of `{$ident}`")] pub prev_span: Span, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)] +#[diag("{$statement_kind} statement outside of function body", code = E0572)] pub(crate) struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, - #[label(hir_typeck_encl_body_label)] + #[label("the {$statement_kind} is part of this body...")] pub encl_body_span: Option, - #[label(hir_typeck_encl_fn_label)] + #[label("...not the enclosing function body")] pub encl_fn_span: Option, pub statement_kind: ReturnLikeStatementKind, } @@ -102,21 +102,21 @@ impl IntoDiagArg for ReturnLikeStatementKind { } #[derive(Diagnostic)] -#[diag(hir_typeck_rustcall_incorrect_args)] +#[diag("functions with the \"rust-call\" ABI must take a single non-self tuple argument")] pub(crate) struct RustCallIncorrectArgs { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)] +#[diag("yield expression outside of coroutine literal", code = E0627)] pub(crate) struct YieldExprOutsideOfCoroutine { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)] +#[diag("cannot create non-exhaustive {$what} using struct expression", code = E0639)] pub(crate) struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -124,24 +124,24 @@ pub(crate) struct StructExprNonExhaustive { } #[derive(Diagnostic)] -#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)] +#[diag("functional record update syntax requires a struct", code = E0436)] pub(crate) struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_address_of_temporary_taken, code = E0745)] +#[diag("cannot take address of a temporary", code = E0745)] pub(crate) struct AddressOfTemporaryTaken { #[primary_span] - #[label] + #[label("temporary value")] pub span: Span, } #[derive(Subdiagnostic)] pub(crate) enum AddReturnTypeSuggestion { #[suggestion( - hir_typeck_add_return_type_add, + "try adding a return type", code = " -> {found}", applicability = "machine-applicable" )] @@ -151,7 +151,7 @@ pub(crate) enum AddReturnTypeSuggestion { found: String, }, #[suggestion( - hir_typeck_add_return_type_missing_here, + "a return type might be missing here", code = " -> _", applicability = "has-placeholders" )] @@ -163,12 +163,12 @@ pub(crate) enum AddReturnTypeSuggestion { #[derive(Subdiagnostic)] pub(crate) enum ExpectedReturnTypeLabel<'tcx> { - #[label(hir_typeck_expected_default_return_type)] + #[label("expected `()` because of default return type")] Unit { #[primary_span] span: Span, }, - #[label(hir_typeck_expected_return_type)] + #[label("expected `{$expected}` because of return type")] Other { #[primary_span] span: Span, @@ -177,10 +177,10 @@ pub(crate) enum ExpectedReturnTypeLabel<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_explicit_destructor, code = E0040)] +#[diag("explicit use of destructor method", code = E0040)] pub(crate) struct ExplicitDestructorCall { #[primary_span] - #[label] + #[label("explicit destructor calls not allowed")] pub span: Span, #[subdiagnostic] pub sugg: ExplicitDestructorCallSugg, @@ -188,9 +188,13 @@ pub(crate) struct ExplicitDestructorCall { #[derive(Subdiagnostic)] pub(crate) enum ExplicitDestructorCallSugg { - #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")] + #[suggestion( + "consider using `drop` function", + code = "drop", + applicability = "maybe-incorrect" + )] Empty(#[primary_span] Span), - #[multipart_suggestion(hir_typeck_suggestion, style = "short")] + #[multipart_suggestion("consider using `drop` function", style = "short")] Snippet { #[suggestion_part(code = "drop(")] lo: Span, @@ -200,10 +204,10 @@ pub(crate) enum ExplicitDestructorCallSugg { } #[derive(Diagnostic)] -#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)] +#[diag("can't call method `{$method_name}` on type `{$ty}`", code = E0689)] pub(crate) struct MissingParenthesesInRange<'tcx> { #[primary_span] - #[label(hir_typeck_missing_parentheses_in_range)] + #[label("can't call method `{$method_name}` on type `{$ty}`")] pub span: Span, pub ty: Ty<'tcx>, pub method_name: String, @@ -213,32 +217,32 @@ pub(crate) struct MissingParenthesesInRange<'tcx> { #[derive(LintDiagnostic)] pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { - #[help] - #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] + #[help("specify the type explicitly")] + #[diag("never type fallback affects this call to an `unsafe` function")] Call { #[subdiagnostic] sugg: SuggestAnnotations, }, - #[help] - #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] + #[help("specify the type explicitly")] + #[diag("never type fallback affects this call to an `unsafe` method")] Method { #[subdiagnostic] sugg: SuggestAnnotations, }, - #[help] - #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] + #[help("specify the type explicitly")] + #[diag("never type fallback affects this `unsafe` function")] Path { #[subdiagnostic] sugg: SuggestAnnotations, }, - #[help] - #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] + #[help("specify the type explicitly")] + #[diag("never type fallback affects this union access")] UnionField { #[subdiagnostic] sugg: SuggestAnnotations, }, - #[help] - #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] + #[help("specify the type explicitly")] + #[diag("never type fallback affects this raw pointer dereference")] Deref { #[subdiagnostic] sugg: SuggestAnnotations, @@ -246,10 +250,10 @@ pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { } #[derive(LintDiagnostic)] -#[help] -#[diag(hir_typeck_dependency_on_unit_never_type_fallback)] +#[help("specify the types explicitly")] +#[diag("this function depends on never type fallback being `()`")] pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { - #[note] + #[note("in edition 2024, the requirement `{$obligation}` will fail")] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, #[subdiagnostic] @@ -310,7 +314,7 @@ impl Subdiagnostic for SuggestAnnotations { #[derive(Subdiagnostic)] #[multipart_suggestion( - hir_typeck_add_missing_parentheses_in_range, + "you must surround the range in parentheses to call its `{$func_name}` function", style = "verbose", applicability = "maybe-incorrect" )] @@ -337,17 +341,35 @@ impl Subdiagnostic for TypeMismatchFruTypo { // Only explain that `a ..b` is a range if it's split up if self.expr_span.between(self.fru_span).is_empty() { - diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note); + diag.span_note( + self.expr_span.to(self.fru_span), + inline_fluent!( + "this expression may have been misinterpreted as a `..` range expression" + ), + ); } else { let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into(); - multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr); - multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2); - diag.span_note(multispan, fluent::hir_typeck_fru_note); + multispan.push_span_label( + self.expr_span, + inline_fluent!("this expression does not end in a comma..."), + ); + multispan.push_span_label(self.fru_span, inline_fluent!("... so this is interpreted as a `..` range expression, instead of functional record update syntax")); + diag.span_note( + multispan, + inline_fluent!( + "this expression may have been misinterpreted as a `..` range expression" + ), + ); } diag.span_suggestion( self.expr_span.shrink_to_hi(), - fluent::hir_typeck_fru_suggestion, + inline_fluent!( + "to set the remaining fields{$expr -> + [NONE]{\"\"} + *[other] {\" \"}from `{$expr}` + }, separate the last named field with a comma" + ), ", ", Applicability::MaybeIncorrect, ); @@ -355,8 +377,10 @@ impl Subdiagnostic for TypeMismatchFruTypo { } #[derive(LintDiagnostic)] -#[diag(hir_typeck_lossy_provenance_int2ptr)] -#[help] +#[diag("strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`")] +#[help( + "if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead" +)] pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, @@ -365,19 +389,25 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)] -#[note] -#[help] +#[diag("cannot add {$traits_len -> + [1] auto trait {$traits} + *[other] auto traits {$traits} +} to dyn bound via pointer cast", code = E0804)] +#[note("this could allow UB elsewhere")] +#[help("use `transmute` if you're sure this is sound")] pub(crate) struct PtrCastAddAutoToObject { #[primary_span] - #[label] + #[label("unsupported cast")] pub span: Span, pub traits_len: usize, pub traits: DiagSymbolList, } #[derive(Subdiagnostic)] -#[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")] +#[multipart_suggestion( + "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address", + applicability = "has-placeholders" +)] pub(crate) struct LossyProvenanceInt2PtrSuggestion { #[suggestion_part(code = "(...).with_addr(")] pub lo: Span, @@ -386,8 +416,12 @@ pub(crate) struct LossyProvenanceInt2PtrSuggestion { } #[derive(LintDiagnostic)] -#[diag(hir_typeck_lossy_provenance_ptr2int)] -#[help] +#[diag( + "under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`" +)] +#[help( + "if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead" +)] pub(crate) struct LossyProvenancePtr2Int<'tcx> { pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, @@ -397,7 +431,10 @@ pub(crate) struct LossyProvenancePtr2Int<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { - #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "use `.addr()` to obtain the address of a pointer", + applicability = "maybe-incorrect" + )] NeedsParensCast { #[suggestion_part(code = "(")] expr_span: Span, @@ -405,7 +442,10 @@ pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { cast_span: Span, cast_ty: Ty<'tcx>, }, - #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "use `.addr()` to obtain the address of a pointer", + applicability = "maybe-incorrect" + )] NeedsParens { #[suggestion_part(code = "(")] expr_span: Span, @@ -413,7 +453,7 @@ pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { cast_span: Span, }, #[suggestion( - hir_typeck_suggestion, + "use `.addr()` to obtain the address of a pointer", code = ".addr() as {cast_ty}", applicability = "maybe-incorrect" )] @@ -422,7 +462,11 @@ pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { cast_span: Span, cast_ty: Ty<'tcx>, }, - #[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")] + #[suggestion( + "use `.addr()` to obtain the address of a pointer", + code = ".addr()", + applicability = "maybe-incorrect" + )] Other { #[primary_span] cast_span: Span, @@ -431,11 +475,11 @@ pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum HelpUseLatestEdition { - #[help(hir_typeck_help_set_edition_cargo)] - #[note(hir_typeck_note_edition_guide)] + #[help("set `edition = \"{$edition}\"` in `Cargo.toml`")] + #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] Cargo { edition: Edition }, - #[help(hir_typeck_help_set_edition_standalone)] - #[note(hir_typeck_note_edition_guide)] + #[help("pass `--edition {$edition}` to `rustc`")] + #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] Standalone { edition: Edition }, } @@ -451,7 +495,7 @@ impl HelpUseLatestEdition { } #[derive(Diagnostic)] -#[diag(hir_typeck_no_field_on_type, code = E0609)] +#[diag("no field `{$field}` on type `{$ty}`", code = E0609)] pub(crate) struct NoFieldOnType<'tcx> { #[primary_span] pub(crate) span: Span, @@ -460,33 +504,33 @@ pub(crate) struct NoFieldOnType<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_no_field_on_variant, code = E0609)] +#[diag("no field named `{$field}` on enum variant `{$container}::{$ident}`", code = E0609)] pub(crate) struct NoFieldOnVariant<'tcx> { #[primary_span] pub(crate) span: Span, pub(crate) container: Ty<'tcx>, pub(crate) ident: Ident, pub(crate) field: Ident, - #[label(hir_typeck_no_field_on_variant_enum)] + #[label("this enum variant...")] pub(crate) enum_span: Span, - #[label(hir_typeck_no_field_on_variant_field)] + #[label("...does not have this field")] pub(crate) field_span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_cant_dereference, code = E0614)] +#[diag("type `{$ty}` cannot be dereferenced", code = E0614)] pub(crate) struct CantDereference<'tcx> { #[primary_span] - #[label(hir_typeck_cant_dereference_label)] + #[label("can't be dereferenced")] pub(crate) span: Span, pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(hir_typeck_expected_array_or_slice, code = E0529)] +#[diag("expected an array or slice, found `{$ty}`", code = E0529)] pub(crate) struct ExpectedArrayOrSlice<'tcx> { #[primary_span] - #[label(hir_typeck_expected_array_or_slice_label)] + #[label("pattern cannot match with input type `{$ty}`")] pub(crate) span: Span, pub(crate) ty: Ty<'tcx>, pub(crate) slice_pat_semantics: bool, @@ -498,7 +542,7 @@ pub(crate) struct ExpectedArrayOrSlice<'tcx> { #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_as_deref_suggestion, + "consider using `as_deref` here", code = ".as_deref()", style = "verbose", applicability = "maybe-incorrect" @@ -510,7 +554,7 @@ pub(crate) struct AsDerefSuggestion { #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_slicing_suggestion, + "consider slicing here", code = "[..]", style = "verbose", applicability = "maybe-incorrect" @@ -521,7 +565,7 @@ pub(crate) struct SlicingSuggestion { } #[derive(Diagnostic)] -#[diag(hir_typeck_invalid_callee, code = E0618)] +#[diag("expected function, found {$found}", code = E0618)] pub(crate) struct InvalidCallee<'tcx> { #[primary_span] pub span: Span, @@ -530,15 +574,20 @@ pub(crate) struct InvalidCallee<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_int_to_fat, code = E0606)] +#[diag("cannot cast `{$expr_ty}` to a pointer that {$known_wide -> + [true] is + *[false] may be +} wide", code = E0606)] pub(crate) struct IntToWide<'tcx> { #[primary_span] - #[label(hir_typeck_int_to_fat_label)] + #[label("creating a `{$cast_ty}` requires both an address and {$metadata}")] pub span: Span, pub metadata: &'tcx str, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, - #[label(hir_typeck_int_to_fat_label_nightly)] + #[label( + "consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`" + )] pub expr_if_nightly: Option, pub known_wide: bool, } @@ -546,7 +595,7 @@ pub(crate) struct IntToWide<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum OptionResultRefMismatch { #[suggestion( - hir_typeck_option_result_copied, + "use `{$def_path}::copied` to copy the value inside the `{$def_path}`", code = ".copied()", style = "verbose", applicability = "machine-applicable" @@ -557,7 +606,7 @@ pub(crate) enum OptionResultRefMismatch { def_path: String, }, #[suggestion( - hir_typeck_option_result_cloned, + "use `{$def_path}::cloned` to clone the value inside the `{$def_path}`", code = ".cloned()", style = "verbose", applicability = "machine-applicable" @@ -569,7 +618,7 @@ pub(crate) enum OptionResultRefMismatch { }, // FIXME: #114050 // #[suggestion( - // hir_typeck_option_result_asref, + // "use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}`", // code = ".as_ref()", // style = "verbose", // applicability = "machine-applicable" @@ -592,14 +641,30 @@ pub(crate) struct RemoveSemiForCoerce { impl Subdiagnostic for RemoveSemiForCoerce { fn add_to_diag(self, diag: &mut Diag<'_, G>) { let mut multispan: MultiSpan = self.semi.into(); - multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr); - multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret); - multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi); - diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce); + multispan.push_span_label( + self.expr, + inline_fluent!( + "this could be implicitly returned but it is a statement, not a tail expression" + ), + ); + multispan.push_span_label( + self.ret, + inline_fluent!("the `match` arms can conform to this return type"), + ); + multispan.push_span_label( + self.semi, + inline_fluent!( + "the `match` is a statement because of this semicolon, consider removing it" + ), + ); + diag.span_note( + multispan, + inline_fluent!("you might have meant to return the `match` expression"), + ); diag.tool_only_span_suggestion( self.semi, - fluent::hir_typeck_remove_semi_for_coerce_suggestion, + inline_fluent!("remove this semicolon"), "", Applicability::MaybeIncorrect, ); @@ -607,14 +672,14 @@ impl Subdiagnostic for RemoveSemiForCoerce { } #[derive(Diagnostic)] -#[diag(hir_typeck_union_pat_multiple_fields)] +#[diag("union patterns should have exactly one field")] pub(crate) struct UnionPatMultipleFields { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_union_pat_dotdot)] +#[diag("`..` cannot be used in union patterns")] pub(crate) struct UnionPatDotDot { #[primary_span] pub span: Span, @@ -622,7 +687,7 @@ pub(crate) struct UnionPatDotDot { #[derive(Subdiagnostic)] #[multipart_suggestion( - hir_typeck_use_is_empty, + "consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything", applicability = "maybe-incorrect", style = "verbose" )] @@ -635,7 +700,7 @@ pub(crate) struct UseIsEmpty<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_arg_mismatch_indeterminate)] +#[diag("argument type mismatch was detected, but rustc had trouble determining where")] pub(crate) struct ArgMismatchIndeterminate { #[primary_span] pub span: Span, @@ -643,9 +708,11 @@ pub(crate) struct ArgMismatchIndeterminate { #[derive(Subdiagnostic)] pub(crate) enum SuggestBoxing { - #[note(hir_typeck_suggest_boxing_note)] + #[note( + "for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html" + )] #[multipart_suggestion( - hir_typeck_suggest_boxing_when_appropriate, + "store this in the heap by calling `Box::new`", applicability = "machine-applicable" )] Unit { @@ -654,11 +721,15 @@ pub(crate) enum SuggestBoxing { #[suggestion_part(code = "")] end: Span, }, - #[note(hir_typeck_suggest_boxing_note)] + #[note( + "for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html" + )] AsyncBody, - #[note(hir_typeck_suggest_boxing_note)] + #[note( + "for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html" + )] #[multipart_suggestion( - hir_typeck_suggest_boxing_when_appropriate, + "store this in the heap by calling `Box::new`", applicability = "machine-applicable" )] ExprFieldShorthand { @@ -668,9 +739,11 @@ pub(crate) enum SuggestBoxing { end: Span, ident: Ident, }, - #[note(hir_typeck_suggest_boxing_note)] + #[note( + "for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html" + )] #[multipart_suggestion( - hir_typeck_suggest_boxing_when_appropriate, + "store this in the heap by calling `Box::new`", applicability = "machine-applicable" )] Other { @@ -683,7 +756,7 @@ pub(crate) enum SuggestBoxing { #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_suggest_ptr_null_mut, + "consider using `core::ptr::null_mut` instead", applicability = "maybe-incorrect", style = "verbose", code = "core::ptr::null_mut()" @@ -694,8 +767,13 @@ pub(crate) struct SuggestPtrNullMut { } #[derive(LintDiagnostic)] -#[diag(hir_typeck_trivial_cast)] -#[help] +#[diag( + "trivial {$numeric -> + [true] numeric cast + *[false] cast + }: `{$expr_ty}` as `{$cast_ty}`" +)] +#[help("cast can be replaced by coercion; this might require a temporary variable")] pub(crate) struct TrivialCast<'tcx> { pub numeric: bool, pub expr_ty: Ty<'tcx>, @@ -716,17 +794,24 @@ pub(crate) struct BreakNonLoop<'a> { impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop); + let mut diag = + Diag::new(dcx, level, inline_fluent!("`break` with value from a `{$kind}` loop")); diag.span(self.span); diag.code(E0571); diag.arg("kind", self.kind); - diag.span_label(self.span, fluent::hir_typeck_label); + diag.span_label( + self.span, + inline_fluent!("can only break with a value inside `loop` or breakable block"), + ); if let Some(head) = self.head { - diag.span_label(head, fluent::hir_typeck_label2); + diag.span_label( + head, + inline_fluent!("you can't `break` with a value in a `{$kind}` loop"), + ); } diag.span_suggestion( self.span, - fluent::hir_typeck_suggestion, + inline_fluent!("use `break` on its own without a value inside this `{$kind}` loop"), self.suggestion, Applicability::MaybeIncorrect, ); @@ -744,7 +829,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> { _ => { diag.span_suggestion( self.break_expr_span, - fluent::hir_typeck_break_expr_suggestion, + inline_fluent!( + "alternatively, you might have meant to use the available loop label" + ), label.ident, Applicability::MaybeIncorrect, ); @@ -756,33 +843,33 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> { } #[derive(Diagnostic)] -#[diag(hir_typeck_continue_labeled_block, code = E0696)] +#[diag("`continue` pointing to a labeled block", code = E0696)] pub(crate) struct ContinueLabeledBlock { #[primary_span] - #[label] + #[label("labeled blocks cannot be `continue`'d")] pub span: Span, - #[label(hir_typeck_block_label)] + #[label("labeled block the `continue` points to")] pub block_span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_break_inside_closure, code = E0267)] +#[diag("`{$name}` inside of a closure", code = E0267)] pub(crate) struct BreakInsideClosure<'a> { #[primary_span] - #[label] + #[label("cannot `{$name}` inside of a closure")] pub span: Span, - #[label(hir_typeck_closure_label)] + #[label("enclosing closure")] pub closure_span: Span, pub name: &'a str, } #[derive(Diagnostic)] -#[diag(hir_typeck_break_inside_coroutine, code = E0267)] +#[diag("`{$name}` inside `{$kind}` {$source}", code = E0267)] pub(crate) struct BreakInsideCoroutine<'a> { #[primary_span] - #[label] + #[label("cannot `{$name}` inside `{$kind}` {$source}")] pub span: Span, - #[label(hir_typeck_coroutine_label)] + #[label("enclosing `{$kind}` {$source}")] pub coroutine_span: Span, pub name: &'a str, pub kind: &'a str, @@ -790,10 +877,18 @@ pub(crate) struct BreakInsideCoroutine<'a> { } #[derive(Diagnostic)] -#[diag(hir_typeck_outside_loop, code = E0268)] +#[diag("`{$name}` outside of a loop{$is_break -> + [true] {\" or labeled block\"} + *[false] {\"\"} + }", code = E0268)] pub(crate) struct OutsideLoop<'a> { #[primary_span] - #[label] + #[label( + "cannot `{$name}` outside of a loop{$is_break -> + [true] {\" or labeled block\"} + *[false] {\"\"} + }" + )] pub spans: Vec, pub name: &'a str, pub is_break: bool, @@ -801,7 +896,10 @@ pub(crate) struct OutsideLoop<'a> { pub suggestion: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "consider labeling this block to be able to break within it", + applicability = "maybe-incorrect" +)] pub(crate) struct OutsideLoopSuggestion { #[suggestion_part(code = "'block: ")] pub block_span: Span, @@ -810,25 +908,30 @@ pub(crate) struct OutsideLoopSuggestion { } #[derive(Diagnostic)] -#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)] +#[diag("unlabeled `{$cf_type}` inside of a labeled block", code = E0695)] pub(crate) struct UnlabeledInLabeledBlock<'a> { #[primary_span] - #[label] + #[label( + "`{$cf_type}` statements that would diverge to or through a labeled block need to bear a label" + )] pub span: Span, pub cf_type: &'a str, } #[derive(Diagnostic)] -#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)] +#[diag("`break` or `continue` with no label in the condition of a `while` loop", code = E0590)] pub(crate) struct UnlabeledCfInWhileCondition<'a> { #[primary_span] - #[label] + #[label("unlabeled `{$cf_type}` in the condition of a `while` loop")] pub span: Span, pub cf_type: &'a str, } #[derive(Diagnostic)] -#[diag(hir_typeck_no_associated_item, code = E0599)] +#[diag("no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty}`{$trait_missing_method -> + [true] {\"\"} + *[other] {\" \"}in the current scope +}", code = E0599)] pub(crate) struct NoAssociatedItem<'tcx> { #[primary_span] pub span: Span, @@ -840,7 +943,13 @@ pub(crate) struct NoAssociatedItem<'tcx> { } #[derive(Subdiagnostic)] -#[note(hir_typeck_candidate_trait_note)] +#[note( + "`{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> + [NONE] {\"\"} + [implement] , perhaps you need to implement it + *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it + }" +)] pub(crate) struct CandidateTraitNote { #[primary_span] pub span: Span, @@ -850,7 +959,7 @@ pub(crate) struct CandidateTraitNote { } #[derive(Diagnostic)] -#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)] +#[diag("cannot cast `{$expr_ty}` as `bool`", code = E0054)] pub(crate) struct CannotCastToBool<'tcx> { #[primary_span] pub span: Span, @@ -860,7 +969,7 @@ pub(crate) struct CannotCastToBool<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_cast_enum_drop)] +#[diag("cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop`")] pub(crate) struct CastEnumDrop<'tcx> { #[primary_span] pub span: Span, @@ -869,7 +978,10 @@ pub(crate) struct CastEnumDrop<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_typeck_cast_unknown_pointer, code = E0641)] +#[diag("cannot cast {$to -> + [true] to + *[false] from +} a pointer of an unknown kind", code = E0641)] pub(crate) struct CastUnknownPointer { #[primary_span] pub span: Span, @@ -887,13 +999,13 @@ impl rustc_errors::Subdiagnostic for CastUnknownPointerSub { fn add_to_diag(self, diag: &mut Diag<'_, G>) { match self { CastUnknownPointerSub::To(span) => { - let msg = diag.eagerly_translate(fluent::hir_typeck_label_to); + let msg = diag.eagerly_translate(inline_fluent!("needs more type information")); diag.span_label(span, msg); - let msg = diag.eagerly_translate(fluent::hir_typeck_note); + let msg = diag.eagerly_translate(inline_fluent!("the type information given here is insufficient to check whether the pointer cast is valid")); diag.note(msg); } CastUnknownPointerSub::From(span) => { - let msg = diag.eagerly_translate(fluent::hir_typeck_label_from); + let msg = diag.eagerly_translate(inline_fluent!("the type information given here is insufficient to check whether the pointer cast is valid")); diag.span_label(span, msg); } } @@ -903,18 +1015,18 @@ impl rustc_errors::Subdiagnostic for CastUnknownPointerSub { #[derive(Subdiagnostic)] pub(crate) enum CannotCastToBoolHelp { #[suggestion( - hir_typeck_suggestion, + "compare with zero instead", applicability = "machine-applicable", code = " != 0", style = "verbose" )] Numeric(#[primary_span] Span), - #[label(hir_typeck_label)] + #[label("unsupported cast")] Unsupported(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(hir_typeck_ctor_is_private, code = E0603)] +#[diag("tuple struct constructor `{$def}` is private", code = E0603)] pub(crate) struct CtorIsPrivate { #[primary_span] pub span: Span, @@ -922,7 +1034,7 @@ pub(crate) struct CtorIsPrivate { } #[derive(Subdiagnostic)] -#[note(hir_typeck_deref_is_empty)] +#[note("this expression `Deref`s to `{$deref_ty}` which implements `is_empty`")] pub(crate) struct DerefImplsIsEmpty<'tcx> { #[primary_span] pub span: Span, @@ -931,7 +1043,7 @@ pub(crate) struct DerefImplsIsEmpty<'tcx> { #[derive(Subdiagnostic)] #[multipart_suggestion( - hir_typeck_convert_using_method, + "try using `{$sugg}` to convert `{$found}` to `{$expected}`", applicability = "machine-applicable", style = "verbose" )] @@ -946,7 +1058,9 @@ pub(crate) struct SuggestConvertViaMethod<'tcx> { } #[derive(Subdiagnostic)] -#[note(hir_typeck_note_caller_chooses_ty_for_ty_param)] +#[note( + "the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`" +)] pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> { pub ty_param_name: Symbol, pub found_ty: Ty<'tcx>, @@ -954,14 +1068,20 @@ pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum SuggestBoxingForReturnImplTrait { - #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "you could change the return type to be a boxed trait object", + applicability = "maybe-incorrect" + )] ChangeReturnType { #[suggestion_part(code = "Box, @@ -971,11 +1091,13 @@ pub(crate) enum SuggestBoxingForReturnImplTrait { } #[derive(Diagnostic)] -#[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)] +#[diag("can't reference `Self` constructor from outer item", code = E0401)] pub(crate) struct SelfCtorFromOuterItem { #[primary_span] pub span: Span, - #[label] + #[label( + "the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference" + )] pub impl_span: Span, #[subdiagnostic] pub sugg: Option, @@ -984,16 +1106,18 @@ pub(crate) struct SelfCtorFromOuterItem { } #[derive(Subdiagnostic)] -#[label(hir_typeck_self_ctor_from_outer_item_inner_item)] +#[label("`Self` used in this inner item")] pub(crate) struct InnerItem { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(hir_typeck_self_ctor_from_outer_item)] +#[diag("can't reference `Self` constructor from outer item")] pub(crate) struct SelfCtorFromOuterItemLint { - #[label] + #[label( + "the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference" + )] pub impl_span: Span, #[subdiagnostic] pub sugg: Option, @@ -1002,7 +1126,11 @@ pub(crate) struct SelfCtorFromOuterItemLint { } #[derive(Subdiagnostic)] -#[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")] +#[suggestion( + "replace `Self` with the actual type", + code = "{name}", + applicability = "machine-applicable" +)] pub(crate) struct ReplaceWithName { #[primary_span] pub span: Span, @@ -1010,44 +1138,75 @@ pub(crate) struct ReplaceWithName { } #[derive(Diagnostic)] -#[diag(hir_typeck_cast_thin_pointer_to_wide_pointer, code = E0607)] +#[diag("cannot cast thin pointer `{$expr_ty}` to wide pointer `{$cast_ty}`", code = E0607)] pub(crate) struct CastThinPointerToWidePointer<'tcx> { #[primary_span] pub span: Span, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, - #[note(hir_typeck_teach_help)] + #[note( + "Thin pointers are \"simple\" pointers: they are purely a reference to a + memory address. + + Wide pointers are pointers referencing \"Dynamically Sized Types\" (also + called DST). DST don't have a statically known size, therefore they can + only exist behind some kind of pointers that contain additional + information. Slices and trait objects are DSTs. In the case of slices, + the additional information the wide pointer holds is their size. + + To fix this error, don't try to cast directly between thin and wide + pointers. + + For more information about casts, take a look at The Book: + https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions" + )] pub(crate) teach: bool, } #[derive(Diagnostic)] -#[diag(hir_typeck_pass_to_variadic_function, code = E0617)] +#[diag("can't pass `{$ty}` to variadic function", code = E0617)] pub(crate) struct PassToVariadicFunction<'a, 'tcx> { #[primary_span] pub span: Span, pub ty: Ty<'tcx>, pub cast_ty: &'a str, - #[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "cast the value to `{$cast_ty}`", + code = " as {cast_ty}", + applicability = "machine-applicable", + style = "verbose" + )] pub sugg_span: Span, - #[note(hir_typeck_teach_help)] + #[note( + "certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules" + )] pub(crate) teach: bool, } #[derive(Diagnostic)] -#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)] -#[help] -#[note] +#[diag("can't pass a function item to a variadic function", code = E0617)] +#[help( + "a function item is zero-sized and needs to be cast into a function pointer to be used in FFI" +)] +#[note( + "for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html" +)] pub(crate) struct PassFnItemToVariadicFunction { #[primary_span] pub span: Span, - #[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "use a function pointer instead", + code = " as {replace}", + applicability = "machine-applicable", + style = "verbose" + )] pub sugg_span: Span, pub replace: String, } #[derive(Subdiagnostic)] #[suggestion( - hir_typeck_replace_comma_with_semicolon, + "replace the comma with a semicolon to create {$descr}", applicability = "machine-applicable", style = "verbose", code = "; " @@ -1059,7 +1218,7 @@ pub(crate) struct ReplaceCommaWithSemicolon { } #[derive(LintDiagnostic)] -#[diag(hir_typeck_supertrait_item_shadowing)] +#[diag("trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait")] pub(crate) struct SupertraitItemShadowing { pub item: Symbol, pub subtrait: Symbol, @@ -1070,7 +1229,7 @@ pub(crate) struct SupertraitItemShadowing { } #[derive(Subdiagnostic)] -#[note(hir_typeck_supertrait_item_shadower)] +#[note("item from `{$subtrait}` shadows a supertrait item")] pub(crate) struct SupertraitItemShadower { pub subtrait: Symbol, #[primary_span] @@ -1079,13 +1238,13 @@ pub(crate) struct SupertraitItemShadower { #[derive(Subdiagnostic)] pub(crate) enum SupertraitItemShadowee { - #[note(hir_typeck_supertrait_item_shadowee)] + #[note("item from `{$supertrait}` is shadowed by a subtrait item")] Labeled { #[primary_span] span: Span, supertrait: Symbol, }, - #[note(hir_typeck_supertrait_item_multiple_shadowee)] + #[note("items from several supertraits are shadowed: {$traits}")] Several { #[primary_span] spans: MultiSpan, @@ -1094,7 +1253,7 @@ pub(crate) enum SupertraitItemShadowee { } #[derive(Diagnostic)] -#[diag(hir_typeck_register_type_unstable)] +#[diag("type `{$ty}` cannot be used with this register class in stable")] pub(crate) struct RegisterTypeUnstable<'a> { #[primary_span] pub span: Span, @@ -1102,22 +1261,22 @@ pub(crate) struct RegisterTypeUnstable<'a> { } #[derive(Diagnostic)] -#[diag(hir_typeck_naked_asm_outside_naked_fn)] +#[diag("the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`")] pub(crate) struct NakedAsmOutsideNakedFn { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_no_patterns)] +#[diag("patterns not allowed in naked function parameters")] pub(crate) struct NoPatterns { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_params_not_allowed)] -#[help] +#[diag("referencing function parameters is not allowed in naked functions")] +#[help("follow the calling convention in asm block to use parameters")] pub(crate) struct ParamsNotAllowed { #[primary_span] pub span: Span, @@ -1132,14 +1291,23 @@ pub(crate) struct NakedFunctionsAsmBlock { impl Diagnostic<'_, G> for NakedFunctionsAsmBlock { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("naked functions must contain a single `naked_asm!` invocation"), + ); diag.span(self.span); diag.code(E0787); for span in self.multiple_asms.iter() { - diag.span_label(*span, fluent::hir_typeck_label_multiple_asm); + diag.span_label( + *span, + inline_fluent!( + "multiple `naked_asm!` invocations are not allowed in naked functions" + ), + ); } for span in self.non_asms.iter() { - diag.span_label(*span, fluent::hir_typeck_label_non_asm); + diag.span_label(*span, inline_fluent!("not allowed in naked functions")); } diag } @@ -1182,44 +1350,48 @@ pub(crate) fn maybe_emit_plus_equals_diagnostic<'a>( } #[derive(Diagnostic)] -#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)] +#[diag("the `asm!` macro is not allowed in naked functions", code = E0787)] pub(crate) struct NakedFunctionsMustNakedAsm { #[primary_span] - #[label] + #[label("consider using the `naked_asm!` macro instead")] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_abi_cannot_be_called)] +#[diag("functions with the {$abi} ABI cannot be called")] pub(crate) struct AbiCannotBeCalled { #[primary_span] - #[note] + #[note("an `extern {$abi}` function can only be called using inline assembly")] pub span: Span, pub abi: ExternAbi, } #[derive(Diagnostic)] -#[diag(hir_typeck_gpu_kernel_abi_cannot_be_called)] +#[diag("functions with the \"gpu-kernel\" ABI cannot be called")] pub(crate) struct GpuKernelAbiCannotBeCalled { #[primary_span] - #[note] + #[note("an `extern \"gpu-kernel\"` function must be launched on the GPU by the runtime")] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_const_continue_bad_label)] +#[diag("`#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`")] pub(crate) struct ConstContinueBadLabel { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_typeck_project_on_non_pin_project_type)] +#[diag("cannot project on type that is not `#[pin_v2]`")] pub(crate) struct ProjectOnNonPinProjectType { #[primary_span] pub span: Span, - #[note] + #[note("type defined here")] pub def_span: Option, - #[suggestion(code = "#[pin_v2]\n", applicability = "machine-applicable")] + #[suggestion( + "add `#[pin_v2]` here", + code = "#[pin_v2]\n", + applicability = "machine-applicable" + )] pub sugg_span: Option, } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3e4c194147f9..934aa0a99614 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -5,7 +5,7 @@ use core::iter; use hir::def_id::LocalDefId; use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::packed::Pu128; -use rustc_errors::{Applicability, Diag, MultiSpan, listify}; +use rustc_errors::{Applicability, Diag, MultiSpan, inline_fluent, listify}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::lang_items::LangItem; use rustc_hir::{ @@ -33,10 +33,10 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _ use tracing::{debug, instrument}; use super::FnCtxt; +use crate::errors; use crate::fn_ctxt::rustc_span::BytePos; use crate::method::probe; use crate::method::probe::{IsSuggestion, Mode, ProbeScope}; -use crate::{errors, fluent_generated as fluent}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn body_fn_sig(&self) -> Option> { @@ -482,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg = prefix_wrap(".map(|x| x.as_str())"); err.span_suggestion_verbose( expr.span.shrink_to_hi(), - fluent::hir_typeck_convert_to_str, + inline_fluent!("try converting the passed type into a `&str`"), sugg, Applicability::MachineApplicable, ); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 6e126b3013c9..ac3db41a4d66 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -67,8 +67,6 @@ use crate::expectation::Expectation; use crate::fn_ctxt::LoweredTy; use crate::gather_locals::GatherLocalsVisitor; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - #[macro_export] macro_rules! type_error_struct { ($dcx:expr, $span:expr, $typ:expr, $code:expr, $($message:tt)*) => ({ From 94a0ba50e12740a68fa91a2890f63dcbaa0f9c33 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 4 Feb 2026 00:54:50 +0000 Subject: [PATCH 59/81] Port `rustc_clean` to attribute parser Also remove mentions of removed `rustc_dirty` --- Cargo.lock | 1 - .../src/attributes/rustc_internal.rs | 114 ++++++++++- compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 23 ++- .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 4 +- compiler/rustc_incremental/Cargo.toml | 1 - .../rustc_incremental/src/assert_dep_graph.rs | 2 +- compiler/rustc_incremental/src/errors.rs | 32 +-- .../src/persist/{dirty_clean.rs => clean.rs} | 184 +++++++----------- compiler/rustc_incremental/src/persist/mod.rs | 2 +- .../rustc_incremental/src/persist/save.rs | 4 +- compiler/rustc_passes/messages.ftl | 5 +- compiler/rustc_passes/src/check_attr.rs | 15 +- compiler/rustc_passes/src/errors.rs | 4 +- compiler/rustc_query_system/src/ich/mod.rs | 1 - compiler/rustc_span/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 - .../compiletest/src/runtest/incremental.rs | 2 +- .../incremental/{dirty_clean.rs => clean.rs} | 0 ...cked_dirty_clean.rs => unchecked_clean.rs} | 0 tests/ui/dep-graph/dep-graph-check-attr.rs | 4 +- .../ui/dep-graph/dep-graph-check-attr.stderr | 8 +- 23 files changed, 241 insertions(+), 169 deletions(-) rename compiler/rustc_incremental/src/persist/{dirty_clean.rs => clean.rs} (73%) rename tests/incremental/{dirty_clean.rs => clean.rs} (100%) rename tests/incremental/{unchecked_dirty_clean.rs => unchecked_clean.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 85d3fc1aa7bf..6e088fc12d32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4051,7 +4051,6 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "thin-vec", "tracing", ] diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 8961dc47706f..e30306d0791c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,7 +1,10 @@ use std::path::PathBuf; use rustc_ast::{LitIntType, LitKind, MetaItemLit}; -use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind}; +use rustc_hir::attrs::{ + BorrowckGraphvizFormatKind, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType, + RustcMirKind, +}; use rustc_session::errors; use super::prelude::*; @@ -497,3 +500,112 @@ impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod; } + +pub(crate) struct RustcCleanParser; + +impl CombineAttributeParser for RustcCleanParser { + const PATH: &[Symbol] = &[sym::rustc_clean]; + + type Item = RustcCleanAttribute; + + const CONVERT: ConvertFn = |items, _| AttributeKind::RustcClean(items); + + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + // tidy-alphabetical-start + Allow(Target::AssocConst), + Allow(Target::AssocTy), + Allow(Target::Const), + Allow(Target::Enum), + Allow(Target::Expression), + Allow(Target::Field), + Allow(Target::Fn), + Allow(Target::ForeignMod), + Allow(Target::Impl { of_trait: false }), + Allow(Target::Impl { of_trait: true }), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Mod), + Allow(Target::Static), + Allow(Target::Struct), + Allow(Target::Trait), + Allow(Target::TyAlias), + Allow(Target::Union), + // tidy-alphabetical-end + ]); + + const TEMPLATE: AttributeTemplate = + template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + let mut except = None; + let mut loaded_from_disk = None; + let mut cfg = None; + + for item in list.mixed() { + let Some((value, name)) = + item.meta_item().and_then(|m| Option::zip(m.args().name_value(), m.ident())) + else { + cx.expected_name_value(item.span(), None); + continue; + }; + let value_span = value.value_span; + let Some(value) = value.value_as_str() else { + cx.expected_string_literal(value_span, None); + continue; + }; + match name.name { + sym::cfg if cfg.is_some() => { + cx.duplicate_key(item.span(), sym::cfg); + } + + sym::cfg => { + cfg = Some(value); + } + sym::except if except.is_some() => { + cx.duplicate_key(item.span(), sym::except); + } + sym::except => { + let entries = + value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect(); + except = Some(RustcCleanQueries { entries, span: value_span }); + } + sym::loaded_from_disk if loaded_from_disk.is_some() => { + cx.duplicate_key(item.span(), sym::loaded_from_disk); + } + sym::loaded_from_disk => { + let entries = + value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect(); + loaded_from_disk = Some(RustcCleanQueries { entries, span: value_span }); + } + _ => { + cx.expected_specific_argument( + name.span, + &[sym::cfg, sym::except, sym::loaded_from_disk], + ); + } + } + } + let Some(cfg) = cfg else { + cx.expected_specific_argument(list.span, &[sym::cfg]); + return None; + }; + + Some(RustcCleanAttribute { + // Used for checking that all attributes have been checked + id: cx.cx.sess.psess.attr_id_generator.mk_attr_id(), + span: cx.attr_span, + cfg, + except, + loaded_from_disk, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index fa9f5b585926..e26595ed7545 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -153,6 +153,7 @@ attribute_parsers!( Combine, Combine, Combine, + Combine, Combine, Combine, Combine, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index a53eff4637ff..7955183baf87 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -5,7 +5,7 @@ pub use ReprAttr::*; use rustc_abi::Align; pub use rustc_ast::attr::data_structures::*; use rustc_ast::token::DocFragmentKind; -use rustc_ast::{AttrStyle, ast}; +use rustc_ast::{AttrId, AttrStyle, ast}; use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute}; @@ -716,6 +716,24 @@ pub enum BorrowckGraphvizFormatKind { TwoPhase, } +#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct RustcCleanAttribute { + pub id: AttrId, + pub span: Span, + pub cfg: Symbol, + pub except: Option, + pub loaded_from_disk: Option, +} + +/// Represents the `except=` or `loaded_from_disk=` argument of `#[rustc_clean]` +#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct RustcCleanQueries { + pub entries: ThinVec, + pub span: Span, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -1022,6 +1040,9 @@ pub enum AttributeKind { /// Represents `#[rustc_builtin_macro]`. RustcBuiltinMacro { builtin_name: Option, helper_attrs: ThinVec, span: Span }, + /// Represents `#[rustc_clean]` + RustcClean(ThinVec), + /// Represents `#[rustc_coherence_is_core]` RustcCoherenceIsCore(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7ec1920152a5..500523567433 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -96,6 +96,7 @@ impl AttributeKind { RustcAsPtr(..) => Yes, RustcBodyStability { .. } => No, RustcBuiltinMacro { .. } => Yes, + RustcClean { .. } => No, RustcCoherenceIsCore(..) => No, RustcCoinductive(..) => No, RustcConfusables { .. } => Yes, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index bd268d2c423f..20efd72e20f7 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -6,7 +6,7 @@ use rustc_abi::Align; use rustc_ast::attr::data_structures::CfgEntry; use rustc_ast::attr::version::RustcVersion; use rustc_ast::token::{CommentKind, DocFragmentKind}; -use rustc_ast::{AttrStyle, IntTy, UintTy}; +use rustc_ast::{AttrId, AttrStyle, IntTy, UintTy}; use rustc_ast_pretty::pp::Printer; use rustc_data_structures::fx::FxIndexMap; use rustc_span::def_id::DefId; @@ -179,7 +179,7 @@ macro_rules! print_tup { } print_tup!(A B C D E F G H); -print_skip!(Span, (), ErrorGuaranteed); +print_skip!(Span, (), ErrorGuaranteed, AttrId); print_disp!(u8, u16, u128, usize, bool, NonZero, Limit); print_debug!( Symbol, diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index ae96cc62e54a..d5c3ad2f8337 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -18,6 +18,5 @@ rustc_middle = { path = "../rustc_middle" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 0e04a2a784ec..7849741802c8 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -5,7 +5,7 @@ //! annotations. These annotations can be used to test whether paths //! exist in the graph. These checks run after codegen, so they view the //! the final state of the dependency graph. Note that there are -//! similar assertions found in `persist::dirty_clean` which check the +//! similar assertions found in `persist::clean` which check the //! **initial** state of the dependency graph, just after it has been //! loaded from disk. //! diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index 65109fdec03a..757392896d9e 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use rustc_macros::Diagnostic; -use rustc_span::{Ident, Span, Symbol}; +use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag("unrecognized `DepNode` variant: {$name}")] @@ -106,42 +106,12 @@ pub(crate) struct NotLoaded<'a> { pub dep_node_str: &'a str, } -#[derive(Diagnostic)] -#[diag("unknown `rustc_clean` argument")] -pub(crate) struct UnknownRustcCleanArgument { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag("no cfg attribute")] -pub(crate) struct NoCfg { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag("associated value expected for `{$ident}`")] -pub(crate) struct AssociatedValueExpectedFor { - #[primary_span] - pub span: Span, - pub ident: Ident, -} - -#[derive(Diagnostic)] -#[diag("expected an associated value")] -pub(crate) struct AssociatedValueExpected { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("found unchecked `#[rustc_clean]` attribute")] pub(crate) struct UncheckedClean { #[primary_span] pub span: Span, } - #[derive(Diagnostic)] #[diag("unable to delete old {$name} at `{$path}`: {$err}")] pub(crate) struct DeleteOld<'a> { diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/clean.rs similarity index 73% rename from compiler/rustc_incremental/src/persist/dirty_clean.rs rename to compiler/rustc_incremental/src/persist/clean.rs index 71fb18895246..c8ed91277aac 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -19,26 +19,23 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. -use rustc_ast::{self as ast, MetaItemInner}; +use rustc_ast::ast; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::unord::UnordSet; +use rustc_hir::attrs::{AttributeKind, RustcCleanAttribute}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{ - Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit, + Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, find_attr, + intravisit, }; use rustc_middle::dep_graph::{DepNode, DepNodeExt, dep_kind_from_label, label_strs}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; -use rustc_span::{Span, Symbol, sym}; -use thin_vec::ThinVec; +use rustc_span::{Span, Symbol}; use tracing::debug; use crate::errors; -const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk; -const EXCEPT: Symbol = sym::except; -const CFG: Symbol = sym::cfg; - // Base and Extra labels to build up the labels /// For typedef, constants, and statics @@ -127,14 +124,14 @@ const LABELS_ADT: &[&[&str]] = &[BASE_HIR, BASE_STRUCT]; type Labels = UnordSet; -/// Represents the requested configuration by rustc_clean/dirty +/// Represents the requested configuration by rustc_clean struct Assertion { clean: Labels, dirty: Labels, loaded_from_disk: Labels, } -pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { +pub(crate) fn check_clean_annotations(tcx: TyCtxt<'_>) { if !tcx.sess.opts.unstable_opts.query_dep_graph { return; } @@ -145,24 +142,24 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { } tcx.dep_graph.with_ignore(|| { - let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() }; + let mut clean_visitor = CleanVisitor { tcx, checked_attrs: Default::default() }; let crate_items = tcx.hir_crate_items(()); for id in crate_items.free_items() { - dirty_clean_visitor.check_item(id.owner_id.def_id); + clean_visitor.check_item(id.owner_id.def_id); } for id in crate_items.trait_items() { - dirty_clean_visitor.check_item(id.owner_id.def_id); + clean_visitor.check_item(id.owner_id.def_id); } for id in crate_items.impl_items() { - dirty_clean_visitor.check_item(id.owner_id.def_id); + clean_visitor.check_item(id.owner_id.def_id); } for id in crate_items.foreign_items() { - dirty_clean_visitor.check_item(id.owner_id.def_id); + clean_visitor.check_item(id.owner_id.def_id); } let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] }; @@ -171,67 +168,62 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { // Note that we cannot use the existing "unused attribute"-infrastructure // here, since that is running before codegen. This is also the reason why // all codegen-specific attributes are `AssumedUsed` in rustc_ast::feature_gate. - all_attrs.report_unchecked_attrs(dirty_clean_visitor.checked_attrs); + all_attrs.report_unchecked_attrs(clean_visitor.checked_attrs); }) } -struct DirtyCleanVisitor<'tcx> { +struct CleanVisitor<'tcx> { tcx: TyCtxt<'tcx>, checked_attrs: FxHashSet, } -impl<'tcx> DirtyCleanVisitor<'tcx> { - /// Possibly "deserialize" the attribute into a clean/dirty assertion - fn assertion_maybe(&mut self, item_id: LocalDefId, attr: &Attribute) -> Option { - assert!(attr.has_name(sym::rustc_clean)); - if !check_config(self.tcx, attr) { - // skip: not the correct `cfg=` - return None; - } - let assertion = self.assertion_auto(item_id, attr); - Some(assertion) +impl<'tcx> CleanVisitor<'tcx> { + /// Convert the attribute to an [`Assertion`] if the relevant cfg is active + fn assertion_maybe( + &mut self, + item_id: LocalDefId, + attr: &RustcCleanAttribute, + ) -> Option { + self.tcx + .sess + .psess + .config + .contains(&(attr.cfg, None)) + .then(|| self.assertion_auto(item_id, attr)) } /// Gets the "auto" assertion on pre-validated attr, along with the `except` labels. - fn assertion_auto(&mut self, item_id: LocalDefId, attr: &Attribute) -> Assertion { - let (name, mut auto) = self.auto_labels(item_id, attr); + fn assertion_auto(&mut self, item_id: LocalDefId, attr: &RustcCleanAttribute) -> Assertion { + let (name, mut auto) = self.auto_labels(item_id, attr.span); let except = self.except(attr); let loaded_from_disk = self.loaded_from_disk(attr); for e in except.items().into_sorted_stable_ord() { if !auto.remove(e) { - self.tcx.dcx().emit_fatal(errors::AssertionAuto { span: attr.span(), name, e }); + self.tcx.dcx().emit_fatal(errors::AssertionAuto { span: attr.span, name, e }); } } Assertion { clean: auto, dirty: except, loaded_from_disk } } /// `loaded_from_disk=` attribute value - fn loaded_from_disk(&self, attr: &Attribute) -> Labels { - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(LOADED_FROM_DISK) { - let value = expect_associated_value(self.tcx, &item); - return self.resolve_labels(&item, value); - } - } - // If `loaded_from_disk=` is not specified, don't assert anything - Labels::default() + fn loaded_from_disk(&self, attr: &RustcCleanAttribute) -> Labels { + attr.loaded_from_disk + .as_ref() + .map(|queries| self.resolve_labels(&queries.entries, queries.span)) + .unwrap_or_default() } /// `except=` attribute value - fn except(&self, attr: &Attribute) -> Labels { - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(EXCEPT) { - let value = expect_associated_value(self.tcx, &item); - return self.resolve_labels(&item, value); - } - } - // if no `label` or `except` is given, only the node's group are asserted - Labels::default() + fn except(&self, attr: &RustcCleanAttribute) -> Labels { + attr.except + .as_ref() + .map(|queries| self.resolve_labels(&queries.entries, queries.span)) + .unwrap_or_default() } /// Return all DepNode labels that should be asserted for this item. /// index=0 is the "name" used for error messages - fn auto_labels(&mut self, item_id: LocalDefId, attr: &Attribute) -> (&'static str, Labels) { + fn auto_labels(&mut self, item_id: LocalDefId, span: Span) -> (&'static str, Labels) { let node = self.tcx.hir_node_by_def_id(item_id); let (name, labels) = match node { HirNode::Item(item) => { @@ -282,7 +274,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL), _ => self.tcx.dcx().emit_fatal(errors::UndefinedCleanDirtyItem { - span: attr.span(), + span, kind: format!("{:?}", item.kind), }), } @@ -297,31 +289,31 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), }, - _ => self.tcx.dcx().emit_fatal(errors::UndefinedCleanDirty { - span: attr.span(), - kind: format!("{node:?}"), - }), + _ => self + .tcx + .dcx() + .emit_fatal(errors::UndefinedCleanDirty { span, kind: format!("{node:?}") }), }; let labels = Labels::from_iter(labels.iter().flat_map(|s| s.iter().map(|l| (*l).to_string()))); (name, labels) } - fn resolve_labels(&self, item: &MetaItemInner, value: Symbol) -> Labels { + fn resolve_labels(&self, values: &[Symbol], span: Span) -> Labels { let mut out = Labels::default(); - for label in value.as_str().split(',') { - let label = label.trim(); - if DepNode::has_label_string(label) { - if out.contains(label) { + for label in values { + let label_str = label.as_str(); + if DepNode::has_label_string(label_str) { + if out.contains(label_str) { self.tcx .dcx() - .emit_fatal(errors::RepeatedDepNodeLabel { span: item.span(), label }); + .emit_fatal(errors::RepeatedDepNodeLabel { span, label: label_str }); } - out.insert(label.to_string()); + out.insert(label_str.to_string()); } else { self.tcx .dcx() - .emit_fatal(errors::UnrecognizedDepNodeLabel { span: item.span(), label }); + .emit_fatal(errors::UnrecognizedDepNodeLabel { span, label: label_str }); } } out @@ -360,11 +352,18 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { fn check_item(&mut self, item_id: LocalDefId) { let item_span = self.tcx.def_span(item_id.to_def_id()); let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id()); - for attr in self.tcx.get_attrs(item_id, sym::rustc_clean) { + + let Some(attr) = + find_attr!(self.tcx.get_all_attrs(item_id), AttributeKind::RustcClean(attr) => attr) + else { + return; + }; + + for attr in attr { let Some(assertion) = self.assertion_maybe(item_id, attr) else { continue; }; - self.checked_attrs.insert(attr.id()); + self.checked_attrs.insert(attr.id); for label in assertion.clean.items().into_sorted_stable_ord() { let dep_node = DepNode::from_label_string(self.tcx, label, def_path_hash).unwrap(); self.assert_clean(item_span, dep_node); @@ -400,61 +399,24 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { } } -/// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have -/// a cfg flag called `foo`. -fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool { - debug!("check_config(attr={:?})", attr); - let config = &tcx.sess.psess.config; - debug!("check_config: config={:?}", config); - let mut cfg = None; - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(CFG) { - let value = expect_associated_value(tcx, &item); - debug!("check_config: searching for cfg {:?}", value); - cfg = Some(config.contains(&(value, None))); - } else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) { - tcx.dcx().emit_err(errors::UnknownRustcCleanArgument { span: item.span() }); - } - } - - match cfg { - None => tcx.dcx().emit_fatal(errors::NoCfg { span: attr.span() }), - Some(c) => c, - } -} - -fn expect_associated_value(tcx: TyCtxt<'_>, item: &MetaItemInner) -> Symbol { - if let Some(value) = item.value_str() { - value - } else if let Some(ident) = item.ident() { - tcx.dcx().emit_fatal(errors::AssociatedValueExpectedFor { span: item.span(), ident }); - } else { - tcx.dcx().emit_fatal(errors::AssociatedValueExpected { span: item.span() }); - } -} - /// A visitor that collects all `#[rustc_clean]` attributes from /// the HIR. It is used to verify that we really ran checks for all annotated /// nodes. struct FindAllAttrs<'tcx> { tcx: TyCtxt<'tcx>, - found_attrs: Vec<&'tcx Attribute>, + found_attrs: Vec<&'tcx RustcCleanAttribute>, } impl<'tcx> FindAllAttrs<'tcx> { - fn is_active_attr(&mut self, attr: &Attribute) -> bool { - if attr.has_name(sym::rustc_clean) && check_config(self.tcx, attr) { - return true; - } - - false + fn is_active_attr(&self, attr: &RustcCleanAttribute) -> bool { + self.tcx.sess.psess.config.contains(&(attr.cfg, None)) } fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet) { for attr in &self.found_attrs { - if !checked_attrs.contains(&attr.id()) { - self.tcx.dcx().emit_err(errors::UncheckedClean { span: attr.span() }); - checked_attrs.insert(attr.id()); + if !checked_attrs.contains(&attr.id) { + self.tcx.dcx().emit_err(errors::UncheckedClean { span: attr.span }); + checked_attrs.insert(attr.id); } } } @@ -468,8 +430,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for FindAllAttrs<'tcx> { } fn visit_attribute(&mut self, attr: &'tcx Attribute) { - if self.is_active_attr(attr) { - self.found_attrs.push(attr); + if let Attribute::Parsed(AttributeKind::RustcClean(attrs)) = attr { + for attr in attrs { + if self.is_active_attr(attr) { + self.found_attrs.push(attr); + } + } } } } diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index f5d5167e0e2c..a3857967ab08 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -2,8 +2,8 @@ //! into the given directory. At the same time, it also hashes the //! various HIR nodes. +mod clean; mod data; -mod dirty_clean; mod file_format; mod fs; mod load; diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 58fea3278a83..be16b543e824 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -14,7 +14,7 @@ use tracing::debug; use super::data::*; use super::fs::*; -use super::{dirty_clean, file_format, work_product}; +use super::{clean, file_format, work_product}; use crate::assert_dep_graph::assert_dep_graph; use crate::errors; @@ -42,7 +42,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { let staging_dep_graph_path = staging_dep_graph_path(sess); sess.time("assert_dep_graph", || assert_dep_graph(tcx)); - sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx)); + sess.time("check_clean", || clean::check_clean_annotations(tcx)); join( move || { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index ab89af226793..d6d3d2a3e626 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -439,10 +439,11 @@ passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn` .label = not a `const fn` +passes_rustc_clean = + attribute requires -Z query-dep-graph to be enabled + passes_rustc_const_stable_indirect_pairing = `const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied -passes_rustc_dirty_clean = - attribute requires -Z query-dep-graph to be enabled passes_rustc_force_inline_coro = attribute cannot be applied to a `async`, `gen` or `async gen` function diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4784456a59d9..cf2963e0c285 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -231,6 +231,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) }, Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, + Attribute::Parsed(AttributeKind::RustcClean(attrs)) => { + for attr in attrs { + self.check_rustc_clean(attr.span); + } + } Attribute::Parsed( // tidy-alphabetical-start AttributeKind::RustcAllowIncoherentImpl(..) @@ -356,10 +361,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::diagnostic, sym::on_const, ..] => { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } - [sym::rustc_clean, ..] - | [sym::rustc_dirty, ..] - | [sym::rustc_if_this_changed, ..] - | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), + [sym::rustc_if_this_changed, ..] + | [sym::rustc_then_this_would_need, ..] => self.check_rustc_clean(attr.span()), [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } @@ -1262,9 +1265,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. - fn check_rustc_dirty_clean(&self, attr: &Attribute) { + fn check_rustc_clean(&self, span: Span) { if !self.tcx.sess.opts.unstable_opts.query_dep_graph { - self.dcx().emit_err(errors::RustcDirtyClean { span: attr.span() }); + self.dcx().emit_err(errors::RustcClean { span }); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 29688dd4d537..9eec6a5ed8b6 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -218,8 +218,8 @@ pub(crate) struct RustcLegacyConstGenericsIndexExceed { } #[derive(Diagnostic)] -#[diag(passes_rustc_dirty_clean)] -pub(crate) struct RustcDirtyClean { +#[diag(passes_rustc_clean)] +pub(crate) struct RustcClean { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_query_system/src/ich/mod.rs b/compiler/rustc_query_system/src/ich/mod.rs index 25778add60a9..72a7f3b8f970 100644 --- a/compiler/rustc_query_system/src/ich/mod.rs +++ b/compiler/rustc_query_system/src/ich/mod.rs @@ -11,7 +11,6 @@ pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ sym::cfg_trace, // FIXME should this really be ignored? sym::rustc_if_this_changed, sym::rustc_then_this_would_need, - sym::rustc_dirty, sym::rustc_clean, sym::rustc_partition_reused, sym::rustc_partition_codegened, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index a178f3260d30..17930d35a251 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1331,6 +1331,7 @@ impl Default for Span { rustc_index::newtype_index! { #[orderable] #[debug_format = "AttrId({})"] + #[derive(HashStable_Generic)] pub struct AttrId {} } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c88dd0948b2a..aac4cf1de8c2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1956,7 +1956,6 @@ symbols! { rustc_deprecated_safe_2024, rustc_diagnostic_item, rustc_diagnostic_macros, - rustc_dirty, rustc_do_not_const_check, rustc_doc_primitive, rustc_driver, diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs index 44eb80300c39..5e7698e24858 100644 --- a/src/tools/compiletest/src/runtest/incremental.rs +++ b/src/tools/compiletest/src/runtest/incremental.rs @@ -21,7 +21,7 @@ impl TestCx<'_> { // - execute build/foo/bar.exe and save output // // FIXME -- use non-incremental mode as an oracle? That doesn't apply - // to #[rustc_dirty] and clean tests I guess + // to #[rustc_clean] tests I guess let revision = self.revision.expect("incremental tests require a list of revisions"); diff --git a/tests/incremental/dirty_clean.rs b/tests/incremental/clean.rs similarity index 100% rename from tests/incremental/dirty_clean.rs rename to tests/incremental/clean.rs diff --git a/tests/incremental/unchecked_dirty_clean.rs b/tests/incremental/unchecked_clean.rs similarity index 100% rename from tests/incremental/unchecked_dirty_clean.rs rename to tests/incremental/unchecked_clean.rs diff --git a/tests/ui/dep-graph/dep-graph-check-attr.rs b/tests/ui/dep-graph/dep-graph-check-attr.rs index a45bf24f8c1f..d1692a2166f8 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.rs +++ b/tests/ui/dep-graph/dep-graph-check-attr.rs @@ -5,7 +5,7 @@ #![allow(dead_code)] #![allow(unused_variables)] -#[rustc_clean(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_clean(cfg = "foo")] //~ ERROR attribute requires -Z query-dep-graph fn main() {} #[rustc_if_this_changed(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph @@ -13,7 +13,7 @@ struct Foo { f: T, } -#[rustc_clean(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_clean(cfg = "foo")] //~ ERROR attribute requires -Z query-dep-graph type TypeAlias = Foo; #[rustc_then_this_would_need(variances_of)] //~ ERROR attribute requires -Z query-dep-graph diff --git a/tests/ui/dep-graph/dep-graph-check-attr.stderr b/tests/ui/dep-graph/dep-graph-check-attr.stderr index 46f4e4358cf6..35df92a5874e 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.stderr +++ b/tests/ui/dep-graph/dep-graph-check-attr.stderr @@ -1,8 +1,8 @@ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:8:1 | -LL | #[rustc_clean(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_clean(cfg = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:11:1 @@ -13,8 +13,8 @@ LL | #[rustc_if_this_changed(hir_owner)] error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:16:1 | -LL | #[rustc_clean(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_clean(cfg = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:19:1 From de7067938dd7e88022f8d72bdd0a9167d4205650 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 4 Feb 2026 02:22:48 +0000 Subject: [PATCH 60/81] Port `rustc_if_this_changed`/`rustc_then_this_would_need` to attr parser --- Cargo.lock | 1 - .../src/attributes/rustc_internal.rs | 127 ++++++++++++++++-- compiler/rustc_attr_parsing/src/context.rs | 2 + .../rustc_hir/src/attrs/data_structures.rs | 9 +- .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 + compiler/rustc_incremental/Cargo.toml | 1 - .../rustc_incremental/src/assert_dep_graph.rs | 71 ++++------ compiler/rustc_incremental/src/errors.rs | 7 - .../rustc_incremental/src/persist/clean.rs | 11 +- compiler/rustc_passes/src/check_attr.rs | 5 +- compiler/rustc_span/src/lib.rs | 1 - .../dep-graph-assoc-type-codegen.stderr | 4 +- .../dep-graph/dep-graph-caller-callee.stderr | 8 +- tests/ui/dep-graph/dep-graph-check-attr.rs | 2 +- .../ui/dep-graph/dep-graph-check-attr.stderr | 4 +- .../dep-graph-struct-signature.stderr | 88 ++++++------ ...h-trait-impl-two-traits-same-method.stderr | 8 +- .../dep-graph-trait-impl-two-traits.stderr | 8 +- .../ui/dep-graph/dep-graph-trait-impl.stderr | 20 +-- .../ui/dep-graph/dep-graph-type-alias.stderr | 48 +++---- .../dep-graph/dep-graph-variance-alias.stderr | 4 +- 21 files changed, 256 insertions(+), 175 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e088fc12d32..76f61fcb0d3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4039,7 +4039,6 @@ name = "rustc_incremental" version = "0.0.0" dependencies = [ "rand 0.9.2", - "rustc_ast", "rustc_data_structures", "rustc_errors", "rustc_fs_util", diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index e30306d0791c..37372995faf1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -6,6 +6,7 @@ use rustc_hir::attrs::{ RustcMirKind, }; use rustc_session::errors; +use rustc_span::Symbol; use super::prelude::*; use super::util::parse_single_integer; @@ -237,7 +238,7 @@ impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationPa pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { - const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default]; + const PATH: &[Symbol] = &[sym::rustc_object_lifetime_default]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); @@ -274,7 +275,7 @@ impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser pub(crate) struct RustcScalableVectorParser; impl SingleAttributeParser for RustcScalableVectorParser { - const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector]; + const PATH: &[Symbol] = &[sym::rustc_scalable_vector]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); @@ -347,7 +348,7 @@ impl NoArgsAttributeParser for RustcOffloadKernelParser { pub(crate) struct RustcLayoutParser; impl CombineAttributeParser for RustcLayoutParser { - const PATH: &[rustc_span::Symbol] = &[sym::rustc_layout]; + const PATH: &[Symbol] = &[sym::rustc_layout]; type Item = RustcLayoutType; @@ -404,7 +405,7 @@ impl CombineAttributeParser for RustcLayoutParser { pub(crate) struct RustcMirParser; impl CombineAttributeParser for RustcMirParser { - const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir]; + const PATH: &[Symbol] = &[sym::rustc_mir]; type Item = RustcMirKind; @@ -599,13 +600,115 @@ impl CombineAttributeParser for RustcCleanParser { return None; }; - Some(RustcCleanAttribute { - // Used for checking that all attributes have been checked - id: cx.cx.sess.psess.attr_id_generator.mk_attr_id(), - span: cx.attr_span, - cfg, - except, - loaded_from_disk, - }) + Some(RustcCleanAttribute { span: cx.attr_span, cfg, except, loaded_from_disk }) + } +} + +pub(crate) struct RustcIfThisChangedParser; + +impl SingleAttributeParser for RustcIfThisChangedParser { + const PATH: &[Symbol] = &[sym::rustc_if_this_changed]; + + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + // tidy-alphabetical-start + Allow(Target::AssocConst), + Allow(Target::AssocTy), + Allow(Target::Const), + Allow(Target::Enum), + Allow(Target::Expression), + Allow(Target::Field), + Allow(Target::Fn), + Allow(Target::ForeignMod), + Allow(Target::Impl { of_trait: false }), + Allow(Target::Impl { of_trait: true }), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Mod), + Allow(Target::Static), + Allow(Target::Struct), + Allow(Target::Trait), + Allow(Target::TyAlias), + Allow(Target::Union), + // tidy-alphabetical-end + ]); + + const TEMPLATE: AttributeTemplate = template!(Word, List: &["DepNode"]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + match args { + ArgParser::NoArgs => Some(AttributeKind::RustcIfThisChanged(cx.attr_span, None)), + ArgParser::List(list) => { + let Some(item) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + let Some(ident) = item.meta_item().and_then(|item| item.ident()) else { + cx.expected_identifier(item.span()); + return None; + }; + Some(AttributeKind::RustcIfThisChanged(cx.attr_span, Some(ident.name))) + } + ArgParser::NameValue(_) => { + cx.expected_list_or_no_args(cx.inner_span); + None + } + } + } +} + +pub(crate) struct RustcThenThisWouldNeedParser; + +impl CombineAttributeParser for RustcThenThisWouldNeedParser { + const PATH: &[Symbol] = &[sym::rustc_then_this_would_need]; + type Item = Ident; + + const CONVERT: ConvertFn = + |items, span| AttributeKind::RustcThenThisWouldNeed(span, items); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + // tidy-alphabetical-start + Allow(Target::AssocConst), + Allow(Target::AssocTy), + Allow(Target::Const), + Allow(Target::Enum), + Allow(Target::Expression), + Allow(Target::Field), + Allow(Target::Fn), + Allow(Target::ForeignMod), + Allow(Target::Impl { of_trait: false }), + Allow(Target::Impl { of_trait: true }), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Mod), + Allow(Target::Static), + Allow(Target::Struct), + Allow(Target::Trait), + Allow(Target::TyAlias), + Allow(Target::Union), + // tidy-alphabetical-end + ]); + + const TEMPLATE: AttributeTemplate = template!(List: &["DepNode"]); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { + let Some(item) = args.list().and_then(|l| l.single()) else { + cx.expected_single_argument(cx.inner_span); + return None; + }; + let Some(ident) = item.meta_item().and_then(|item| item.ident()) else { + cx.expected_identifier(item.span()); + return None; + }; + Some(ident) } } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index e26595ed7545..065a17819393 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -156,6 +156,7 @@ attribute_parsers!( Combine, Combine, Combine, + Combine, Combine, Combine, // tidy-alphabetical-end @@ -192,6 +193,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7955183baf87..ebb34ea87066 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -5,7 +5,7 @@ pub use ReprAttr::*; use rustc_abi::Align; pub use rustc_ast::attr::data_structures::*; use rustc_ast::token::DocFragmentKind; -use rustc_ast::{AttrId, AttrStyle, ast}; +use rustc_ast::{AttrStyle, ast}; use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute}; @@ -719,7 +719,6 @@ pub enum BorrowckGraphvizFormatKind { #[derive(Clone, Debug, PartialEq, Eq)] #[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct RustcCleanAttribute { - pub id: AttrId, pub span: Span, pub cfg: Symbol, pub except: Option, @@ -1098,6 +1097,9 @@ pub enum AttributeKind { /// Represents `#[rustc_hidden_type_of_opaques]` RustcHiddenTypeOfOpaques, + /// Represents `#[rustc_if_this_changed]` + RustcIfThisChanged(Span, Option), + /// Represents `#[rustc_layout]` RustcLayout(ThinVec), @@ -1199,6 +1201,9 @@ pub enum AttributeKind { /// Represents `#[rustc_std_internal_symbol]`. RustcStdInternalSymbol(Span), + /// Represents `#[rustc_then_this_would_need]` + RustcThenThisWouldNeed(Span, ThinVec), + /// Represents `#[rustc_unsafe_specialization_marker]`. RustcUnsafeSpecializationMarker(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 500523567433..e97093383b2c 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -113,6 +113,7 @@ impl AttributeKind { RustcDynIncompatibleTrait(..) => No, RustcHasIncoherentInherentImpls => Yes, RustcHiddenTypeOfOpaques => No, + RustcIfThisChanged(..) => No, RustcLayout(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, @@ -145,6 +146,7 @@ impl AttributeKind { RustcSkipDuringMethodDispatch { .. } => No, RustcSpecializationTrait(..) => No, RustcStdInternalSymbol(..) => No, + RustcThenThisWouldNeed(..) => No, RustcUnsafeSpecializationMarker(..) => No, RustcVariance => No, RustcVarianceOfOpaques => No, diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index d5c3ad2f8337..ac4d7d8e1cbc 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rand = "0.9.0" -rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 7849741802c8..3447836598bf 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -39,14 +39,16 @@ use std::io::Write; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING}; +use rustc_hir::Attribute; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; +use rustc_middle::bug; use rustc_middle::dep_graph::{ DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter, dep_kinds, }; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; -use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use tracing::debug; use {rustc_graphviz as dot, rustc_hir as hir}; @@ -105,29 +107,13 @@ struct IfThisChanged<'tcx> { } impl<'tcx> IfThisChanged<'tcx> { - fn argument(&self, attr: &hir::Attribute) -> Option { - let mut value = None; - for list_item in attr.meta_item_list().unwrap_or_default() { - match list_item.ident() { - Some(ident) if list_item.is_word() && value.is_none() => value = Some(ident.name), - _ => - // FIXME better-encapsulate meta_item (don't directly access `node`) - { - span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item) - } - } - } - value - } - fn process_attrs(&mut self, def_id: LocalDefId) { let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id()); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { - if attr.has_name(sym::rustc_if_this_changed) { - let dep_node_interned = self.argument(attr); - let dep_node = match dep_node_interned { + if let Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, dep_node)) = *attr { + let dep_node = match dep_node { None => DepNode::from_def_path_hash( self.tcx, def_path_hash, @@ -136,36 +122,29 @@ impl<'tcx> IfThisChanged<'tcx> { Some(n) => { match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) { Ok(n) => n, - Err(()) => self.tcx.dcx().emit_fatal(errors::UnrecognizedDepNode { - span: attr.span(), - name: n, - }), + Err(()) => self + .tcx + .dcx() + .emit_fatal(errors::UnrecognizedDepNode { span, name: n }), } } }; - self.if_this_changed.push((attr.span(), def_id.to_def_id(), dep_node)); - } else if attr.has_name(sym::rustc_then_this_would_need) { - let dep_node_interned = self.argument(attr); - let dep_node = match dep_node_interned { - Some(n) => { - match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) { - Ok(n) => n, - Err(()) => self.tcx.dcx().emit_fatal(errors::UnrecognizedDepNode { - span: attr.span(), - name: n, - }), - } - } - None => { - self.tcx.dcx().emit_fatal(errors::MissingDepNode { span: attr.span() }); - } - }; - self.then_this_would_need.push(( - attr.span(), - dep_node_interned.unwrap(), - hir_id, - dep_node, - )); + self.if_this_changed.push((span, def_id.to_def_id(), dep_node)); + } else if let Attribute::Parsed(AttributeKind::RustcThenThisWouldNeed( + _, + ref dep_nodes, + )) = *attr + { + for &n in dep_nodes { + let Ok(dep_node) = + DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) + else { + self.tcx + .dcx() + .emit_fatal(errors::UnrecognizedDepNode { span: n.span, name: n.name }); + }; + self.then_this_would_need.push((n.span, n.name, hir_id, dep_node)); + } } } } diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index 757392896d9e..9b33b49d4406 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -11,13 +11,6 @@ pub(crate) struct UnrecognizedDepNode { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag("missing `DepNode` variant")] -pub(crate) struct MissingDepNode { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("no `#[rustc_if_this_changed]` annotation detected")] pub(crate) struct MissingIfThisChanged { diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index c8ed91277aac..d83ba5a78bed 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -19,7 +19,6 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. -use rustc_ast::ast; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::unord::UnordSet; use rustc_hir::attrs::{AttributeKind, RustcCleanAttribute}; @@ -174,7 +173,7 @@ pub(crate) fn check_clean_annotations(tcx: TyCtxt<'_>) { struct CleanVisitor<'tcx> { tcx: TyCtxt<'tcx>, - checked_attrs: FxHashSet, + checked_attrs: FxHashSet, } impl<'tcx> CleanVisitor<'tcx> { @@ -363,7 +362,7 @@ impl<'tcx> CleanVisitor<'tcx> { let Some(assertion) = self.assertion_maybe(item_id, attr) else { continue; }; - self.checked_attrs.insert(attr.id); + self.checked_attrs.insert(attr.span); for label in assertion.clean.items().into_sorted_stable_ord() { let dep_node = DepNode::from_label_string(self.tcx, label, def_path_hash).unwrap(); self.assert_clean(item_span, dep_node); @@ -412,11 +411,11 @@ impl<'tcx> FindAllAttrs<'tcx> { self.tcx.sess.psess.config.contains(&(attr.cfg, None)) } - fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet) { + fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet) { for attr in &self.found_attrs { - if !checked_attrs.contains(&attr.id) { + if !checked_attrs.contains(&attr.span) { self.tcx.dcx().emit_err(errors::UncheckedClean { span: attr.span }); - checked_attrs.insert(attr.id); + checked_attrs.insert(attr.span); } } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index cf2963e0c285..48580508b454 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -235,6 +235,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { self.check_rustc_clean(attr.span); } + }, + Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, _) | AttributeKind::RustcThenThisWouldNeed(span, _)) => { + self.check_rustc_clean(*span); } Attribute::Parsed( // tidy-alphabetical-start @@ -361,8 +364,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::diagnostic, sym::on_const, ..] => { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } - [sym::rustc_if_this_changed, ..] - | [sym::rustc_then_this_would_need, ..] => self.check_rustc_clean(attr.span()), [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 17930d35a251..a178f3260d30 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1331,7 +1331,6 @@ impl Default for Span { rustc_index::newtype_index! { #[orderable] #[debug_format = "AttrId({})"] - #[derive(HashStable_Generic)] pub struct AttrId {} } diff --git a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr index f26b43aa3ec7..b0372051f026 100644 --- a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr +++ b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr @@ -1,8 +1,8 @@ error: OK - --> $DIR/dep-graph-assoc-type-codegen.rs:29:5 + --> $DIR/dep-graph-assoc-type-codegen.rs:29:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/dep-graph/dep-graph-caller-callee.stderr b/tests/ui/dep-graph/dep-graph-caller-callee.stderr index 4d06dc7f3ed3..33fe91b3500a 100644 --- a/tests/ui/dep-graph/dep-graph-caller-callee.stderr +++ b/tests/ui/dep-graph/dep-graph-caller-callee.stderr @@ -1,14 +1,14 @@ error: OK - --> $DIR/dep-graph-caller-callee.rs:21:5 + --> $DIR/dep-graph-caller-callee.rs:21:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x` to `typeck` - --> $DIR/dep-graph-caller-callee.rs:32:5 + --> $DIR/dep-graph-caller-callee.rs:32:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-check-attr.rs b/tests/ui/dep-graph/dep-graph-check-attr.rs index d1692a2166f8..c0697a5316f7 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.rs +++ b/tests/ui/dep-graph/dep-graph-check-attr.rs @@ -8,7 +8,7 @@ #[rustc_clean(cfg = "foo")] //~ ERROR attribute requires -Z query-dep-graph fn main() {} -#[rustc_if_this_changed(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_if_this_changed] //~ ERROR attribute requires -Z query-dep-graph struct Foo { f: T, } diff --git a/tests/ui/dep-graph/dep-graph-check-attr.stderr b/tests/ui/dep-graph/dep-graph-check-attr.stderr index 35df92a5874e..4b651c47ac83 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.stderr +++ b/tests/ui/dep-graph/dep-graph-check-attr.stderr @@ -7,8 +7,8 @@ LL | #[rustc_clean(cfg = "foo")] error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:11:1 | -LL | #[rustc_if_this_changed(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_if_this_changed] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:16:1 diff --git a/tests/ui/dep-graph/dep-graph-struct-signature.stderr b/tests/ui/dep-graph/dep-graph-struct-signature.stderr index cfe1e62d9318..98efedc7244c 100644 --- a/tests/ui/dep-graph/dep-graph-struct-signature.stderr +++ b/tests/ui/dep-graph/dep-graph-struct-signature.stderr @@ -1,134 +1,134 @@ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:28:5 + --> $DIR/dep-graph-struct-signature.rs:28:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `associated_item` - --> $DIR/dep-graph-struct-signature.rs:29:5 + --> $DIR/dep-graph-struct-signature.rs:29:34 | LL | #[rustc_then_this_would_need(associated_item)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: no path from `WillChange` to `trait_def` - --> $DIR/dep-graph-struct-signature.rs:30:5 + --> $DIR/dep-graph-struct-signature.rs:30:34 | LL | #[rustc_then_this_would_need(trait_def)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:36:5 + --> $DIR/dep-graph-struct-signature.rs:36:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:37:5 + --> $DIR/dep-graph-struct-signature.rs:37:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:40:5 + --> $DIR/dep-graph-struct-signature.rs:40:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:41:5 + --> $DIR/dep-graph-struct-signature.rs:41:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:46:5 + --> $DIR/dep-graph-struct-signature.rs:46:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:53:5 + --> $DIR/dep-graph-struct-signature.rs:53:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:61:9 + --> $DIR/dep-graph-struct-signature.rs:61:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:63:9 + --> $DIR/dep-graph-struct-signature.rs:63:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:68:5 + --> $DIR/dep-graph-struct-signature.rs:68:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:75:5 + --> $DIR/dep-graph-struct-signature.rs:75:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:81:5 + --> $DIR/dep-graph-struct-signature.rs:81:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:84:5 + --> $DIR/dep-graph-struct-signature.rs:84:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `typeck` - --> $DIR/dep-graph-struct-signature.rs:85:5 + --> $DIR/dep-graph-struct-signature.rs:85:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:32:9 + --> $DIR/dep-graph-struct-signature.rs:32:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:77:9 + --> $DIR/dep-graph-struct-signature.rs:77:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:48:9 + --> $DIR/dep-graph-struct-signature.rs:48:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:49:9 + --> $DIR/dep-graph-struct-signature.rs:49:38 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:55:9 + --> $DIR/dep-graph-struct-signature.rs:55:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:56:9 + --> $DIR/dep-graph-struct-signature.rs:56:38 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 22 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr index 6f56cbc8dd7a..293f918a3187 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr @@ -1,14 +1,14 @@ error: OK - --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:5 + --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:5 + --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr index 08f382cc024c..46cb0e9ea86f 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr @@ -1,14 +1,14 @@ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits.rs:32:5 + --> $DIR/dep-graph-trait-impl-two-traits.rs:32:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits.rs:41:5 + --> $DIR/dep-graph-trait-impl-two-traits.rs:41:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl.stderr b/tests/ui/dep-graph/dep-graph-trait-impl.stderr index bfee6d5c87b3..a5fce64c3a1c 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl.stderr @@ -1,32 +1,32 @@ error: OK - --> $DIR/dep-graph-trait-impl.rs:28:5 + --> $DIR/dep-graph-trait-impl.rs:28:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:33:5 + --> $DIR/dep-graph-trait-impl.rs:33:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:38:5 + --> $DIR/dep-graph-trait-impl.rs:38:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:43:5 + --> $DIR/dep-graph-trait-impl.rs:43:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl.rs:56:5 + --> $DIR/dep-graph-trait-impl.rs:56:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/dep-graph/dep-graph-type-alias.stderr b/tests/ui/dep-graph/dep-graph-type-alias.stderr index 42ac803b22ec..9f24c1113b98 100644 --- a/tests/ui/dep-graph/dep-graph-type-alias.stderr +++ b/tests/ui/dep-graph/dep-graph-type-alias.stderr @@ -1,74 +1,74 @@ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:18:1 + --> $DIR/dep-graph-type-alias.rs:18:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:20:5 + --> $DIR/dep-graph-type-alias.rs:20:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:25:1 + --> $DIR/dep-graph-type-alias.rs:25:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:28:9 + --> $DIR/dep-graph-type-alias.rs:28:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:34:1 + --> $DIR/dep-graph-type-alias.rs:34:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:42:1 + --> $DIR/dep-graph-type-alias.rs:42:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:49:1 + --> $DIR/dep-graph-type-alias.rs:49:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:52:1 + --> $DIR/dep-graph-type-alias.rs:52:30 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:53:1 + --> $DIR/dep-graph-type-alias.rs:53:30 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:36:5 + --> $DIR/dep-graph-type-alias.rs:36:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:44:5 + --> $DIR/dep-graph-type-alias.rs:44:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:45:5 + --> $DIR/dep-graph-type-alias.rs:45:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 12 previous errors diff --git a/tests/ui/dep-graph/dep-graph-variance-alias.stderr b/tests/ui/dep-graph/dep-graph-variance-alias.stderr index e11de2452899..83ef573aad48 100644 --- a/tests/ui/dep-graph/dep-graph-variance-alias.stderr +++ b/tests/ui/dep-graph/dep-graph-variance-alias.stderr @@ -1,8 +1,8 @@ error: OK - --> $DIR/dep-graph-variance-alias.rs:19:1 + --> $DIR/dep-graph-variance-alias.rs:19:30 | LL | #[rustc_then_this_would_need(variances_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to 1 previous error From 522778e34826c70576163a207c641483e277419d Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 4 Feb 2026 20:43:29 +0000 Subject: [PATCH 61/81] Move `query-dep-graph` opt check to attr parsing --- .../src/attributes/rustc_internal.rs | 11 ++++++++++- .../src/session_diagnostics.rs | 8 ++++++++ compiler/rustc_passes/messages.ftl | 3 --- compiler/rustc_passes/src/check_attr.rs | 19 +++---------------- compiler/rustc_passes/src/errors.rs | 7 ------- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 37372995faf1..348882dc59fc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -10,7 +10,7 @@ use rustc_span::Symbol; use super::prelude::*; use super::util::parse_single_integer; -use crate::session_diagnostics::RustcScalableVectorCountOutOfRange; +use crate::session_diagnostics::{AttributeRequiresOpt, RustcScalableVectorCountOutOfRange}; pub(crate) struct RustcMainParser; @@ -543,6 +543,9 @@ impl CombineAttributeParser for RustcCleanParser { cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser, ) -> impl IntoIterator { + if !cx.cx.sess.opts.unstable_opts.query_dep_graph { + cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" }); + } let Some(list) = args.list() else { cx.expected_list(cx.attr_span, args); return None; @@ -641,6 +644,9 @@ impl SingleAttributeParser for RustcIfThisChangedParser { const TEMPLATE: AttributeTemplate = template!(Word, List: &["DepNode"]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + if !cx.cx.sess.opts.unstable_opts.query_dep_graph { + cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" }); + } match args { ArgParser::NoArgs => Some(AttributeKind::RustcIfThisChanged(cx.attr_span, None)), ArgParser::List(list) => { @@ -701,6 +707,9 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser { cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser, ) -> impl IntoIterator { + if !cx.cx.sess.opts.unstable_opts.query_dep_graph { + cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" }); + } let Some(item) = args.list().and_then(|l| l.single()) else { cx.expected_single_argument(cx.inner_span); return None; diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index b0a334210f74..6ca47e8d698b 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -532,6 +532,14 @@ pub(crate) struct RustcScalableVectorCountOutOfRange { pub n: u128, } +#[derive(Diagnostic)] +#[diag("attribute requires {$opt} to be enabled")] +pub(crate) struct AttributeRequiresOpt { + #[primary_span] + pub span: Span, + pub opt: &'static str, +} + pub(crate) enum AttributeParseErrorReason<'a> { ExpectedNoArgs, ExpectedStringLiteral { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index d6d3d2a3e626..fae0052ab7a4 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -439,9 +439,6 @@ passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn` .label = not a `const fn` -passes_rustc_clean = - attribute requires -Z query-dep-graph to be enabled - passes_rustc_const_stable_indirect_pairing = `const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 48580508b454..c46321788aed 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -231,14 +231,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) }, Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, - Attribute::Parsed(AttributeKind::RustcClean(attrs)) => { - for attr in attrs { - self.check_rustc_clean(attr.span); - } - }, - Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, _) | AttributeKind::RustcThenThisWouldNeed(span, _)) => { - self.check_rustc_clean(*span); - } Attribute::Parsed( // tidy-alphabetical-start AttributeKind::RustcAllowIncoherentImpl(..) @@ -300,6 +292,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcAsPtr(..) | AttributeKind::RustcBodyStability { .. } | AttributeKind::RustcBuiltinMacro { .. } + | AttributeKind::RustcClean(..) | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::RustcCoinductive(..) | AttributeKind::RustcConfusables { .. } @@ -315,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDynIncompatibleTrait(..) | AttributeKind::RustcHasIncoherentInherentImpls | AttributeKind::RustcHiddenTypeOfOpaques + | AttributeKind::RustcIfThisChanged(..) | AttributeKind::RustcLayout(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLayoutScalarValidRangeStart(..) @@ -343,6 +337,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcSkipDuringMethodDispatch { .. } | AttributeKind::RustcSpecializationTrait(..) | AttributeKind::RustcStdInternalSymbol (..) + | AttributeKind::RustcThenThisWouldNeed(..) | AttributeKind::RustcUnsafeSpecializationMarker(..) | AttributeKind::RustcVariance | AttributeKind::RustcVarianceOfOpaques @@ -1264,14 +1259,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph - /// option is passed to the compiler. - fn check_rustc_clean(&self, span: Span) { - if !self.tcx.sess.opts.unstable_opts.query_dep_graph { - self.dcx().emit_err(errors::RustcClean { span }); - } - } - /// Checks if the `#[repr]` attributes on `item` are valid. fn check_repr( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 9eec6a5ed8b6..d0fa1c4f0e03 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -217,13 +217,6 @@ pub(crate) struct RustcLegacyConstGenericsIndexExceed { pub arg_count: usize, } -#[derive(Diagnostic)] -#[diag(passes_rustc_clean)] -pub(crate) struct RustcClean { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_repr_conflicting, code = E0566)] pub(crate) struct ReprConflicting { From a68bb0c3711ccb6d90aa039cac9a28c67a4e3cc0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Feb 2026 15:27:05 +1100 Subject: [PATCH 62/81] Move `rustc_query_system::values` module into `rustc_middle`. It's a tiny module with one trait and a default impl. It's not used in `rustc_query_system`; all uses and non-default impls are in `rustc_middle` and `rustc_query_impl`. This commit moves it into `rustc_middle`, which makes things simpler overall. --- compiler/rustc_middle/src/lib.rs | 2 +- compiler/rustc_middle/src/values.rs | 41 +++++++++++++++++------ compiler/rustc_query_impl/src/lib.rs | 2 +- compiler/rustc_query_system/src/lib.rs | 2 -- compiler/rustc_query_system/src/values.rs | 21 ------------ 5 files changed, 32 insertions(+), 36 deletions(-) delete mode 100644 compiler/rustc_query_system/src/values.rs diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index bb94b4c927ae..a21427f6c819 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -81,7 +81,7 @@ pub mod thir; pub mod traits; pub mod ty; pub mod util; -mod values; +pub mod values; #[macro_use] pub mod query; diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index fd08b5a972c6..0828758cc94e 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -7,7 +7,6 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_query_system::Value; use rustc_query_system::query::{CycleError, report_cycle}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; @@ -16,7 +15,27 @@ use crate::dep_graph::dep_kinds; use crate::query::plumbing::CyclePlaceholder; use crate::ty::{self, Representability, Ty, TyCtxt}; -impl<'tcx> Value> for Ty<'_> { +pub trait Value<'tcx>: Sized { + fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) + -> Self; +} + +impl<'tcx, T> Value<'tcx> for T { + default fn from_cycle_error( + tcx: TyCtxt<'tcx>, + cycle_error: &CycleError, + _guar: ErrorGuaranteed, + ) -> T { + tcx.sess.dcx().abort_if_errors(); + bug!( + "<{} as Value>::from_cycle_error called without errors: {:#?}", + std::any::type_name::(), + cycle_error.cycle, + ); + } +} + +impl<'tcx> Value<'tcx> for Ty<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. @@ -24,13 +43,13 @@ impl<'tcx> Value> for Ty<'_> { } } -impl<'tcx> Value> for Result>, CyclePlaceholder> { +impl<'tcx> Value<'tcx> for Result>, CyclePlaceholder> { fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self { Err(CyclePlaceholder(guar)) } } -impl<'tcx> Value> for ty::SymbolName<'_> { +impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, _guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. @@ -42,7 +61,7 @@ impl<'tcx> Value> for ty::SymbolName<'_> { } } -impl<'tcx> Value> for ty::Binder<'_, ty::FnSig<'_>> { +impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -76,7 +95,7 @@ impl<'tcx> Value> for ty::Binder<'_, ty::FnSig<'_>> { } } -impl<'tcx> Value> for Representability { +impl<'tcx> Value<'tcx> for Representability { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -112,7 +131,7 @@ impl<'tcx> Value> for Representability { } } -impl<'tcx> Value> for ty::EarlyBinder<'_, Ty<'_>> { +impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, Ty<'_>> { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -122,7 +141,7 @@ impl<'tcx> Value> for ty::EarlyBinder<'_, Ty<'_>> { } } -impl<'tcx> Value> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { +impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -132,7 +151,7 @@ impl<'tcx> Value> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig< } } -impl<'tcx> Value> for &[ty::Variance] { +impl<'tcx> Value<'tcx> for &[ty::Variance] { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -180,7 +199,7 @@ fn search_for_cycle_permutation( otherwise() } -impl<'tcx, T> Value> for Result> { +impl<'tcx, T> Value<'tcx> for Result> { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: &CycleError, @@ -273,7 +292,7 @@ impl<'tcx, T> Value> for Result> // item_and_field_ids should form a cycle where each field contains the // type in the next element in the list -pub fn recursive_type_error( +fn recursive_type_error( tcx: TyCtxt<'_>, mut item_and_field_ids: Vec<(LocalDefId, LocalDefId)>, representable_ids: &FxHashSet, diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index baa37111c807..44f3da7785f0 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -20,7 +20,7 @@ use rustc_middle::query::AsLocalKey; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; use rustc_middle::ty::TyCtxt; -use rustc_query_system::Value; +use rustc_middle::values::Value; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index d1907a8c582d..3175dbb54bea 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -10,7 +10,5 @@ pub mod dep_graph; mod error; pub mod ich; pub mod query; -mod values; pub use error::{QueryOverflow, QueryOverflowNote}; -pub use values::Value; diff --git a/compiler/rustc_query_system/src/values.rs b/compiler/rustc_query_system/src/values.rs deleted file mode 100644 index 133904f59af1..000000000000 --- a/compiler/rustc_query_system/src/values.rs +++ /dev/null @@ -1,21 +0,0 @@ -use rustc_span::ErrorGuaranteed; - -use crate::dep_graph::DepContext; -use crate::query::CycleError; - -pub trait Value: Sized { - fn from_cycle_error(tcx: Tcx, cycle_error: &CycleError, guar: ErrorGuaranteed) -> Self; -} - -impl Value for T { - default fn from_cycle_error(tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed) -> T { - tcx.sess().dcx().abort_if_errors(); - // Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's - // non-trivial to define it earlier. - panic!( - "<{} as Value>::from_cycle_error called without errors: {:#?}", - std::any::type_name::(), - cycle_error.cycle, - ); - } -} From 7bcb7a281e6cb36d9d87ca28e4d0edbaddaf5eef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Feb 2026 10:38:28 +1100 Subject: [PATCH 63/81] Move `rustc_middle::values` module to `rustc_middle::query::values`. It's a better place for it, because it relates to queries. --- compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 1 + compiler/rustc_middle/src/{ => query}/values.rs | 0 compiler/rustc_query_impl/src/lib.rs | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename compiler/rustc_middle/src/{ => query}/values.rs (100%) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index a21427f6c819..7d1b775cc4bc 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -81,7 +81,6 @@ pub mod thir; pub mod traits; pub mod ty; pub mod util; -pub mod values; #[macro_use] pub mod query; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 24a38e70ff6f..a7707cf48c49 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -13,6 +13,7 @@ mod keys; pub mod on_disk_cache; #[macro_use] pub mod plumbing; +pub mod values; pub fn describe_as_module(def_id: impl Into, tcx: TyCtxt<'_>) -> String { let def_id = def_id.into(); diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/query/values.rs similarity index 100% rename from compiler/rustc_middle/src/values.rs rename to compiler/rustc_middle/src/query/values.rs diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 44f3da7785f0..6c9a075177ad 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -19,8 +19,8 @@ use rustc_middle::queries::{ use rustc_middle::query::AsLocalKey; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; +use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; -use rustc_middle::values::Value; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ From 0932068b6c9330f54eab92d5888131e6c877b3ce Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Feb 2026 16:05:26 +1100 Subject: [PATCH 64/81] Move the `QueryOverflow` and `QueryOverflowNote` errors. They are defined in `rustc_query_system` but used in `rustc_query_impl`. This is very much *not* how things are supposed to be done; I suspect someone got lazy and took a shortcut at some point. This commit moves the errors into `rustc_query_impl`. This requires more lines of code to give `rustc_query_impl` an errors module, but it's worthwhile to do things in the normal way instead of a weird exceptional way. --- Cargo.lock | 2 ++ compiler/rustc_query_impl/Cargo.toml | 2 ++ compiler/rustc_query_impl/src/error.rs | 24 +++++++++++++++++++++++ compiler/rustc_query_impl/src/lib.rs | 2 ++ compiler/rustc_query_impl/src/plumbing.rs | 2 +- compiler/rustc_query_system/src/error.rs | 24 +---------------------- compiler/rustc_query_system/src/lib.rs | 2 -- 7 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 compiler/rustc_query_impl/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 85d3fc1aa7bf..363cb8a5dc05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4534,9 +4534,11 @@ version = "0.0.0" dependencies = [ "measureme", "rustc_data_structures", + "rustc_errors", "rustc_hashes", "rustc_hir", "rustc_index", + "rustc_macros", "rustc_middle", "rustc_query_system", "rustc_serialize", diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 257785b10c8b..d611629671a0 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -7,9 +7,11 @@ edition = "2024" # tidy-alphabetical-start measureme = "12.0.1" rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_query_impl/src/error.rs b/compiler/rustc_query_impl/src/error.rs new file mode 100644 index 000000000000..b109172d8e49 --- /dev/null +++ b/compiler/rustc_query_impl/src/error.rs @@ -0,0 +1,24 @@ +use rustc_hir::limit::Limit; +use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_span::{Span, Symbol}; + +#[derive(Diagnostic)] +#[help( + "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)" +)] +#[diag("queries overflow the depth limit!")] +pub(crate) struct QueryOverflow { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub note: QueryOverflowNote, + pub suggested_limit: Limit, + pub crate_name: Symbol, +} + +#[derive(Subdiagnostic)] +#[note("query depth increased by {$depth} when {$desc}")] +pub(crate) struct QueryOverflowNote { + pub desc: String, + pub depth: usize, +} diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 6c9a075177ad..cb5010861e5f 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -39,6 +39,8 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; +mod error; + #[derive(ConstParamTy)] // Allow this struct to be used for const-generic values. #[derive(Clone, Copy, Debug, PartialEq, Eq)] struct QueryFlags { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b074a9ca11b0..4147de7d2c4d 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -30,11 +30,11 @@ use rustc_query_system::query::{ QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query, }; -use rustc_query_system::{QueryOverflow, QueryOverflowNote}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; use crate::QueryDispatcherUnerased; +use crate::error::{QueryOverflow, QueryOverflowNote}; /// Implements [`QueryContext`] for use by [`rustc_query_system`], since that /// crate does not have direct access to [`TyCtxt`]. diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index 55f2feba0d86..adce85bf31be 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs @@ -1,7 +1,6 @@ use rustc_errors::codes::*; -use rustc_hir::limit::Limit; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_span::{Span, Symbol}; +use rustc_span::Span; #[derive(Subdiagnostic)] #[note("...which requires {$desc}...")] @@ -75,24 +74,3 @@ pub(crate) struct IncrementCompilation { pub run_cmd: String, pub dep_node: String, } - -#[derive(Diagnostic)] -#[help( - "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)" -)] -#[diag("queries overflow the depth limit!")] -pub struct QueryOverflow { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub note: QueryOverflowNote, - pub suggested_limit: Limit, - pub crate_name: Symbol, -} - -#[derive(Subdiagnostic)] -#[note("query depth increased by {$depth} when {$desc}")] -pub struct QueryOverflowNote { - pub desc: String, - pub depth: usize, -} diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 3175dbb54bea..61edf397886b 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -10,5 +10,3 @@ pub mod dep_graph; mod error; pub mod ich; pub mod query; - -pub use error::{QueryOverflow, QueryOverflowNote}; From 0420a2e86405e2abf672046383e556e97b2cfac8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 10:48:39 +1100 Subject: [PATCH 65/81] Remove `Cache::clear`. It's unused. And it's nice to remove this function that didn't behave like normal `clear` does, as the comment explained. --- compiler/rustc_query_system/src/cache.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/compiler/rustc_query_system/src/cache.rs b/compiler/rustc_query_system/src/cache.rs index 1b8332ad9e01..4217d0a49b91 100644 --- a/compiler/rustc_query_system/src/cache.rs +++ b/compiler/rustc_query_system/src/cache.rs @@ -23,13 +23,6 @@ impl Default for Cache { } } -impl Cache { - /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` - pub fn clear(&self) { - *self.hashmap.borrow_mut() = Default::default(); - } -} - impl Cache { pub fn get(&self, key: &Key, tcx: Tcx) -> Option { Some(self.hashmap.borrow().get(key)?.get(tcx)) From aa0ce237b4e67c2481371b2b85475e10b44d33e6 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 8 Jan 2026 13:55:03 +0100 Subject: [PATCH 66/81] c-variadic: minor cleanups of `va_arg` --- compiler/rustc_codegen_llvm/src/va_arg.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index c7da2457ada5..fed0a8837c48 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -131,7 +131,7 @@ fn emit_ptr_va_arg<'ll, 'tcx>( ); if indirect { let tmp_ret = bx.load(llty, addr, addr_align); - bx.load(bx.cx.layout_of(target_ty).llvm_type(bx.cx), tmp_ret, align.abi) + bx.load(layout.llvm_type(bx.cx), tmp_ret, align.abi) } else { bx.load(llty, addr, addr_align) } @@ -1140,13 +1140,10 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), - Arch::Hexagon => { - if target.env == Env::Musl { - emit_hexagon_va_arg_musl(bx, addr, target_ty) - } else { - emit_hexagon_va_arg_bare_metal(bx, addr, target_ty) - } - } + Arch::Hexagon => match target.env { + Env::Musl => emit_hexagon_va_arg_musl(bx, addr, target_ty), + _ => emit_hexagon_va_arg_bare_metal(bx, addr, target_ty), + }, // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction From d2b5ba2ff75106d39e36f1b06c3ff709390821f2 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 8 Jan 2026 14:05:34 +0100 Subject: [PATCH 67/81] c-variadic: make va_arg match on `Arch` exhaustive --- compiler/rustc_codegen_llvm/src/va_arg.rs | 77 ++++++++++++++++++----- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index fed0a8837c48..a491f30fd916 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1007,6 +1007,8 @@ fn emit_xtensa_va_arg<'ll, 'tcx>( /// Determine the va_arg implementation to use. The LLVM va_arg instruction /// is lacking in some instances, so we should only use it as a fallback. +/// +/// pub(super) fn emit_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, addr: OperandRef<'tcx, &'ll Value>, @@ -1015,6 +1017,10 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( let layout = bx.cx.layout_of(target_ty); let target_ty_size = layout.layout.size().bytes(); + // Some ABIs have special behavior for zero-sized types. currently `VaArgSafe` is not + // implemented for any zero-sized types, so this assert should always hold. + assert!(!bx.layout_of(target_ty).is_zst()); + let target = &bx.cx.tcx.sess.target; match target.arch { Arch::X86 => emit_ptr_va_arg( @@ -1026,17 +1032,24 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, ForceRightAdjust::No, ), - Arch::AArch64 | Arch::Arm64EC if target.is_like_windows || target.is_like_darwin => { - emit_ptr_va_arg( - bx, - addr, - target_ty, - PassMode::Direct, - SlotSize::Bytes8, - if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, - ForceRightAdjust::No, - ) - } + Arch::Arm64EC => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes8, + if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, + ForceRightAdjust::No, + ), + Arch::AArch64 if target.is_like_windows || target.is_like_darwin => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes8, + if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, + ForceRightAdjust::No, + ), Arch::AArch64 => emit_aapcs_va_arg(bx, addr, target_ty), Arch::Arm => { // Types wider than 16 bytes are not currently supported. Clang has special logic for @@ -1064,7 +1077,16 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::Yes, ), - Arch::LoongArch32 => emit_ptr_va_arg( + Arch::RiscV32 if target.abi == Abi::Ilp32e => { + // FIXME: clang manually adjusts the alignment for this ABI. It notes: + // + // > To be compatible with GCC's behaviors, we force arguments with + // > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, + // > `unsigned long long` and `double` to have 4-byte alignment. This + // > behavior may be changed when RV32E/ILP32E is ratified. + bug!("c-variadic calls with ilp32e use a custom ABI and are not currently implemented"); + } + Arch::RiscV32 | Arch::LoongArch32 => emit_ptr_va_arg( bx, addr, target_ty, @@ -1073,7 +1095,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::No, ), - Arch::LoongArch64 => emit_ptr_va_arg( + Arch::RiscV64 | Arch::LoongArch64 => emit_ptr_va_arg( bx, addr, target_ty, @@ -1144,9 +1166,30 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( Env::Musl => emit_hexagon_va_arg_musl(bx, addr, target_ty), _ => emit_hexagon_va_arg_bare_metal(bx, addr, target_ty), }, - // For all other architecture/OS combinations fall back to using - // the LLVM va_arg instruction. - // https://llvm.org/docs/LangRef.html#va-arg-instruction - _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)), + Arch::Sparc64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 2 * 8 { PassMode::Indirect } else { PassMode::Direct }, + SlotSize::Bytes8, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + + Arch::Bpf => bug!("bpf does not support c-variadic functions"), + Arch::SpirV => bug!("spirv does not support c-variadic functions"), + + Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { + // FIXME: port MipsTargetLowering::lowerVAARG. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } + Arch::Sparc | Arch::Avr | Arch::M68k | Arch::Msp430 => { + // Clang uses the LLVM implementation for these architectures. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } + Arch::Other(_) => { + // For custom targets, use the LLVM va_arg instruction as a fallback. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } } } From 6970849fee93900b6eb28a64cf957157a9fb51b3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 5 Feb 2026 12:32:07 +1100 Subject: [PATCH 68/81] Disable flaky test `oneshot::recv_timeout_before_send` --- library/std/tests/sync/oneshot.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/tests/sync/oneshot.rs b/library/std/tests/sync/oneshot.rs index 6a87c72b9cb5..8c47f35ebfea 100644 --- a/library/std/tests/sync/oneshot.rs +++ b/library/std/tests/sync/oneshot.rs @@ -127,6 +127,7 @@ fn recv_before_send() { } #[test] +#[ignore = "Inherently flaky and has caused several CI failures"] fn recv_timeout_before_send() { let (sender, receiver) = oneshot::channel(); @@ -135,6 +136,8 @@ fn recv_timeout_before_send() { sender.send(99u128).unwrap(); }); + // FIXME(#152145): Under load, there's no guarantee that thread `t` has + // ever been scheduled and run before this timeout expires. match receiver.recv_timeout(Duration::from_secs(1)) { Ok(99) => {} _ => panic!("expected Ok(99)"), From 8c404a764919b9155c0ac68978185d7db80cc351 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 5 Feb 2026 04:37:12 +0000 Subject: [PATCH 69/81] Prepare for merging from rust-lang/rust This updates the rust-version file to db3e99bbab28c6ca778b13222becdea54533d908. --- library/stdarch/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/rust-version b/library/stdarch/rust-version index ccc0b55d4dc5..aa3876b14a22 100644 --- a/library/stdarch/rust-version +++ b/library/stdarch/rust-version @@ -1 +1 @@ -873d4682c7d285540b8f28bfe637006cef8918a6 +db3e99bbab28c6ca778b13222becdea54533d908 From 438220673f5bde3e4f183b8d2cad753f116b3504 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 5 Feb 2026 15:58:57 +1100 Subject: [PATCH 70/81] Incorporate query description functions into `QueryVTable` --- compiler/rustc_macros/src/query.rs | 9 ++- compiler/rustc_middle/src/query/plumbing.rs | 9 ++- compiler/rustc_query_impl/src/plumbing.rs | 63 ++++++++++----------- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 5d7204f7a30c..adcf4e00241e 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -429,7 +429,14 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { $macro!(#feedable_queries); } } - pub mod descs { + + /// Functions that format a human-readable description of each query + /// and its key, as specified by the `desc` query modifier. + /// + /// (The leading `_` avoids collisions with actual query names when + /// expanded in `rustc_middle::queries`, and makes this macro-generated + /// module easier to search for.) + pub mod _description_fns { use super::*; #query_description_stream } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index b8f1fe9ec20b..abb02caef25d 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -32,7 +32,8 @@ pub type IsLoadableFromDiskFn<'tcx, Key> = /// Stores function pointers and other metadata for a particular query. /// -/// Used indirectly by query plumbing in `rustc_query_system`, via a trait. +/// Used indirectly by query plumbing in `rustc_query_system` via a trait, +/// and also used directly by query plumbing in `rustc_query_impl`. pub struct QueryVTable<'tcx, C: QueryCache> { pub name: &'static str, pub eval_always: bool, @@ -52,6 +53,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> { pub value_from_cycle_error: fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value, pub format_value: fn(&C::Value) -> String, + + /// Formats a human-readable description of this query and its key, as + /// specified by the `desc` query modifier. + /// + /// Used when reporting query cycle errors and similar problems. + pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String, } pub struct QuerySystemFns { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a28bbeccc078..bce685cb9a6a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -9,17 +9,18 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; +use rustc_hir::def_id::DefId; use rustc_hir::limit::Limit; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::dep_graph::{ - self, DepContext, DepKind, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex, - dep_kinds, + self, DepContext, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex, dep_kinds, }; use rustc_middle::query::Key; use rustc_middle::query::on_disk_cache::{ AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex, }; +use rustc_middle::query::plumbing::QueryVTable; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; @@ -312,15 +313,14 @@ macro_rules! should_ever_cache_on_disk { }; } -fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>( - (tcx, key, kind, name, do_describe): ( - TyCtxt<'tcx>, - K, - DepKind, - &'static str, - fn(TyCtxt<'tcx>, K) -> String, - ), -) -> QueryStackFrameExtra { +/// The deferred part of a deferred query stack frame. +fn mk_query_stack_frame_extra<'tcx, Cache>( + (tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key), +) -> QueryStackFrameExtra +where + Cache: QueryCache, + Cache::Key: Key, +{ let def_id = key.key_as_def_id(); // If reduced queries are requested, we may be printing a query stack due @@ -328,13 +328,13 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>( let reduce_queries = with_reduced_queries(); // Avoid calling queries while formatting the description - let description = ty::print::with_no_queries!(do_describe(tcx, key)); + let description = ty::print::with_no_queries!((vtable.description_fn)(tcx, key)); let description = if tcx.sess.verbose_internals() { - format!("{description} [{name:?}]") + format!("{description} [{name:?}]", name = vtable.name) } else { description }; - let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries { + let span = if vtable.dep_kind == dep_graph::dep_kinds::def_span || reduce_queries { // The `def_span` query is used to calculate `default_span`, // so exit to avoid infinite recursion. None @@ -342,7 +342,7 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>( Some(key.default_span(tcx)) }; - let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries { + let def_kind = if vtable.dep_kind == dep_graph::dep_kinds::def_kind || reduce_queries { // Try to avoid infinite recursion. None } else { @@ -351,17 +351,16 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>( QueryStackFrameExtra::new(description, span, def_kind) } -pub(crate) fn create_query_frame< - 'tcx, - K: Copy + DynSend + DynSync + Key + for<'a> HashStable> + 'tcx, ->( +pub(crate) fn create_deferred_query_stack_frame<'tcx, Cache>( tcx: TyCtxt<'tcx>, - do_describe: fn(TyCtxt<'tcx>, K) -> String, - key: K, - kind: DepKind, - name: &'static str, -) -> QueryStackFrame> { - let def_id = key.key_as_def_id(); + vtable: &'tcx QueryVTable<'tcx, Cache>, + key: Cache::Key, +) -> QueryStackFrame> +where + Cache: QueryCache, + Cache::Key: Key + DynSend + DynSync + for<'a> HashStable> + 'tcx, +{ + let kind = vtable.dep_kind; let hash = tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); @@ -369,11 +368,11 @@ pub(crate) fn create_query_frame< key.hash_stable(&mut hcx, &mut hasher); hasher.finish::() }); - let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle(); - let info = - QueryStackDeferred::new((tcx, key, kind, name, do_describe), mk_query_stack_frame_extra); + let def_id: Option = key.key_as_def_id(); + let def_id_for_ty_in_cycle: Option = key.def_id_for_ty_in_cycle(); + let info = QueryStackDeferred::new((tcx, vtable, key), mk_query_stack_frame_extra); QueryStackFrame::new(info, kind, hash, def_id, def_id_for_ty_in_cycle) } @@ -697,6 +696,7 @@ macro_rules! define_queries { }, hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]), format_value: |value| format!("{:?}", erase::restore_val::>(*value)), + description_fn: $crate::queries::_description_fns::$name, } } @@ -742,10 +742,9 @@ macro_rules! define_queries { qmap: &mut QueryMap<'tcx>, require_complete: bool, ) -> Option<()> { - let make_frame = |tcx, key| { - let kind = rustc_middle::dep_graph::dep_kinds::$name; - let name = stringify!($name); - $crate::plumbing::create_query_frame(tcx, queries::descs::$name, key, kind, name) + let make_frame = |tcx: TyCtxt<'tcx>, key| { + let vtable = &tcx.query_system.query_vtables.$name; + $crate::plumbing::create_deferred_query_stack_frame(tcx, vtable, key) }; // Call `gather_active_jobs_inner` to do the actual work. From d40e60fc447e36afc664c69353a0b1e6ab4d2738 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 18:05:19 +0100 Subject: [PATCH 71/81] Convert to inline diagnostics in `rustc_builtin_macros` --- Cargo.lock | 2 - compiler/rustc_builtin_macros/Cargo.toml | 1 - compiler/rustc_builtin_macros/messages.ftl | 320 ------------ .../src/deriving/coerce_pointee.rs | 14 +- compiler/rustc_builtin_macros/src/errors.rs | 490 +++++++++++------- compiler/rustc_builtin_macros/src/lib.rs | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - 8 files changed, 298 insertions(+), 533 deletions(-) delete mode 100644 compiler/rustc_builtin_macros/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 9c98946c9d39..07afb4a27779 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3600,7 +3600,6 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_lexer", @@ -3775,7 +3774,6 @@ dependencies = [ "rustc_ast_passes", "rustc_ast_pretty", "rustc_borrowck", - "rustc_builtin_macros", "rustc_codegen_ssa", "rustc_const_eval", "rustc_data_structures", diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index ce9a3ce3f248..dd84a2c1802d 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -15,7 +15,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl deleted file mode 100644 index f9ffddf79084..000000000000 --- a/compiler/rustc_builtin_macros/messages.ftl +++ /dev/null @@ -1,320 +0,0 @@ -builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function -builtin_macros_alloc_must_statics = allocators must be statics - -builtin_macros_asm_attribute_not_supported = - this attribute is not supported on assembly - -builtin_macros_asm_clobber_abi = clobber_abi -builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs -builtin_macros_asm_clobber_outputs = generic outputs - -builtin_macros_asm_duplicate_arg = duplicate argument named `{$name}` - .label = previously here - .arg = duplicate argument - -builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names - -builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option - -builtin_macros_asm_modifier_invalid = asm template modifier must be a single character - -builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive - -builtin_macros_asm_no_matched_argument_name = there is no argument named `{$name}` - -builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option - -builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided - .label = this option was already provided - .suggestion = remove this option - -builtin_macros_asm_pos_after = positional arguments cannot follow named arguments or explicit register arguments - .pos = positional argument - .named = named argument - .explicit = explicit register argument - -builtin_macros_asm_pure_combine = the `pure` option must be combined with either `nomem` or `readonly` - -builtin_macros_asm_pure_no_output = asm with the `pure` option must have at least one output - -builtin_macros_asm_unsupported_clobber_abi = `clobber_abi` cannot be used with `{$macro_name}!` - -builtin_macros_asm_unsupported_option = the `{$symbol}` option cannot be used with `{$macro_name}!` - .label = the `{$symbol}` option is not meaningful for global-scoped inline assembly - .suggestion = remove this option - -builtin_macros_assert_missing_comma = unexpected string literal - .suggestion = try adding a comma - -builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument - .label = boolean expression required - -builtin_macros_assert_requires_expression = macro requires an expression as an argument - .suggestion = try removing semicolon - -builtin_macros_autodiff = autodiff must be applied to function -builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode -builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode -builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} -builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode -builtin_macros_autodiff_ty_activity = {$act} can not be used for this type -builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` - -builtin_macros_autodiff_width = autodiff width must fit u32, but is {$width} - -builtin_macros_avoid_att_syntax = avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - -builtin_macros_avoid_intel_syntax = avoid using `.intel_syntax`, Intel syntax is the default - -builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s - .label = not applicable here - .label2 = not a `struct`, `enum` or `union` - -builtin_macros_bench_sig = functions used as benches must have signature `fn(&mut Bencher) -> impl Termination` - - -builtin_macros_cannot_derive_union = this trait cannot be derived for unions - -builtin_macros_cfg_accessible_has_args = `cfg_accessible` path cannot accept arguments - -builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path is accessible or not - -builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal -builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified -builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified - -builtin_macros_cfg_select_no_matches = none of the predicates in this `cfg_select` evaluated to true - -builtin_macros_cfg_select_unreachable = unreachable predicate - .label = always matches - .label2 = this predicate is never reached - -builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized` - -builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field - -builtin_macros_coerce_pointee_requires_one_generic = `CoercePointee` can only be derived on `struct`s that are generic over at least one type - -builtin_macros_coerce_pointee_requires_one_pointee = exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits - -builtin_macros_coerce_pointee_requires_transparent = `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` - -builtin_macros_coerce_pointee_too_many_pointees = only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits - .label = here another type parameter is marked as `#[pointee]` - - -builtin_macros_concat_bytes_array = cannot concatenate doubly nested array - .note = byte strings are treated as arrays of bytes - .help = try flattening the array - -builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number - -builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals - .byte_char = try using a byte character - .byte_str = try using a byte string - .c_str = try using a null-terminated byte string - .c_str_note = concatenating C strings is ambiguous about including the '\0' - .number_array = try wrapping the number in an array - -builtin_macros_concat_bytes_missing_literal = expected a byte literal - .note = only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()` - -builtin_macros_concat_bytes_non_u8 = numeric literal is not a `u8` - -builtin_macros_concat_bytes_oob = numeric literal is out of bounds - -builtin_macros_concat_bytestr = cannot concatenate a byte string literal -builtin_macros_concat_c_str_lit = cannot concatenate a C string literal - -builtin_macros_concat_missing_literal = expected a literal - .note = only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()` - -builtin_macros_default_arg = `#[default]` attribute does not accept a value - .suggestion = try using `#[default]` - -builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field - -builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields -> - [true] multiple fields - *[false] no fields -} - -builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind} - -builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros - -builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept arguments - .suggestion = remove the arguments - -builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values - .suggestion = remove the value - -builtin_macros_duplicate_macro_attribute = duplicated attribute - -builtin_macros_eii_declaration_expected_list = `#[eii_declaration(...)]` expects a list of one or two elements -builtin_macros_eii_declaration_expected_macro = `#[eii_declaration(...)]` is only valid on macros -builtin_macros_eii_declaration_expected_unsafe = expected this argument to be "unsafe" - .note = the second argument is optional - -builtin_macros_eii_only_once = `#[{$name}]` can only be specified once - .note = specified again here - -builtin_macros_eii_shared_macro_expected_function = `#[{$name}]` is only valid on functions -builtin_macros_eii_shared_macro_expected_max_one_argument = `#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]` -builtin_macros_eii_shared_macro_in_statement_position = `#[{$name}]` can only be used on functions inside a module - .label = `#[{$name}]` is used on this item, which is part of another item's local scope - -builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time - .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead - .cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}` - .custom = use `std::env::var({$var_expr})` to read the variable at run time - -builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string - -builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments - -builtin_macros_expected_comma_in_list = expected token: `,` - -builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern - -builtin_macros_expected_other = expected operand, {$is_inline_asm -> - [false] options - *[true] clobber_abi, options - }, or additional template string - -builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently - -builtin_macros_format_add_missing_colon = add a colon before the format specifier - -builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}` - .label1 = previously here - .label2 = duplicate argument - -builtin_macros_format_no_arg_named = there is no argument named `{$name}` - .note = did you intend to capture a variable `{$name}` from the surrounding scope? - .note2 = to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro - -builtin_macros_format_pos_mismatch = {$n} positional {$n -> - [one] argument - *[more] arguments - } in format string, but {$desc} - -builtin_macros_format_positional_after_named = positional arguments cannot follow named arguments - .label = positional arguments must be before named arguments - .named_args = named argument - -builtin_macros_format_redundant_args = redundant {$n -> - [one] argument - *[more] arguments - } - .help = {$n -> - [one] the formatting string already captures the binding directly, it doesn't need to be included in the argument list - *[more] the formatting strings already captures the bindings directly, they don't need to be included in the argument list - } - .note = {$n -> - [one] the formatting specifier is referencing the binding already - *[more] the formatting specifiers are referencing the bindings already - } - .suggestion = this can be removed - -builtin_macros_format_remove_raw_ident = remove the `r#` - -builtin_macros_format_reorder_format_parameter = did you mean `{$replacement}`? - -builtin_macros_format_requires_string = requires at least a format string argument - -builtin_macros_format_string_invalid = invalid format string: {$desc} - .label = {$label1} in format string - .note = {$note} - .second_label = {$label} - -builtin_macros_format_unknown_trait = unknown format trait `{$ty}` - .note = the only appropriate formatting traits are: - - ``, which uses the `Display` trait - - `?`, which uses the `Debug` trait - - `e`, which uses the `LowerExp` trait - - `E`, which uses the `UpperExp` trait - - `o`, which uses the `Octal` trait - - `p`, which uses the `Pointer` trait - - `b`, which uses the `Binary` trait - - `x`, which uses the `LowerHex` trait - - `X`, which uses the `UpperHex` trait - .suggestion = use the `{$trait_name}` trait - -builtin_macros_format_unused_arg = {$named -> - [true] named argument - *[false] argument - } never used - -builtin_macros_format_unused_args = multiple unused formatting arguments - .label = multiple missing formatting specifiers - -builtin_macros_format_use_positional = consider using a positional formatting argument instead - -builtin_macros_incomplete_include = include macro expected single expression in source - -builtin_macros_multiple_default_attrs = multiple `#[default]` attributes - .note = only one `#[default]` attribute is needed - .label = `#[default]` used here - .label_again = `#[default]` used again here - .help = try removing {$only_one -> - [true] this - *[false] these - } - -builtin_macros_multiple_defaults = multiple declared defaults - .label = first default - .additional = additional default - .note = only one variant can be default - .suggestion = make `{$ident}` default - -builtin_macros_naked_functions_testing_attribute = - cannot use `#[unsafe(naked)]` with testing attributes - .label = function marked with testing attribute here - .naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes - -builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]` - .label = this enum needs a unit variant marked with `#[default]` - .suggestion = make this unit variant default by placing `#[default]` on it - -builtin_macros_non_exhaustive_default = default variant must be exhaustive - .label = declared `#[non_exhaustive]` here - .help = consider a manual implementation of `Default` - -builtin_macros_non_generic_pointee = the `#[pointee]` attribute may only be used on generic parameters - -builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants{$post} - .help = consider a manual implementation of `Default` - -builtin_macros_only_one_argument = {$name} takes 1 argument - -builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]` - -builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type - -builtin_macros_requires_cfg_pattern = - macro requires a cfg-pattern as an argument - .label = cfg-pattern required - -builtin_macros_source_utils_expected_item = expected item, found `{$token}` - -builtin_macros_takes_no_arguments = {$name} takes no arguments - -builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests - .label = `{$kind}` because of this - -builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items - -builtin_macros_test_runner_invalid = `test_runner` argument must be a path -builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument - -builtin_macros_tests_not_support = building tests with panic=abort is not supported without `-Zpanic_abort_tests` - -builtin_macros_trace_macros = trace_macros! accepts only `true` or `false` - -builtin_macros_unexpected_lit = expected path to a trait, found literal - .label = not a trait - .str_lit = try using `#[derive({$sym})]` - .other = for example, write `#[derive(Debug)]` for `Debug` - -builtin_macros_unnameable_test_items = cannot test inner items diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index d6fdf088b0d1..8984e51c0844 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -463,44 +463,44 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b> } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_transparent, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`", code = E0802)] struct RequireTransparent { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_field, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s with at least one field", code = E0802)] struct RequireOneField { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_generic, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s that are generic over at least one type", code = E0802)] struct RequireOneGeneric { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_pointee, code = E0802)] +#[diag("exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits", code = E0802)] struct RequireOnePointee { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_too_many_pointees, code = E0802)] +#[diag("only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits", code = E0802)] struct TooManyPointees { #[primary_span] one: Span, - #[label] + #[label("here another type parameter is marked as `#[pointee]`")] another: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_maybe_sized, code = E0802)] +#[diag("`derive(CoercePointee)` requires `{$name}` to be marked `?Sized`", code = E0802)] struct RequiresMaybeSized { #[primary_span] span: Span, diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 0aaa8cf558c4..d3f7e1c5d8e3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1,150 +1,157 @@ use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans, - Subdiagnostic, + Subdiagnostic, inline_fluent, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; #[derive(LintDiagnostic)] -#[diag(builtin_macros_avoid_intel_syntax)] +#[diag("avoid using `.intel_syntax`, Intel syntax is the default")] pub(crate) struct AvoidIntelSyntax; #[derive(LintDiagnostic)] -#[diag(builtin_macros_avoid_att_syntax)] +#[diag("avoid using `.att_syntax`, prefer using `options(att_syntax)` instead")] pub(crate) struct AvoidAttSyntax; #[derive(LintDiagnostic)] -#[diag(builtin_macros_incomplete_include)] +#[diag("include macro expected single expression in source")] pub(crate) struct IncompleteInclude; #[derive(LintDiagnostic)] -#[diag(builtin_macros_unnameable_test_items)] +#[diag("cannot test inner items")] pub(crate) struct UnnameableTestItems; #[derive(LintDiagnostic)] -#[diag(builtin_macros_duplicate_macro_attribute)] +#[diag("duplicated attribute")] pub(crate) struct DuplicateMacroAttribute; #[derive(Diagnostic)] -#[diag(builtin_macros_requires_cfg_pattern)] +#[diag("macro requires a cfg-pattern as an argument")] pub(crate) struct RequiresCfgPattern { #[primary_span] - #[label] + #[label("cfg-pattern required")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_expected_one_cfg_pattern)] +#[diag("expected 1 cfg-pattern")] pub(crate) struct OneCfgPattern { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_alloc_error_must_be_fn)] +#[diag("alloc_error_handler must be a function")] pub(crate) struct AllocErrorMustBeFn { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_requires_boolean)] +#[diag("macro requires a boolean expression as an argument")] pub(crate) struct AssertRequiresBoolean { #[primary_span] - #[label] + #[label("boolean expression required")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_requires_expression)] +#[diag("macro requires an expression as an argument")] pub(crate) struct AssertRequiresExpression { #[primary_span] pub(crate) span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[suggestion("try removing semicolon", code = "", applicability = "maybe-incorrect")] pub(crate) token: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_missing_comma)] +#[diag("unexpected string literal")] pub(crate) struct AssertMissingComma { #[primary_span] pub(crate) span: Span, - #[suggestion(code = ", ", applicability = "maybe-incorrect", style = "short")] + #[suggestion( + "try adding a comma", + code = ", ", + applicability = "maybe-incorrect", + style = "short" + )] pub(crate) comma: Span, } #[derive(Diagnostic)] pub(crate) enum CfgAccessibleInvalid { - #[diag(builtin_macros_cfg_accessible_unspecified_path)] + #[diag("`cfg_accessible` path is not specified")] UnspecifiedPath(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_multiple_paths)] + #[diag("multiple `cfg_accessible` paths are specified")] MultiplePaths(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_literal_path)] + #[diag("`cfg_accessible` path cannot be a literal")] LiteralPath(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_has_args)] + #[diag("`cfg_accessible` path cannot accept arguments")] HasArguments(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_accessible_indeterminate)] +#[diag("cannot determine whether the path is accessible or not")] pub(crate) struct CfgAccessibleIndeterminate { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_missing_literal)] -#[note] +#[diag("expected a literal")] +#[note("only literals (like `\"foo\"`, `-42` and `3.14`) can be passed to `concat!()`")] pub(crate) struct ConcatMissingLiteral { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytestr)] +#[diag("cannot concatenate a byte string literal")] pub(crate) struct ConcatBytestr { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_c_str_lit)] +#[diag("cannot concatenate a C string literal")] pub(crate) struct ConcatCStrLit { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_export_macro_rules)] +#[diag("cannot export macro_rules! macros from a `proc-macro` crate type currently")] pub(crate) struct ExportMacroRules { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_proc_macro)] +#[diag( + "`proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`" +)] pub(crate) struct ProcMacro { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_trace_macros)] +#[diag("trace_macros! accepts only `true` or `false`")] pub(crate) struct TraceMacros { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_bench_sig)] +#[diag("functions used as benches must have signature `fn(&mut Bencher) -> impl Termination`")] pub(crate) struct BenchSig { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_alloc_must_statics)] +#[diag("allocators must be statics")] pub(crate) struct AllocMustStatics { #[primary_span] pub(crate) span: Span, @@ -155,27 +162,27 @@ pub(crate) use autodiff::*; mod autodiff { use super::*; #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_missing_config)] + #[diag("autodiff requires at least a name and mode")] pub(crate) struct AutoDiffMissingConfig { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_unknown_activity)] + #[diag("did not recognize Activity: `{$act}`")] pub(crate) struct AutoDiffUnknownActivity { #[primary_span] pub(crate) span: Span, pub(crate) act: String, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_ty_activity)] + #[diag("{$act} can not be used for this type")] pub(crate) struct AutoDiffInvalidTypeForActivity { #[primary_span] pub(crate) span: Span, pub(crate) act: String, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_number_activities)] + #[diag("expected {$expected} activities, but found {$found}")] pub(crate) struct AutoDiffInvalidNumberActivities { #[primary_span] pub(crate) span: Span, @@ -183,7 +190,7 @@ mod autodiff { pub(crate) found: usize, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_mode_activity)] + #[diag("{$act} can not be used in {$mode} Mode")] pub(crate) struct AutoDiffInvalidApplicationModeAct { #[primary_span] pub(crate) span: Span, @@ -192,7 +199,7 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_ret_activity)] + #[diag("invalid return activity {$act} in {$mode} Mode")] pub(crate) struct AutoDiffInvalidRetAct { #[primary_span] pub(crate) span: Span, @@ -201,7 +208,7 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_width)] + #[diag("autodiff width must fit u32, but is {$width}")] pub(crate) struct AutoDiffInvalidWidth { #[primary_span] pub(crate) span: Span, @@ -209,7 +216,7 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff)] + #[diag("autodiff must be applied to function")] pub(crate) struct AutoDiffInvalidApplication { #[primary_span] pub(crate) span: Span, @@ -217,21 +224,21 @@ mod autodiff { } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_invalid)] +#[diag("cannot concatenate {$lit_kind} literals")] pub(crate) struct ConcatBytesInvalid { #[primary_span] pub(crate) span: Span, pub(crate) lit_kind: &'static str, #[subdiagnostic] pub(crate) sugg: Option, - #[note(builtin_macros_c_str_note)] + #[note("concatenating C strings is ambiguous about including the '\\0'")] pub(crate) cs_note: Option<()>, } #[derive(Subdiagnostic)] pub(crate) enum ConcatBytesInvalidSuggestion { #[suggestion( - builtin_macros_byte_char, + "try using a byte character", code = "b{snippet}", applicability = "machine-applicable" )] @@ -241,7 +248,7 @@ pub(crate) enum ConcatBytesInvalidSuggestion { snippet: String, }, #[suggestion( - builtin_macros_byte_str, + "try using a byte string", code = "b{snippet}", applicability = "machine-applicable" )] @@ -250,15 +257,19 @@ pub(crate) enum ConcatBytesInvalidSuggestion { span: Span, snippet: String, }, - #[note(builtin_macros_c_str_note)] - #[suggestion(builtin_macros_c_str, code = "{as_bstr}", applicability = "machine-applicable")] + #[note("concatenating C strings is ambiguous about including the '\\0'")] + #[suggestion( + "try using a null-terminated byte string", + code = "{as_bstr}", + applicability = "machine-applicable" + )] CStrLit { #[primary_span] span: Span, as_bstr: String, }, #[suggestion( - builtin_macros_number_array, + "try wrapping the number in an array", code = "[{snippet}]", applicability = "machine-applicable" )] @@ -270,63 +281,65 @@ pub(crate) enum ConcatBytesInvalidSuggestion { } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_oob)] +#[diag("numeric literal is out of bounds")] pub(crate) struct ConcatBytesOob { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_non_u8)] +#[diag("numeric literal is not a `u8`")] pub(crate) struct ConcatBytesNonU8 { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_missing_literal)] -#[note] +#[diag("expected a byte literal")] +#[note( + "only byte literals (like `b\"foo\"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`" +)] pub(crate) struct ConcatBytesMissingLiteral { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_array)] +#[diag("cannot concatenate doubly nested array")] pub(crate) struct ConcatBytesArray { #[primary_span] pub(crate) span: Span, - #[note] - #[help] + #[note("byte strings are treated as arrays of bytes")] + #[help("try flattening the array")] pub(crate) bytestr: bool, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_bad_repeat)] +#[diag("repeat count is not a positive number")] pub(crate) struct ConcatBytesBadRepeat { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_bad_derive_target, code = E0774)] +#[diag("`derive` may only be applied to `struct`s, `enum`s and `union`s", code = E0774)] pub(crate) struct BadDeriveTarget { #[primary_span] - #[label] + #[label("not applicable here")] pub(crate) span: Span, - #[label(builtin_macros_label2)] + #[label("not a `struct`, `enum` or `union`")] pub(crate) item: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_tests_not_support)] +#[diag("building tests with panic=abort is not supported without `-Zpanic_abort_tests`")] pub(crate) struct TestsNotSupport {} #[derive(Diagnostic)] -#[diag(builtin_macros_unexpected_lit, code = E0777)] +#[diag("expected path to a trait, found literal", code = E0777)] pub(crate) struct BadDeriveLit { #[primary_span] - #[label] + #[label("not a trait")] pub(crate) span: Span, #[subdiagnostic] pub help: BadDeriveLitHelp, @@ -334,55 +347,59 @@ pub(crate) struct BadDeriveLit { #[derive(Subdiagnostic)] pub(crate) enum BadDeriveLitHelp { - #[help(builtin_macros_str_lit)] + #[help("try using `#[derive({$sym})]`")] StrLit { sym: Symbol }, - #[help(builtin_macros_other)] + #[help("for example, write `#[derive(Debug)]` for `Debug`")] Other, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_path_args_list)] +#[diag("traits in `#[derive(...)]` don't accept arguments")] pub(crate) struct DerivePathArgsList { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the arguments", code = "", applicability = "machine-applicable")] #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_path_args_value)] +#[diag("traits in `#[derive(...)]` don't accept values")] pub(crate) struct DerivePathArgsValue { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the value", code = "", applicability = "machine-applicable")] #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_no_default_variant, code = E0665)] +#[diag("`#[derive(Default)]` on enum with no `#[default]`", code = E0665)] pub(crate) struct NoDefaultVariant { #[primary_span] pub(crate) span: Span, - #[label] + #[label("this enum needs a unit variant marked with `#[default]`")] pub(crate) item_span: Span, #[subdiagnostic] pub(crate) suggs: Vec, } #[derive(Subdiagnostic)] -#[suggestion(builtin_macros_suggestion, code = "#[default] ", applicability = "maybe-incorrect")] +#[suggestion( + "make this unit variant default by placing `#[default]` on it", + code = "#[default] ", + applicability = "maybe-incorrect" +)] pub(crate) struct NoDefaultVariantSugg { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_multiple_defaults)] -#[note] +#[diag("multiple declared defaults")] +#[note("only one variant can be default")] pub(crate) struct MultipleDefaults { #[primary_span] pub(crate) span: Span, - #[label] + #[label("first default")] pub(crate) first: Span, - #[label(builtin_macros_additional)] + #[label("additional default")] pub additional: Vec, #[subdiagnostic] pub suggs: Vec, @@ -390,7 +407,7 @@ pub(crate) struct MultipleDefaults { #[derive(Subdiagnostic)] #[multipart_suggestion( - builtin_macros_suggestion, + "make `{$ident}` default", applicability = "maybe-incorrect", style = "tool-only" )] @@ -401,8 +418,8 @@ pub(crate) struct MultipleDefaultsSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_non_unit_default)] -#[help] +#[diag("the `#[default]` attribute may only be used on unit enum variants{$post}")] +#[help("consider a manual implementation of `Default`")] pub(crate) struct NonUnitDefault { #[primary_span] pub(crate) span: Span, @@ -410,26 +427,31 @@ pub(crate) struct NonUnitDefault { } #[derive(Diagnostic)] -#[diag(builtin_macros_non_exhaustive_default)] -#[help] +#[diag("default variant must be exhaustive")] +#[help("consider a manual implementation of `Default`")] pub(crate) struct NonExhaustiveDefault { #[primary_span] pub(crate) span: Span, - #[label] + #[label("declared `#[non_exhaustive]` here")] pub(crate) non_exhaustive: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_multiple_default_attrs)] -#[note] +#[diag("multiple `#[default]` attributes")] +#[note("only one `#[default]` attribute is needed")] pub(crate) struct MultipleDefaultAttrs { #[primary_span] pub(crate) span: Span, - #[label] + #[label("`#[default]` used here")] pub(crate) first: Span, - #[label(builtin_macros_label_again)] + #[label("`#[default]` used again here")] pub(crate) first_rest: Span, - #[help] + #[help( + "try removing {$only_one -> + [true] this + *[false] these + }" + )] pub(crate) rest: MultiSpan, pub(crate) only_one: bool, #[subdiagnostic] @@ -438,7 +460,7 @@ pub(crate) struct MultipleDefaultAttrs { #[derive(Subdiagnostic)] #[multipart_suggestion( - builtin_macros_help, + "consider a manual implementation of `Default`", applicability = "machine-applicable", style = "tool-only" )] @@ -448,16 +470,21 @@ pub(crate) struct MultipleDefaultAttrsSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_default_arg)] +#[diag("`#[default]` attribute does not accept a value")] pub(crate) struct DefaultHasArg { #[primary_span] - #[suggestion(code = "#[default]", style = "hidden", applicability = "maybe-incorrect")] + #[suggestion( + "try using `#[default]`", + code = "#[default]", + style = "hidden", + applicability = "maybe-incorrect" + )] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_from_wrong_target)] -#[note(builtin_macros_derive_from_usage_note)] +#[diag("`#[derive(From)]` used on {$kind}")] +#[note("`#[derive(From)]` can only be used on structs with exactly one field")] pub(crate) struct DeriveFromWrongTarget<'a> { #[primary_span] pub(crate) span: MultiSpan, @@ -465,8 +492,13 @@ pub(crate) struct DeriveFromWrongTarget<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_from_wrong_field_count)] -#[note(builtin_macros_derive_from_usage_note)] +#[diag( + "`#[derive(From)]` used on a struct with {$multiple_fields -> + [true] multiple fields + *[false] no fields + }" +)] +#[note("`#[derive(From)]` can only be used on structs with exactly one field")] pub(crate) struct DeriveFromWrongFieldCount { #[primary_span] pub(crate) span: MultiSpan, @@ -474,21 +506,21 @@ pub(crate) struct DeriveFromWrongFieldCount { } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_macro_call)] +#[diag("`derive` cannot be used on items with type macros")] pub(crate) struct DeriveMacroCall { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_cannot_derive_union)] +#[diag("this trait cannot be derived for unions")] pub(crate) struct DeriveUnion { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_env_takes_args)] +#[diag("`env!()` takes 1 or 2 arguments")] pub(crate) struct EnvTakesArgs { #[primary_span] pub(crate) span: Span, @@ -511,24 +543,26 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessag #[derive(Diagnostic)] pub(crate) enum EnvNotDefined<'a> { - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_cargo)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help( + "Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead" + )] CargoEnvVar { #[primary_span] span: Span, var: Symbol, var_expr: &'a rustc_ast::Expr, }, - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_cargo_typo)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help("there is a similar Cargo environment variable: `{$suggested_var}`")] CargoEnvVarTypo { #[primary_span] span: Span, var: Symbol, suggested_var: Symbol, }, - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_custom)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help("use `std::env::var({$var_expr})` to read the variable at run time")] CustomEnvVar { #[primary_span] span: Span, @@ -538,7 +572,7 @@ pub(crate) enum EnvNotDefined<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_env_not_unicode)] +#[diag("environment variable `{$var}` is not a valid Unicode string")] pub(crate) struct EnvNotUnicode { #[primary_span] pub(crate) span: Span, @@ -546,39 +580,39 @@ pub(crate) struct EnvNotUnicode { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_requires_string)] +#[diag("requires at least a format string argument")] pub(crate) struct FormatRequiresString { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_duplicate_arg)] +#[diag("duplicate argument named `{$ident}`")] pub(crate) struct FormatDuplicateArg { #[primary_span] pub(crate) span: Span, - #[label(builtin_macros_label1)] + #[label("previously here")] pub(crate) prev: Span, - #[label(builtin_macros_label2)] + #[label("duplicate argument")] pub(crate) duplicate: Span, pub(crate) ident: Ident, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_positional_after_named)] +#[diag("positional arguments cannot follow named arguments")] pub(crate) struct PositionalAfterNamed { #[primary_span] - #[label] + #[label("positional arguments must be before named arguments")] pub(crate) span: Span, - #[label(builtin_macros_named_args)] + #[label("named argument")] pub(crate) args: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_string_invalid)] +#[diag("invalid format string: {$desc}")] pub(crate) struct InvalidFormatString { #[primary_span] - #[label] + #[label("{$label1} in format string")] pub(crate) span: Span, pub(crate) desc: String, pub(crate) label1: String, @@ -591,13 +625,13 @@ pub(crate) struct InvalidFormatString { } #[derive(Subdiagnostic)] -#[note(builtin_macros_note)] +#[note("{$note}")] pub(crate) struct InvalidFormatStringNote { pub(crate) note: String, } #[derive(Subdiagnostic)] -#[label(builtin_macros_second_label)] +#[label("{$label}")] pub(crate) struct InvalidFormatStringLabel { #[primary_span] pub(crate) span: Span, @@ -607,7 +641,7 @@ pub(crate) struct InvalidFormatStringLabel { #[derive(Subdiagnostic)] pub(crate) enum InvalidFormatStringSuggestion { #[multipart_suggestion( - builtin_macros_format_use_positional, + "consider using a positional formatting argument instead", style = "verbose", applicability = "machine-applicable" )] @@ -619,17 +653,13 @@ pub(crate) enum InvalidFormatStringSuggestion { span: Span, arg: String, }, - #[suggestion( - builtin_macros_format_remove_raw_ident, - code = "", - applicability = "machine-applicable" - )] + #[suggestion("remove the `r#`", code = "", applicability = "machine-applicable")] RemoveRawIdent { #[primary_span] span: Span, }, #[suggestion( - builtin_macros_format_reorder_format_parameter, + "did you mean `{$replacement}`?", code = "{replacement}", style = "verbose", applicability = "machine-applicable" @@ -640,7 +670,7 @@ pub(crate) enum InvalidFormatStringSuggestion { replacement: String, }, #[suggestion( - builtin_macros_format_add_missing_colon, + "add a colon before the format specifier", code = ":?", applicability = "machine-applicable" )] @@ -651,9 +681,11 @@ pub(crate) enum InvalidFormatStringSuggestion { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_no_arg_named)] -#[note] -#[note(builtin_macros_note2)] +#[diag("there is no argument named `{$name}`")] +#[note("did you intend to capture a variable `{$name}` from the surrounding scope?")] +#[note( + "to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro" +)] pub(crate) struct FormatNoArgNamed { #[primary_span] pub(crate) span: Span, @@ -661,8 +693,19 @@ pub(crate) struct FormatNoArgNamed { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unknown_trait)] -#[note] +#[diag("unknown format trait `{$ty}`")] +#[note( + "the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait" +)] pub(crate) struct FormatUnknownTrait<'a> { #[primary_span] pub(crate) span: Span, @@ -673,7 +716,7 @@ pub(crate) struct FormatUnknownTrait<'a> { #[derive(Subdiagnostic)] #[suggestion( - builtin_macros_suggestion, + "use the `{$trait_name}` trait", code = "{fmt}", style = "tool-only", applicability = "maybe-incorrect" @@ -686,10 +729,20 @@ pub(crate) struct FormatUnknownTraitSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unused_arg)] +#[diag( + "{$named -> + [true] named argument + *[false] argument + } never used" +)] pub(crate) struct FormatUnusedArg { #[primary_span] - #[label(builtin_macros_format_unused_arg)] + #[label( + "{$named -> + [true] named argument + *[false] argument + } never used" + )] pub(crate) span: Span, pub(crate) named: bool, } @@ -699,25 +752,35 @@ pub(crate) struct FormatUnusedArg { impl Subdiagnostic for FormatUnusedArg { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.arg("named", self.named); - let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg); + let msg = diag.eagerly_translate(inline_fluent!( + "{$named -> + [true] named argument + *[false] argument + } never used" + )); diag.remove_arg("named"); diag.span_label(self.span, msg); } } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unused_args)] +#[diag("multiple unused formatting arguments")] pub(crate) struct FormatUnusedArgs { #[primary_span] pub(crate) unused: Vec, - #[label] + #[label("multiple missing formatting specifiers")] pub(crate) fmt: Span, #[subdiagnostic] pub(crate) unused_labels: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_pos_mismatch)] +#[diag( + "{$n} positional {$n -> + [one] argument + *[more] arguments + } in format string, but {$desc}" +)] pub(crate) struct FormatPositionalMismatch { #[primary_span] pub(crate) span: MultiSpan, @@ -728,13 +791,23 @@ pub(crate) struct FormatPositionalMismatch { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_redundant_args)] +#[diag( + "redundant {$n -> + [one] argument + *[more] arguments + }" +)] pub(crate) struct FormatRedundantArgs { #[primary_span] pub(crate) span: MultiSpan, pub(crate) n: usize, - #[note] + #[note( + "{$n -> + [one] the formatting specifier is referencing the binding already + *[more] the formatting specifiers are referencing the bindings already + }" + )] pub(crate) note: MultiSpan, #[subdiagnostic] @@ -742,38 +815,38 @@ pub(crate) struct FormatRedundantArgs { } #[derive(Subdiagnostic)] -#[multipart_suggestion(builtin_macros_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("this can be removed", applicability = "machine-applicable")] pub(crate) struct FormatRedundantArgsSugg { #[suggestion_part(code = "")] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_test_case_non_item)] +#[diag("`#[test_case]` attribute is only allowed on items")] pub(crate) struct TestCaseNonItem { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_test_bad_fn)] +#[diag("{$kind} functions cannot be used for tests")] pub(crate) struct TestBadFn { #[primary_span] pub(crate) span: Span, - #[label] + #[label("`{$kind}` because of this")] pub(crate) cause: Span, pub(crate) kind: &'static str, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_explicit_register_name)] +#[diag("explicit register arguments cannot have names")] pub(crate) struct AsmExplicitRegisterName { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_mutually_exclusive)] +#[diag("the `{$opt1}` and `{$opt2}` options are mutually exclusive")] pub(crate) struct AsmMutuallyExclusive { #[primary_span] pub(crate) spans: Vec, @@ -782,65 +855,65 @@ pub(crate) struct AsmMutuallyExclusive { } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pure_combine)] +#[diag("the `pure` option must be combined with either `nomem` or `readonly`")] pub(crate) struct AsmPureCombine { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pure_no_output)] +#[diag("asm with the `pure` option must have at least one output")] pub(crate) struct AsmPureNoOutput { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_modifier_invalid)] +#[diag("asm template modifier must be a single character")] pub(crate) struct AsmModifierInvalid { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_attribute_not_supported)] +#[diag("this attribute is not supported on assembly")] pub(crate) struct AsmAttributeNotSupported { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_duplicate_arg)] +#[diag("duplicate argument named `{$name}`")] pub(crate) struct AsmDuplicateArg { #[primary_span] - #[label(builtin_macros_arg)] + #[label("duplicate argument")] pub(crate) span: Span, - #[label] + #[label("previously here")] pub(crate) prev: Span, pub(crate) name: Symbol, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pos_after)] +#[diag("positional arguments cannot follow named arguments or explicit register arguments")] pub(crate) struct AsmPositionalAfter { #[primary_span] - #[label(builtin_macros_pos)] + #[label("positional argument")] pub(crate) span: Span, - #[label(builtin_macros_named)] + #[label("named argument")] pub(crate) named: Vec, - #[label(builtin_macros_explicit)] + #[label("explicit register argument")] pub(crate) explicit: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_noreturn)] +#[diag("asm outputs are not allowed with the `noreturn` option")] pub(crate) struct AsmNoReturn { #[primary_span] pub(crate) outputs_sp: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_no_matched_argument_name)] +#[diag("there is no argument named `{$name}`")] pub(crate) struct AsmNoMatchedArgumentName { pub(crate) name: String, #[primary_span] @@ -848,7 +921,7 @@ pub(crate) struct AsmNoMatchedArgumentName { } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_mayunwind)] +#[diag("asm labels are not allowed with the `may_unwind` option")] pub(crate) struct AsmMayUnwind { #[primary_span] pub(crate) labels_sp: Vec, @@ -862,46 +935,55 @@ pub(crate) struct AsmClobberNoReg { impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AsmClobberNoReg { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { // eager translation as `span_labels` takes `AsRef` - let lbl1 = dcx.eagerly_translate_to_string( - crate::fluent_generated::builtin_macros_asm_clobber_abi, - [].into_iter(), - ); - let lbl2 = dcx.eagerly_translate_to_string( - crate::fluent_generated::builtin_macros_asm_clobber_outputs, - [].into_iter(), - ); - Diag::new(dcx, level, crate::fluent_generated::builtin_macros_asm_clobber_no_reg) - .with_span(self.spans.clone()) - .with_span_labels(self.clobbers, &lbl1) - .with_span_labels(self.spans, &lbl2) + let lbl1 = dcx.eagerly_translate_to_string(inline_fluent!("clobber_abi"), [].into_iter()); + let lbl2 = + dcx.eagerly_translate_to_string(inline_fluent!("generic outputs"), [].into_iter()); + Diag::new( + dcx, + level, + inline_fluent!("asm with `clobber_abi` must specify explicit registers for outputs"), + ) + .with_span(self.spans.clone()) + .with_span_labels(self.clobbers, &lbl1) + .with_span_labels(self.spans, &lbl2) } } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_opt_already_provided)] +#[diag("the `{$symbol}` option was already provided")] pub(crate) struct AsmOptAlreadyprovided { #[primary_span] - #[label] + #[label("this option was already provided")] pub(crate) span: Span, pub(crate) symbol: Symbol, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove this option", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub(crate) span_with_comma: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_unsupported_option)] +#[diag("the `{$symbol}` option cannot be used with `{$macro_name}!`")] pub(crate) struct AsmUnsupportedOption { #[primary_span] - #[label] + #[label("the `{$symbol}` option is not meaningful for global-scoped inline assembly")] pub(crate) span: Span, pub(crate) symbol: Symbol, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove this option", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub(crate) span_with_comma: Span, pub(crate) macro_name: &'static str, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_unsupported_clobber_abi)] +#[diag("`clobber_abi` cannot be used with `{$macro_name}!`")] pub(crate) struct AsmUnsupportedClobberAbi { #[primary_span] pub(crate) spans: Vec, @@ -909,28 +991,28 @@ pub(crate) struct AsmUnsupportedClobberAbi { } #[derive(Diagnostic)] -#[diag(builtin_macros_test_runner_invalid)] +#[diag("`test_runner` argument must be a path")] pub(crate) struct TestRunnerInvalid { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_test_runner_nargs)] +#[diag("`#![test_runner(..)]` accepts exactly 1 argument")] pub(crate) struct TestRunnerNargs { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_expected_comma_in_list)] +#[diag("expected token: `,`")] pub(crate) struct ExpectedCommaInList { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_only_one_argument)] +#[diag("{$name} takes 1 argument")] pub(crate) struct OnlyOneArgument<'a> { #[primary_span] pub span: Span, @@ -938,7 +1020,7 @@ pub(crate) struct OnlyOneArgument<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_takes_no_arguments)] +#[diag("{$name} takes no arguments")] pub(crate) struct TakesNoArguments<'a> { #[primary_span] pub span: Span, @@ -946,7 +1028,7 @@ pub(crate) struct TakesNoArguments<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)] +#[diag("the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type")] pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { #[primary_span] pub span: Span, @@ -954,7 +1036,7 @@ pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_source_utils_expected_item)] +#[diag("expected item, found `{$token}`")] pub(crate) struct ExpectedItem<'a> { #[primary_span] pub span: Span, @@ -962,73 +1044,83 @@ pub(crate) struct ExpectedItem<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)] +#[diag("cannot use `#[unsafe(naked)]` with testing attributes", code = E0736)] pub(crate) struct NakedFunctionTestingAttribute { #[primary_span] - #[label(builtin_macros_naked_attribute)] + #[label("`#[unsafe(naked)]` is incompatible with testing attributes")] pub naked_span: Span, - #[label] + #[label("function marked with testing attribute here")] pub testing_span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_non_generic_pointee)] +#[diag("the `#[pointee]` attribute may only be used on generic parameters")] pub(crate) struct NonGenericPointee { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_expected_other)] +#[diag( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" +)] pub(crate) struct AsmExpectedOther { #[primary_span] - #[label(builtin_macros_expected_other)] + #[label( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" + )] pub(crate) span: Span, pub(crate) is_inline_asm: bool, } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_select_no_matches)] +#[diag("none of the predicates in this `cfg_select` evaluated to true")] pub(crate) struct CfgSelectNoMatches { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_select_unreachable)] +#[diag("unreachable predicate")] pub(crate) struct CfgSelectUnreachable { #[primary_span] - #[label(builtin_macros_label2)] + #[label("this predicate is never reached")] pub span: Span, - #[label] + #[label("always matches")] pub wildcard_span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_declaration_expected_macro)] +#[diag("`#[eii_declaration(...)]` is only valid on macros")] pub(crate) struct EiiExternTargetExpectedMacro { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_declaration_expected_list)] +#[diag("`#[eii_declaration(...)]` expects a list of one or two elements")] pub(crate) struct EiiExternTargetExpectedList { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_declaration_expected_unsafe)] +#[diag("expected this argument to be \"unsafe\"")] pub(crate) struct EiiExternTargetExpectedUnsafe { #[primary_span] - #[note] + #[note("the second argument is optional")] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_shared_macro_expected_function)] +#[diag("`#[{$name}]` is only valid on functions")] pub(crate) struct EiiSharedMacroExpectedFunction { #[primary_span] pub span: Span, @@ -1036,27 +1128,27 @@ pub(crate) struct EiiSharedMacroExpectedFunction { } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_shared_macro_in_statement_position)] +#[diag("`#[{$name}]` can only be used on functions inside a module")] pub(crate) struct EiiSharedMacroInStatementPosition { #[primary_span] pub span: Span, pub name: String, - #[label] + #[label("`#[{$name}]` is used on this item, which is part of another item's local scope")] pub item_span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_only_once)] +#[diag("`#[{$name}]` can only be specified once")] pub(crate) struct EiiOnlyOnce { #[primary_span] pub span: Span, - #[note] + #[note("specified again here")] pub first_span: Span, pub name: String, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_shared_macro_expected_max_one_argument)] +#[diag("`#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]`")] pub(crate) struct EiiMacroExpectedMaxOneArgument { #[primary_span] pub span: Span, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 120e3f849ff6..8ac15ceb4bbe 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -57,8 +57,6 @@ pub mod standard_library_imports; pub mod test_harness; pub mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index c24a4ca53219..e7b266552f4f 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -12,7 +12,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_borrowck = { path = "../rustc_borrowck" } -rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_const_eval = { path = "../rustc_const_eval" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 02298dbf8267..9dbdfb141fc1 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -116,7 +116,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ // tidy-alphabetical-start rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, - rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, rustc_const_eval::DEFAULT_LOCALE_RESOURCE, rustc_errors::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, From 46753b1b4330683096345638011077f117f80099 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 17:48:13 +0100 Subject: [PATCH 72/81] Convert to inline diagnostics in `rustc_middle` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/messages.ftl | 133 ------------------ compiler/rustc_middle/src/error.rs | 66 +++++---- compiler/rustc_middle/src/lib.rs | 2 - compiler/rustc_middle/src/middle/stability.rs | 19 ++- compiler/rustc_middle/src/mir/terminator.rs | 55 +++++--- compiler/rustc_middle/src/ty/layout.rs | 28 ++-- 9 files changed, 103 insertions(+), 203 deletions(-) delete mode 100644 compiler/rustc_middle/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 9c98946c9d39..a87921056331 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4262,7 +4262,6 @@ dependencies = [ "rustc_error_messages", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_graphviz", "rustc_hashes", "rustc_hir", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 02298dbf8267..d15121614693 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -121,7 +121,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_errors::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, - rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index fbcce16cedca..f9d5e7c02789 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -18,7 +18,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl deleted file mode 100644 index b46f43841c8e..000000000000 --- a/compiler/rustc_middle/messages.ftl +++ /dev/null @@ -1,133 +0,0 @@ -middle_assert_async_resume_after_drop = `async fn` resumed after async drop - -middle_assert_async_resume_after_panic = `async fn` resumed after panicking - -middle_assert_async_resume_after_return = `async fn` resumed after completion - -middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop - -middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking - -middle_assert_coroutine_resume_after_return = coroutine resumed after completion - -middle_assert_divide_by_zero = - attempt to divide `{$val}` by zero - -middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped - -middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked - -middle_assert_invalid_enum_construction = - trying to construct an enum from an invalid value `{$source}` - -middle_assert_misaligned_ptr_deref = - misaligned pointer dereference: address must be a multiple of {$required} but is {$found} - -middle_assert_null_ptr_deref = - null pointer dereference occurred - -middle_assert_op_overflow = - attempt to compute `{$left} {$op} {$right}`, which would overflow - -middle_assert_overflow_neg = - attempt to negate `{$val}`, which would overflow - -middle_assert_remainder_by_zero = - attempt to calculate the remainder of `{$val}` with a divisor of zero - -middle_assert_shl_overflow = - attempt to shift left by `{$val}`, which would overflow - -middle_assert_shr_overflow = - attempt to shift right by `{$val}`, which would overflow - -middle_autodiff_unsafe_inner_const_ref = reading from a `Duplicated` const {$ty} is unsafe - -middle_bounds_check = - index out of bounds: the length is {$len} but the index is {$index} - -middle_conflict_types = - this expression supplies two conflicting concrete types for the same opaque type - -middle_consider_type_length_limit = - consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate - -middle_const_eval_non_int = - constant evaluation of enum discriminant resulted in non-integer - -middle_const_not_used_in_type_alias = - const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias - -middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note -> - [true] : {$note} - *[other] {""} - } -middle_deprecated_in_future = use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> - [true] : {$note} - *[other] {""} - } -middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> - [true] : {$note} - *[other] {""} - } -middle_deprecated_suggestion = replace the use of the deprecated {$kind} - -middle_drop_check_overflow = - overflow while adding drop-check rules for `{$ty}` - .note = overflowed on `{$overflow_ty}` - -middle_erroneous_constant = erroneous constant encountered - -middle_failed_writing_file = - failed to write file {$path}: {$error}" - -# Note: We only mention patterns here since the error can only occur with references, and those -# are forbidden in const generics. -middle_invalid_const_in_valtree = constant {$global_const_id} cannot be used as pattern - .note = constants that reference mutable or external memory cannot be used as patterns - -middle_layout_cycle = - a cycle occurred during layout computation - -middle_layout_normalization_failure = - unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized - -middle_layout_references_error = - the type has an unknown layout - -middle_layout_simd_too_many = - the SIMD type `{$ty}` has more elements than the limit {$max_lanes} - -middle_layout_simd_zero_length = - the SIMD type `{$ty}` has zero elements - -middle_layout_size_overflow = - values of the type `{$ty}` are too big for the target architecture - -middle_layout_too_generic = the type `{$ty}` does not have a fixed layout - -middle_layout_unknown = - the type `{$ty}` has an unknown layout - -middle_max_num_nodes_in_valtree = maximum number of nodes exceeded in constant {$global_const_id} - -middle_opaque_hidden_type_mismatch = - concrete type differs from previous defining opaque type use - .label = expected `{$self_ty}`, got `{$other_ty}` - -middle_previous_use_here = - previous use here - -middle_recursion_limit_reached = - reached the recursion limit finding the struct tail for `{$ty}` - .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` - -middle_requires_lang_item = requires `{$name}` lang_item - -middle_strict_coherence_needs_negative_coherence = - to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled - .label = due to this attribute - -middle_type_length_limit = reached the type-length limit while instantiating `{$instance}` - -middle_unsupported_union = we don't support unions yet: '{$ty_name}' diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 3ff9eea8cc4b..a5d5978916eb 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -9,8 +9,8 @@ use rustc_span::{Span, Symbol}; use crate::ty::{Instance, Ty}; #[derive(Diagnostic)] -#[diag(middle_drop_check_overflow, code = E0320)] -#[note] +#[diag("overflow while adding drop-check rules for `{$ty}`", code = E0320)] +#[note("overflowed on `{$overflow_ty}`")] pub(crate) struct DropCheckOverflow<'tcx> { #[primary_span] pub span: Span, @@ -19,33 +19,33 @@ pub(crate) struct DropCheckOverflow<'tcx> { } #[derive(Diagnostic)] -#[diag(middle_failed_writing_file)] +#[diag("failed to write file {$path}: {$error}\"")] pub(crate) struct FailedWritingFile<'a> { pub path: &'a Path, pub error: io::Error, } #[derive(Diagnostic)] -#[diag(middle_opaque_hidden_type_mismatch)] +#[diag("concrete type differs from previous defining opaque type use")] pub(crate) struct OpaqueHiddenTypeMismatch<'tcx> { pub self_ty: Ty<'tcx>, pub other_ty: Ty<'tcx>, #[primary_span] - #[label] + #[label("expected `{$self_ty}`, got `{$other_ty}`")] pub other_span: Span, #[subdiagnostic] pub sub: TypeMismatchReason, } #[derive(Diagnostic)] -#[diag(middle_unsupported_union)] +#[diag("we don't support unions yet: '{$ty_name}'")] pub struct UnsupportedUnion { pub ty_name: String, } // FIXME(autodiff): I should get used somewhere #[derive(Diagnostic)] -#[diag(middle_autodiff_unsafe_inner_const_ref)] +#[diag("reading from a `Duplicated` const {$ty} is unsafe")] pub struct AutodiffUnsafeInnerConstRef<'tcx> { #[primary_span] pub span: Span, @@ -54,12 +54,12 @@ pub struct AutodiffUnsafeInnerConstRef<'tcx> { #[derive(Subdiagnostic)] pub enum TypeMismatchReason { - #[label(middle_conflict_types)] + #[label("this expression supplies two conflicting concrete types for the same opaque type")] ConflictType { #[primary_span] span: Span, }, - #[note(middle_previous_use_here)] + #[note("previous use here")] PreviousUse { #[primary_span] span: Span, @@ -67,8 +67,10 @@ pub enum TypeMismatchReason { } #[derive(Diagnostic)] -#[diag(middle_recursion_limit_reached)] -#[help] +#[diag("reached the recursion limit finding the struct tail for `{$ty}`")] +#[help( + "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]`" +)] pub(crate) struct RecursionLimitReached<'tcx> { #[primary_span] pub span: Span, @@ -77,23 +79,25 @@ pub(crate) struct RecursionLimitReached<'tcx> { } #[derive(Diagnostic)] -#[diag(middle_const_eval_non_int)] +#[diag("constant evaluation of enum discriminant resulted in non-integer")] pub(crate) struct ConstEvalNonIntError { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(middle_strict_coherence_needs_negative_coherence)] +#[diag( + "to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled" +)] pub(crate) struct StrictCoherenceNeedsNegativeCoherence { #[primary_span] pub span: Span, - #[label] + #[label("due to this attribute")] pub attr_span: Option, } #[derive(Diagnostic)] -#[diag(middle_requires_lang_item)] +#[diag("requires `{$name}` lang_item")] pub(crate) struct RequiresLangItem { #[primary_span] pub span: Span, @@ -101,7 +105,9 @@ pub(crate) struct RequiresLangItem { } #[derive(Diagnostic)] -#[diag(middle_const_not_used_in_type_alias)] +#[diag( + "const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias" +)] pub(super) struct ConstNotUsedTraitAlias { pub ct: String, #[primary_span] @@ -133,41 +139,41 @@ impl fmt::Debug for CustomSubdiagnostic<'_> { #[derive(Diagnostic)] pub enum LayoutError<'tcx> { - #[diag(middle_layout_unknown)] + #[diag("the type `{$ty}` has an unknown layout")] Unknown { ty: Ty<'tcx> }, - #[diag(middle_layout_too_generic)] + #[diag("the type `{$ty}` does not have a fixed layout")] TooGeneric { ty: Ty<'tcx> }, - #[diag(middle_layout_size_overflow)] + #[diag("values of the type `{$ty}` are too big for the target architecture")] Overflow { ty: Ty<'tcx> }, - #[diag(middle_layout_simd_too_many)] + #[diag("the SIMD type `{$ty}` has more elements than the limit {$max_lanes}")] SimdTooManyLanes { ty: Ty<'tcx>, max_lanes: u64 }, - #[diag(middle_layout_simd_zero_length)] + #[diag("the SIMD type `{$ty}` has zero elements")] SimdZeroLength { ty: Ty<'tcx> }, - #[diag(middle_layout_normalization_failure)] + #[diag("unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized")] NormalizationFailure { ty: Ty<'tcx>, failure_ty: String }, - #[diag(middle_layout_cycle)] + #[diag("a cycle occurred during layout computation")] Cycle, - #[diag(middle_layout_references_error)] + #[diag("the type has an unknown layout")] ReferencesError, } #[derive(Diagnostic)] -#[diag(middle_erroneous_constant)] +#[diag("erroneous constant encountered")] pub(crate) struct ErroneousConstant { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(middle_type_length_limit)] -#[help(middle_consider_type_length_limit)] +#[diag("reached the type-length limit while instantiating `{$instance}`")] +#[help("consider adding a `#![type_length_limit=\"{$type_length}\"]` attribute to your crate")] pub(crate) struct TypeLengthLimit<'tcx> { #[primary_span] pub span: Span, @@ -176,7 +182,7 @@ pub(crate) struct TypeLengthLimit<'tcx> { } #[derive(Diagnostic)] -#[diag(middle_max_num_nodes_in_valtree)] +#[diag("maximum number of nodes exceeded in constant {$global_const_id}")] pub(crate) struct MaxNumNodesInValtree { #[primary_span] pub span: Span, @@ -184,8 +190,8 @@ pub(crate) struct MaxNumNodesInValtree { } #[derive(Diagnostic)] -#[diag(middle_invalid_const_in_valtree)] -#[note] +#[diag("constant {$global_const_id} cannot be used as pattern")] +#[note("constants that reference mutable or external memory cannot be used as patterns")] pub(crate) struct InvalidConstInValtree { #[primary_span] pub span: Span, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 7d1b775cc4bc..5b32d4551a16 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -91,5 +91,3 @@ pub mod dep_graph; // Allows macros to refer to this crate as `::rustc_middle` extern crate self as rustc_middle; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index fe2d4b9130ed..fce0158aa511 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -4,7 +4,7 @@ use std::num::NonZero; use rustc_ast::NodeId; -use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer}; +use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer, inline_fluent}; use rustc_feature::GateIssue; use rustc_hir::attrs::{DeprecatedSince, Deprecation}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -103,7 +103,7 @@ fn deprecation_lint(is_in_effect: bool) -> &'static Lint { #[derive(Subdiagnostic)] #[suggestion( - middle_deprecated_suggestion, + "replace the use of the deprecated {$kind}", code = "{suggestion}", style = "verbose", applicability = "machine-applicable" @@ -128,10 +128,19 @@ pub struct Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { diag.primary_message(match &self.since_kind { - DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated, - DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future, + DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note -> + [true] : {$note} + *[other] {\"\"} + }"), + DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> + [true] : {$note} + *[other] {\"\"} + }"), DeprecatedSinceKind::InVersion(_) => { - crate::fluent_generated::middle_deprecated_in_version + inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> + [true] : {$note} + *[other] {\"\"} + }") } }); diag.arg("kind", self.kind); diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index cd447d4ed992..e212dd43fa7d 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -336,18 +336,26 @@ impl AssertKind { pub fn diagnostic_message(&self) -> DiagMessage { use AssertKind::*; - use crate::fluent_generated::*; - match self { - BoundsCheck { .. } => middle_bounds_check, - Overflow(BinOp::Shl, _, _) => middle_assert_shl_overflow, - Overflow(BinOp::Shr, _, _) => middle_assert_shr_overflow, - Overflow(_, _, _) => middle_assert_op_overflow, - OverflowNeg(_) => middle_assert_overflow_neg, - DivisionByZero(_) => middle_assert_divide_by_zero, - RemainderByZero(_) => middle_assert_remainder_by_zero, + BoundsCheck { .. } => inline_fluent!( + "index out of bounds: the length is {$len} but the index is {$index}" + ), + Overflow(BinOp::Shl, _, _) => { + inline_fluent!("attempt to shift left by `{$val}`, which would overflow") + } + Overflow(BinOp::Shr, _, _) => { + inline_fluent!("attempt to shift right by `{$val}`, which would overflow") + } + Overflow(_, _, _) => { + inline_fluent!("attempt to compute `{$left} {$op} {$right}`, which would overflow") + } + OverflowNeg(_) => inline_fluent!("attempt to negate `{$val}`, which would overflow"), + DivisionByZero(_) => inline_fluent!("attempt to divide `{$val}` by zero"), + RemainderByZero(_) => inline_fluent!( + "attempt to calculate the remainder of `{$val}` with a divisor of zero" + ), ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { - middle_assert_async_resume_after_return + inline_fluent!("`async fn` resumed after completion") } ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { todo!() @@ -356,36 +364,42 @@ impl AssertKind { bug!("gen blocks can be resumed after they return and will keep returning `None`") } ResumedAfterReturn(CoroutineKind::Coroutine(_)) => { - middle_assert_coroutine_resume_after_return + inline_fluent!("coroutine resumed after completion") } ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { - middle_assert_async_resume_after_panic + inline_fluent!("`async fn` resumed after panicking") } ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { todo!() } ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { - middle_assert_gen_resume_after_panic + inline_fluent!("`gen` fn or block cannot be further iterated on after it panicked") } ResumedAfterPanic(CoroutineKind::Coroutine(_)) => { - middle_assert_coroutine_resume_after_panic + inline_fluent!("coroutine resumed after panicking") + } + NullPointerDereference => inline_fluent!("null pointer dereference occurred"), + InvalidEnumConstruction(_) => { + inline_fluent!("trying to construct an enum from an invalid value `{$source}`") } - NullPointerDereference => middle_assert_null_ptr_deref, - InvalidEnumConstruction(_) => middle_assert_invalid_enum_construction, ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { - middle_assert_async_resume_after_drop + inline_fluent!("`async fn` resumed after async drop") } ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { todo!() } ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { - middle_assert_gen_resume_after_drop + inline_fluent!( + "`gen` fn or block cannot be further iterated on after it async dropped" + ) } ResumedAfterDrop(CoroutineKind::Coroutine(_)) => { - middle_assert_coroutine_resume_after_drop + inline_fluent!("coroutine resumed after async drop") } - MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref, + MisalignedPointerDereference { .. } => inline_fluent!( + "misaligned pointer dereference: address must be a multiple of {$required} but is {$found}" + ), } } @@ -498,6 +512,7 @@ impl<'tcx> TerminatorKind<'tcx> { } pub use helper::*; +use rustc_errors::inline_fluent; mod helper { use super::*; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 14ebcc968f7a..d3b4654a8d79 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -9,6 +9,7 @@ use rustc_abi::{ use rustc_error_messages::DiagMessage; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, + inline_fluent, }; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; @@ -268,18 +269,25 @@ impl<'tcx> LayoutError<'tcx> { pub fn diagnostic_message(&self) -> DiagMessage { use LayoutError::*; - use crate::fluent_generated::*; match self { - Unknown(_) => middle_layout_unknown, - SizeOverflow(_) => middle_layout_size_overflow, - InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => { - middle_layout_simd_too_many + Unknown(_) => inline_fluent!("the type `{$ty}` has an unknown layout"), + SizeOverflow(_) => { + inline_fluent!("values of the type `{$ty}` are too big for the target architecture") } - InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => middle_layout_simd_zero_length, - TooGeneric(_) => middle_layout_too_generic, - NormalizationFailure(_, _) => middle_layout_normalization_failure, - Cycle(_) => middle_layout_cycle, - ReferencesError(_) => middle_layout_references_error, + InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => { + inline_fluent!( + "the SIMD type `{$ty}` has more elements than the limit {$max_lanes}" + ) + } + InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => { + inline_fluent!("the SIMD type `{$ty}` has zero elements") + } + TooGeneric(_) => inline_fluent!("the type `{$ty}` does not have a fixed layout"), + NormalizationFailure(_, _) => inline_fluent!( + "unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized" + ), + Cycle(_) => inline_fluent!("a cycle occurred during layout computation"), + ReferencesError(_) => inline_fluent!("the type has an unknown layout"), } } From 0da9476010e9ee65777638928bd38820c6d7dfc2 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 15:53:02 +0100 Subject: [PATCH 73/81] Convert to inline diagnostics in `rustc_ast_passes` --- Cargo.lock | 2 - compiler/rustc_ast_passes/Cargo.toml | 1 - compiler/rustc_ast_passes/messages.ftl | 342 ----------- compiler/rustc_ast_passes/src/errors.rs | 531 +++++++++++------- compiler/rustc_ast_passes/src/feature_gate.rs | 3 +- compiler/rustc_ast_passes/src/lib.rs | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - 8 files changed, 329 insertions(+), 554 deletions(-) delete mode 100644 compiler/rustc_ast_passes/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 9c98946c9d39..6103e787f107 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3514,7 +3514,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_macros", "rustc_session", "rustc_span", @@ -3772,7 +3771,6 @@ dependencies = [ "libc", "rustc_abi", "rustc_ast", - "rustc_ast_passes", "rustc_ast_pretty", "rustc_borrowck", "rustc_builtin_macros", diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 3e04f8b11ec9..fdc735fa8d4f 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -13,7 +13,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl deleted file mode 100644 index b9117c83ae2f..000000000000 --- a/compiler/rustc_ast_passes/messages.ftl +++ /dev/null @@ -1,342 +0,0 @@ -ast_passes_abi_cannot_be_coroutine = - functions with the {$abi} ABI cannot be `{$coroutine_kind_str}` - .suggestion = remove the `{$coroutine_kind_str}` keyword from this definition - -ast_passes_abi_custom_safe_foreign_function = - foreign functions with the "custom" ABI cannot be safe - .suggestion = remove the `safe` keyword from this definition - -ast_passes_abi_custom_safe_function = - functions with the "custom" ABI must be unsafe - .suggestion = add the `unsafe` keyword to this definition - -ast_passes_abi_must_not_have_parameters_or_return_type= - invalid signature for `extern {$abi}` function - .note = functions with the {$abi} ABI cannot have any parameters or return type - .suggestion = remove the parameters and return type - -ast_passes_abi_must_not_have_return_type= - invalid signature for `extern {$abi}` function - .note = functions with the {$abi} ABI cannot have a return type - .help = remove the return type - -ast_passes_abi_x86_interrupt = - invalid signature for `extern "x86-interrupt"` function - .note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count}) - -ast_passes_assoc_const_without_body = - associated constant in `impl` without body - .suggestion = provide a definition for the constant - -ast_passes_assoc_fn_without_body = - associated function in `impl` without body - .suggestion = provide a definition for the function - -ast_passes_assoc_type_without_body = - associated type in `impl` without body - .suggestion = provide a definition for the type - -ast_passes_async_fn_in_const_trait_or_trait_impl = - async functions are not allowed in `const` {$context -> - [trait_impl] trait impls - [impl] impls - *[trait] traits - } - .label = associated functions of `const` cannot be declared `async` - -ast_passes_at_least_one_trait = at least one trait must be specified - -ast_passes_auto_generic = auto traits cannot have generic parameters - .label = auto trait cannot have generic parameters - .suggestion = remove the parameters - -ast_passes_auto_items = auto traits cannot have associated items - .label = {ast_passes_auto_items} - .suggestion = remove the associated items - -ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds - .label = {ast_passes_auto_super_lifetime} - .suggestion = remove the super traits or lifetime bounds - -ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block - .cannot_have = cannot have a body - .invalid = the invalid body - .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body - -ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect - -ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions - .label = `extern "{$abi}"` because of this - .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list - -ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions - .label = `extern "{$abi}"` because of this - .help = C-variadic function must have a compatible calling convention - -ast_passes_c_variadic_must_be_unsafe = - functions with a C variable argument list must be unsafe - .suggestion = add the `unsafe` keyword to this definition - -ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions - .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list - -ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions - -ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic - .const = `const` because of this - .variadic = C-variadic because of this - -ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}` - .const = `const` because of this - .coroutine = `{$coroutine_kind}` because of this - .label = {""} - -ast_passes_const_auto_trait = auto traits cannot be const - .help = remove the `const` keyword - -ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types - -ast_passes_const_without_body = - free constant item without body - .suggestion = provide a definition for the constant - -ast_passes_constraint_on_negative_bound = - associated type constraints not allowed on negative bounds - -ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic - .const = `{$coroutine_kind}` because of this - .variadic = C-variadic because of this - -ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses - .label = not supported - .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax - .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax - .note = see issue #20041 for more information - -ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block - -ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier - .label = in this `extern` block - .suggestion = remove the `{$kw}` qualifier - -ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - .suggestion = add `unsafe` to this `extern` block - -ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers - .label = in this `extern` block - .note = this limitation may be lifted in the future; see issue #83942 for more information - -ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html - -ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr} - .suggestion = remove the {$remove_descr} - .label = `extern` block begins here - -ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed - .suggestion = specify an ABI - .help = prior to Rust 2024, a default ABI was inferred - -ast_passes_extern_without_abi_sugg = `extern` declarations without an explicit ABI are deprecated - .label = ABI should be specified here - .suggestion = explicitly specify the {$default_abi} ABI - -ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel - .suggestion = remove the attribute - .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable - -ast_passes_fieldless_union = unions cannot have zero fields - -ast_passes_fn_body_extern = incorrect function inside `extern` block - .cannot_have = cannot have a body - .suggestion = remove the invalid body - .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block - .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body - -ast_passes_fn_param_c_var_args_not_last = - `...` must be the last argument of a C-variadic function - -ast_passes_fn_param_doc_comment = - documentation comments cannot be applied to function parameters - .label = doc comments are not allowed here - -ast_passes_fn_param_forbidden_attr = - allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - -ast_passes_fn_param_forbidden_self = - `self` parameter is only allowed in associated functions - .label = not semantically valid as function parameter - .note = associated functions are those in `impl` or `trait` definitions - -ast_passes_fn_param_too_many = - function can not have more than {$max_num_args} arguments - -ast_passes_fn_ptr_invalid_safety = function pointers cannot be declared with `safe` safety qualifier - .suggestion = remove safe from this item - -ast_passes_fn_without_body = - free function without a body - .suggestion = provide a definition for the function - -ast_passes_forbidden_bound = - bounds cannot be used in this context - -ast_passes_forbidden_const_param = - late-bound const parameters cannot be used currently - -ast_passes_forbidden_default = - `default` is only allowed on items in trait impls - .label = `default` because of this - -ast_passes_forbidden_non_lifetime_param = - only lifetime parameters can be used in this context - -ast_passes_generic_before_constraints = generic arguments must come before the first constraint - .constraints = {$constraint_len -> - [one] constraint - *[other] constraints - } - .args = generic {$args_len -> - [one] argument - *[other] arguments - } - .empty_string = {""}, - .suggestion = move the {$constraint_len -> - [one] constraint - *[other] constraints - } after the generic {$args_len -> - [one] argument - *[other] arguments - } - -ast_passes_generic_default_trailing = generic parameters with a default must be trailing - -ast_passes_impl_fn_const = - redundant `const` fn marker in const impl - .parent_constness = this declares all associated functions implicitly const - .label = remove the `const` - -ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed - .help = remove one of these features - -ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier - .suggestion = remove safe from this item - -ast_passes_item_underscore = `{$kind}` items in this context need a name - .label = `_` is not a valid name for this `{$kind}` item - -ast_passes_match_arm_with_no_body = - `match` arm with no body - .suggestion = add a body after the pattern - -ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe - .suggestion = needs `unsafe` before the extern keyword - -ast_passes_missing_unsafe_on_extern_lint = extern blocks should be unsafe - .suggestion = needs `unsafe` before the extern keyword - -ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name - .help = consider using the `#[path]` attribute to specify filesystem path - -ast_passes_negative_bound_not_supported = - negative bounds are not supported - -ast_passes_negative_bound_with_parenthetical_notation = - parenthetical notation may not be used for negative bounds - -ast_passes_nested_impl_trait = nested `impl Trait` is not allowed - .outer = outer `impl Trait` - .inner = nested `impl Trait` here - -ast_passes_nested_lifetimes = nested quantification of lifetimes - -ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier - -ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax - .help = use `auto trait Trait {"{}"}` instead - -ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters - .suggestion = reorder the parameters: lifetimes, then consts and types - -ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies - .label = pattern not allowed in function without body - -ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types - -ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations - .label = pattern not allowed in foreign function - -ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax - .label = second `use<...>` here - -ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc} - -ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs - -ast_passes_static_without_body = - free static item without body - .suggestion = provide a definition for the static - -ast_passes_tilde_const_disallowed = `[const]` is not allowed here - .closure = closures cannot have `[const]` trait bounds - .function = this function is not `const`, so it cannot have `[const]` trait bounds - .trait = this trait is not `const`, so it cannot have `[const]` trait bounds - .trait_impl = this impl is not `const`, so it cannot have `[const]` trait bounds - .impl = inherent impls cannot have `[const]` trait bounds - .trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds - .trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds - .inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds - .struct = structs cannot have `[const]` trait bounds - .enum = enums cannot have `[const]` trait bounds - .union = unions cannot have `[const]` trait bounds - .anon_const = anonymous constants cannot have `[const]` trait bounds - .object = trait objects cannot have `[const]` trait bounds - .item = this item cannot have `[const]` trait bounds - -ast_passes_trait_fn_const = - functions in {$in_impl -> - [true] trait impls - *[false] traits - } cannot be declared const - .label = functions in {$in_impl -> - [true] trait impls - *[false] traits - } cannot be const - .const_context_label = this declares all associated functions implicitly const - .remove_const_sugg = remove the `const`{$requires_multiple_changes -> - [true] {" ..."} - *[false] {""} - } - .make_impl_const_sugg = ... and declare the impl to be const instead - .make_trait_const_sugg = ... and declare the trait to be const instead - -ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted - -ast_passes_ty_alias_without_body = - free type alias without body - .suggestion = provide a definition for the type - -ast_passes_unsafe_item = {$kind} cannot be declared unsafe - -ast_passes_unsafe_negative_impl = negative impls cannot be unsafe - .negative = negative because of this - .unsafe = unsafe because of this - -ast_passes_unsafe_static = - static items cannot be declared with `unsafe` safety qualifier outside of `extern` block - -ast_passes_visibility_not_permitted = - visibility qualifiers are not permitted here - .enum_variant = enum variants and their fields always share the visibility of the enum they are in - .trait_impl = trait items always share the visibility of their trait - .individual_impl_items = place qualifiers on individual impl items instead - .individual_foreign_items = place qualifiers on individual foreign items instead - .remove_qualifier_sugg = remove the qualifier - -ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases - .note = see issue #112792 for more information - .help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable - -ast_passes_where_clause_before_type_alias = where clauses are not allowed before the type for type aliases - .note = see issue #89122 for more information - .remove_suggestion = remove this `where` - .move_suggestion = move it to the end of the type declaration diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 22adaae8c6f2..baf6f6beaeed 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -3,68 +3,76 @@ use rustc_abi::ExternAbi; use rustc_ast::ParamKindOrd; use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic}; +use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic, inline_fluent}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] -#[diag(ast_passes_visibility_not_permitted, code = E0449)] +#[diag("visibility qualifiers are not permitted here", code = E0449)] pub(crate) struct VisibilityNotPermitted { #[primary_span] pub span: Span, #[subdiagnostic] pub note: VisibilityNotPermittedNote, - #[suggestion( - ast_passes_remove_qualifier_sugg, - code = "", - applicability = "machine-applicable" - )] + #[suggestion("remove the qualifier", code = "", applicability = "machine-applicable")] pub remove_qualifier_sugg: Span, } #[derive(Subdiagnostic)] pub(crate) enum VisibilityNotPermittedNote { - #[note(ast_passes_enum_variant)] + #[note("enum variants and their fields always share the visibility of the enum they are in")] EnumVariant, - #[note(ast_passes_trait_impl)] + #[note("trait items always share the visibility of their trait")] TraitImpl, - #[note(ast_passes_individual_impl_items)] + #[note("place qualifiers on individual impl items instead")] IndividualImplItems, - #[note(ast_passes_individual_foreign_items)] + #[note("place qualifiers on individual foreign items instead")] IndividualForeignItems, } #[derive(Diagnostic)] -#[diag(ast_passes_impl_fn_const)] +#[diag("redundant `const` fn marker in const impl")] pub(crate) struct ImplFnConst { #[primary_span] - #[suggestion(ast_passes_label, code = "", applicability = "machine-applicable")] + #[suggestion("remove the `const`", code = "", applicability = "machine-applicable")] pub span: Span, - #[label(ast_passes_parent_constness)] + #[label("this declares all associated functions implicitly const")] pub parent_constness: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_trait_fn_const, code = E0379)] +#[diag("functions in {$in_impl -> + [true] trait impls + *[false] traits + } cannot be declared const", code = E0379)] pub(crate) struct TraitFnConst { #[primary_span] - #[label] + #[label( + "functions in {$in_impl -> + [true] trait impls + *[false] traits + } cannot be const" + )] pub span: Span, pub in_impl: bool, - #[label(ast_passes_const_context_label)] + #[label("this declares all associated functions implicitly const")] pub const_context_label: Option, - #[suggestion(ast_passes_remove_const_sugg, code = "")] + #[suggestion( + "remove the `const`{$requires_multiple_changes -> + [true] {\" ...\"} + *[false] {\"\"} + }", + code = "" + )] pub remove_const_sugg: (Span, Applicability), pub requires_multiple_changes: bool, #[suggestion( - ast_passes_make_impl_const_sugg, + "... and declare the impl to be const instead", code = "const ", applicability = "maybe-incorrect" )] pub make_impl_const_sugg: Option, #[suggestion( - ast_passes_make_trait_const_sugg, + "... and declare the trait to be const instead", code = "const ", applicability = "maybe-incorrect" )] @@ -72,31 +80,37 @@ pub(crate) struct TraitFnConst { } #[derive(Diagnostic)] -#[diag(ast_passes_async_fn_in_const_trait_or_trait_impl)] +#[diag( + "async functions are not allowed in `const` {$context -> + [trait_impl] trait impls + [impl] impls + *[trait] traits + }" +)] pub(crate) struct AsyncFnInConstTraitOrTraitImpl { #[primary_span] pub async_keyword: Span, pub context: &'static str, - #[label] + #[label("associated functions of `const` cannot be declared `async`")] pub const_keyword: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_bound)] +#[diag("bounds cannot be used in this context")] pub(crate) struct ForbiddenBound { #[primary_span] pub spans: Vec, } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_const_param)] +#[diag("late-bound const parameters cannot be used currently")] pub(crate) struct ForbiddenConstParam { #[primary_span] pub const_param_spans: Vec, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_param_too_many)] +#[diag("function can not have more than {$max_num_args} arguments")] pub(crate) struct FnParamTooMany { #[primary_span] pub span: Span, @@ -104,105 +118,135 @@ pub(crate) struct FnParamTooMany { } #[derive(Diagnostic)] -#[diag(ast_passes_fn_param_c_var_args_not_last)] +#[diag("`...` must be the last argument of a C-variadic function")] pub(crate) struct FnParamCVarArgsNotLast { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_param_doc_comment)] +#[diag("documentation comments cannot be applied to function parameters")] pub(crate) struct FnParamDocComment { #[primary_span] - #[label] + #[label("doc comments are not allowed here")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_param_forbidden_attr)] +#[diag( + "allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters" +)] pub(crate) struct FnParamForbiddenAttr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_param_forbidden_self)] -#[note] +#[diag("`self` parameter is only allowed in associated functions")] +#[note("associated functions are those in `impl` or `trait` definitions")] pub(crate) struct FnParamForbiddenSelf { #[primary_span] - #[label] + #[label("not semantically valid as function parameter")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_default)] +#[diag("`default` is only allowed on items in trait impls")] pub(crate) struct ForbiddenDefault { #[primary_span] pub span: Span, - #[label] + #[label("`default` because of this")] pub def_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_assoc_const_without_body)] +#[diag("associated constant in `impl` without body")] pub(crate) struct AssocConstWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " = ;", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the constant", + code = " = ;", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_assoc_fn_without_body)] +#[diag("associated function in `impl` without body")] pub(crate) struct AssocFnWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " {{ }}", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the function", + code = " {{ }}", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_assoc_type_without_body)] +#[diag("associated type in `impl` without body")] pub(crate) struct AssocTypeWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " = ;", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the type", + code = " = ;", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_const_without_body)] +#[diag("free constant item without body")] pub(crate) struct ConstWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " = ;", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the constant", + code = " = ;", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_static_without_body)] +#[diag("free static item without body")] pub(crate) struct StaticWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " = ;", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the static", + code = " = ;", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_ty_alias_without_body)] +#[diag("free type alias without body")] pub(crate) struct TyAliasWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " = ;", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the type", + code = " = ;", + applicability = "has-placeholders" + )] pub replace_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_without_body)] +#[diag("free function without a body")] pub(crate) struct FnWithoutBody { #[primary_span] pub span: Span, - #[suggestion(code = " {{ }}", applicability = "has-placeholders")] + #[suggestion( + "provide a definition for the function", + code = " {{ }}", + applicability = "has-placeholders" + )] pub replace_span: Span, #[subdiagnostic] pub extern_block_suggestion: Option, @@ -210,14 +254,20 @@ pub(crate) struct FnWithoutBody { #[derive(Subdiagnostic)] pub(crate) enum ExternBlockSuggestion { - #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "if you meant to declare an externally defined function, use an `extern` block", + applicability = "maybe-incorrect" + )] Implicit { #[suggestion_part(code = "extern {{")] start_span: Span, #[suggestion_part(code = " }}")] end_span: Span, }, - #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "if you meant to declare an externally defined function, use an `extern` block", + applicability = "maybe-incorrect" + )] Explicit { #[suggestion_part(code = "extern \"{abi}\" {{")] start_span: Span, @@ -228,37 +278,44 @@ pub(crate) enum ExternBlockSuggestion { } #[derive(Diagnostic)] -#[diag(ast_passes_extern_invalid_safety)] +#[diag("items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers")] pub(crate) struct InvalidSafetyOnExtern { #[primary_span] pub item_span: Span, - #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "add `unsafe` to this `extern` block", + code = "unsafe ", + applicability = "machine-applicable", + style = "verbose" + )] pub block: Option, } #[derive(Diagnostic)] -#[diag(ast_passes_item_invalid_safety)] +#[diag( + "items outside of `unsafe extern {\"{ }\"}` cannot be declared with `safe` safety qualifier" +)] pub(crate) struct InvalidSafetyOnItem { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_ptr_invalid_safety)] +#[diag("function pointers cannot be declared with `safe` safety qualifier")] pub(crate) struct InvalidSafetyOnFnPtr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_unsafe_static)] +#[diag("static items cannot be declared with `unsafe` safety qualifier outside of `extern` block")] pub(crate) struct UnsafeStatic { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_bound_in_context)] +#[diag("bounds on `type`s in {$ctx} have no effect")] pub(crate) struct BoundInContext<'a> { #[primary_span] pub span: Span, @@ -266,83 +323,93 @@ pub(crate) struct BoundInContext<'a> { } #[derive(Diagnostic)] -#[diag(ast_passes_extern_types_cannot)] -#[note(ast_passes_extern_keyword_link)] +#[diag("`type`s inside `extern` blocks cannot have {$descr}")] +#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")] pub(crate) struct ExternTypesCannotHave<'a> { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[suggestion("remove the {$remove_descr}", code = "", applicability = "maybe-incorrect")] pub span: Span, pub descr: &'a str, pub remove_descr: &'a str, - #[label] + #[label("`extern` block begins here")] pub block_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_body_in_extern)] -#[note(ast_passes_extern_keyword_link)] +#[diag("incorrect `{$kind}` inside `extern` block")] +#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")] pub(crate) struct BodyInExtern<'a> { #[primary_span] - #[label(ast_passes_cannot_have)] + #[label("cannot have a body")] pub span: Span, - #[label(ast_passes_invalid)] + #[label("the invalid body")] pub body: Span, - #[label(ast_passes_existing)] + #[label( + "`extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body" + )] pub block: Span, pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(ast_passes_fn_body_extern)] -#[help] -#[note(ast_passes_extern_keyword_link)] +#[diag("incorrect function inside `extern` block")] +#[help( + "you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block" +)] +#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")] pub(crate) struct FnBodyInExtern { #[primary_span] - #[label(ast_passes_cannot_have)] + #[label("cannot have a body")] pub span: Span, - #[suggestion(code = ";", applicability = "maybe-incorrect")] + #[suggestion("remove the invalid body", code = ";", applicability = "maybe-incorrect")] pub body: Span, - #[label] + #[label( + "`extern` blocks define existing foreign functions and functions inside of them cannot have a body" + )] pub block: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_extern_fn_qualifiers)] +#[diag("functions in `extern` blocks cannot have `{$kw}` qualifier")] pub(crate) struct FnQualifierInExtern { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[suggestion("remove the `{$kw}` qualifier", code = "", applicability = "maybe-incorrect")] pub span: Span, - #[label] + #[label("in this `extern` block")] pub block: Span, pub kw: &'static str, } #[derive(Diagnostic)] -#[diag(ast_passes_extern_item_ascii)] -#[note] +#[diag("items in `extern` blocks cannot use non-ascii identifiers")] +#[note( + "this limitation may be lifted in the future; see issue #83942 for more information" +)] pub(crate) struct ExternItemAscii { #[primary_span] pub span: Span, - #[label] + #[label("in this `extern` block")] pub block: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_no_extern)] -#[help] +#[diag("`...` is not supported for non-extern functions")] +#[help( + "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" +)] pub(crate) struct CVariadicNoExtern { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_must_be_unsafe)] +#[diag("functions with a C variable argument list must be unsafe")] pub(crate) struct CVariadicMustBeUnsafe { #[primary_span] pub span: Span, #[suggestion( - ast_passes_suggestion, + "add the `unsafe` keyword to this definition", applicability = "maybe-incorrect", code = "unsafe ", style = "verbose" @@ -351,46 +418,48 @@ pub(crate) struct CVariadicMustBeUnsafe { } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_bad_extern)] -#[help] +#[diag("`...` is not supported for `extern \"{$abi}\"` functions")] +#[help( + "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" +)] pub(crate) struct CVariadicBadExtern { #[primary_span] pub span: Span, pub abi: &'static str, - #[label] + #[label("`extern \"{$abi}\"` because of this")] pub extern_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_bad_naked_extern)] -#[help] +#[diag("`...` is not supported for `extern \"{$abi}\"` naked functions")] +#[help("C-variadic function must have a compatible calling convention")] pub(crate) struct CVariadicBadNakedExtern { #[primary_span] pub span: Span, pub abi: &'static str, - #[label] + #[label("`extern \"{$abi}\"` because of this")] pub extern_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_item_underscore)] +#[diag("`{$kind}` items in this context need a name")] pub(crate) struct ItemUnderscore<'a> { #[primary_span] - #[label] + #[label("`_` is not a valid name for this `{$kind}` item")] pub span: Span, pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(ast_passes_nomangle_ascii, code = E0754)] +#[diag("`#[no_mangle]` requires ASCII identifier", code = E0754)] pub(crate) struct NoMangleAscii { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_module_nonascii, code = E0754)] -#[help] +#[diag("trying to load file for module `{$name}` with non-ascii identifier name", code = E0754)] +#[help("consider using the `#[path]` attribute to specify filesystem path")] pub(crate) struct ModuleNonAscii { #[primary_span] pub span: Span, @@ -398,55 +467,91 @@ pub(crate) struct ModuleNonAscii { } #[derive(Diagnostic)] -#[diag(ast_passes_auto_generic, code = E0567)] +#[diag("auto traits cannot have generic parameters", code = E0567)] pub(crate) struct AutoTraitGeneric { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the parameters", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub span: Span, - #[label] + #[label("auto trait cannot have generic parameters")] pub ident: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_auto_super_lifetime, code = E0568)] +#[diag("auto traits cannot have super traits or lifetime bounds", code = E0568)] pub(crate) struct AutoTraitBounds { #[primary_span] pub span: Vec, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the super traits or lifetime bounds", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub removal: Span, - #[label] + #[label("auto traits cannot have super traits or lifetime bounds")] pub ident: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_auto_items, code = E0380)] +#[diag("auto traits cannot have associated items", code = E0380)] pub(crate) struct AutoTraitItems { #[primary_span] pub spans: Vec, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the super traits or lifetime bounds", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub total: Span, - #[label] + #[label("auto traits cannot have associated items")] pub ident: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_const_auto_trait)] -#[help] +#[diag("auto traits cannot be const")] +#[help("remove the `const` keyword")] pub(crate) struct ConstAutoTrait { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_generic_before_constraints)] +#[diag("generic arguments must come before the first constraint")] pub(crate) struct ArgsBeforeConstraint { #[primary_span] pub arg_spans: Vec, - #[label(ast_passes_constraints)] + #[label( + "{$constraint_len -> + [one] constraint + *[other] constraints + }" + )] pub constraints: Span, - #[label(ast_passes_args)] + #[label( + "generic {$args_len -> + [one] argument + *[other] arguments + }" + )] pub args: Span, - #[suggestion(code = "{suggestion}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "move the {$constraint_len -> + [one] constraint + *[other] constraints + } after the generic {$args_len -> + [one] argument + *[other] arguments + }", + code = "{suggestion}", + applicability = "machine-applicable", + style = "verbose" + )] pub data: Span, pub suggestion: String, pub constraint_len: usize, @@ -467,43 +572,47 @@ impl Subdiagnostic for EmptyLabelManySpans { } #[derive(Diagnostic)] -#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)] +#[diag("patterns aren't allowed in function pointer types", code = E0561)] pub(crate) struct PatternFnPointer { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_trait_object_single_bound, code = E0226)] +#[diag("only a single explicit lifetime bound is permitted", code = E0226)] pub(crate) struct TraitObjectBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_nested_impl_trait, code = E0666)] +#[diag("nested `impl Trait` is not allowed", code = E0666)] pub(crate) struct NestedImplTrait { #[primary_span] pub span: Span, - #[label(ast_passes_outer)] + #[label("outer `impl Trait`")] pub outer: Span, - #[label(ast_passes_inner)] + #[label("nested `impl Trait` here")] pub inner: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_at_least_one_trait)] +#[diag("at least one trait must be specified")] pub(crate) struct AtLeastOneTrait { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_out_of_order_params)] +#[diag("{$param_ord} parameters must be declared prior to {$max_param} parameters")] pub(crate) struct OutOfOrderParams<'a> { #[primary_span] pub spans: Vec, - #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")] + #[suggestion( + "reorder the parameters: lifetimes, then consts and types", + code = "{ordered_params}", + applicability = "machine-applicable" + )] pub sugg_span: Span, pub param_ord: &'a ParamKindOrd, pub max_param: &'a ParamKindOrd, @@ -511,26 +620,26 @@ pub(crate) struct OutOfOrderParams<'a> { } #[derive(Diagnostic)] -#[diag(ast_passes_obsolete_auto)] -#[help] +#[diag("`impl Trait for .. {\"{}\"}` is an obsolete syntax")] +#[help("use `auto trait Trait {\"{}\"}` instead")] pub(crate) struct ObsoleteAuto { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_unsafe_negative_impl, code = E0198)] +#[diag("negative impls cannot be unsafe", code = E0198)] pub(crate) struct UnsafeNegativeImpl { #[primary_span] pub span: Span, - #[label(ast_passes_negative)] + #[label("negative because of this")] pub negative: Span, - #[label(ast_passes_unsafe)] + #[label("unsafe because of this")] pub r#unsafe: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_unsafe_item)] +#[diag("{$kind} cannot be declared unsafe")] pub(crate) struct UnsafeItem { #[primary_span] pub span: Span, @@ -538,39 +647,43 @@ pub(crate) struct UnsafeItem { } #[derive(Diagnostic)] -#[diag(ast_passes_missing_unsafe_on_extern)] +#[diag("extern blocks must be unsafe")] pub(crate) struct MissingUnsafeOnExtern { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(ast_passes_missing_unsafe_on_extern_lint)] +#[diag("extern blocks should be unsafe")] pub(crate) struct MissingUnsafeOnExternLint { - #[suggestion(code = "unsafe ", applicability = "machine-applicable")] + #[suggestion( + "needs `unsafe` before the extern keyword", + code = "unsafe ", + applicability = "machine-applicable" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_fieldless_union)] +#[diag("unions cannot have zero fields")] pub(crate) struct FieldlessUnion { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_where_clause_after_type_alias)] -#[note] +#[diag("where clauses are not allowed after the type for type aliases")] +#[note("see issue #112792 for more information")] pub(crate) struct WhereClauseAfterTypeAlias { #[primary_span] pub span: Span, - #[help] + #[help("add `#![feature(lazy_type_alias)]` to the crate attributes to enable")] pub help: bool, } #[derive(Diagnostic)] -#[diag(ast_passes_where_clause_before_type_alias)] -#[note] +#[diag("where clauses are not allowed before the type for type aliases")] +#[note("see issue #89122 for more information")] pub(crate) struct WhereClauseBeforeTypeAlias { #[primary_span] pub span: Span, @@ -580,13 +693,13 @@ pub(crate) struct WhereClauseBeforeTypeAlias { #[derive(Subdiagnostic)] pub(crate) enum WhereClauseBeforeTypeAliasSugg { - #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")] + #[suggestion("remove this `where`", applicability = "machine-applicable", code = "")] Remove { #[primary_span] span: Span, }, #[multipart_suggestion( - ast_passes_move_suggestion, + "move it to the end of the type declaration", applicability = "machine-applicable", style = "verbose" )] @@ -600,21 +713,21 @@ pub(crate) enum WhereClauseBeforeTypeAliasSugg { } #[derive(Diagnostic)] -#[diag(ast_passes_generic_default_trailing)] +#[diag("generic parameters with a default must be trailing")] pub(crate) struct GenericDefaultTrailing { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_nested_lifetimes, code = E0316)] +#[diag("nested quantification of lifetimes", code = E0316)] pub(crate) struct NestedLifetimes { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_const_bound_trait_object)] +#[diag("const trait bounds are not allowed in trait object types")] pub(crate) struct ConstBoundTraitObject { #[primary_span] pub span: Span, @@ -623,7 +736,7 @@ pub(crate) struct ConstBoundTraitObject { // FIXME(const_trait_impl): Consider making the note/reason the message of the diagnostic. // FIXME(const_trait_impl): Provide structured suggestions (e.g., add `const` here). #[derive(Diagnostic)] -#[diag(ast_passes_tilde_const_disallowed)] +#[diag("`[const]` is not allowed here")] pub(crate) struct TildeConstDisallowed { #[primary_span] pub span: Span, @@ -633,108 +746,108 @@ pub(crate) struct TildeConstDisallowed { #[derive(Subdiagnostic, Copy, Clone)] pub(crate) enum TildeConstReason { - #[note(ast_passes_closure)] + #[note("closures cannot have `[const]` trait bounds")] Closure, - #[note(ast_passes_function)] + #[note("this function is not `const`, so it cannot have `[const]` trait bounds")] Function { #[primary_span] ident: Span, }, - #[note(ast_passes_trait)] + #[note("this trait is not `const`, so it cannot have `[const]` trait bounds")] Trait { #[primary_span] span: Span, }, - #[note(ast_passes_trait_impl)] + #[note("this impl is not `const`, so it cannot have `[const]` trait bounds")] TraitImpl { #[primary_span] span: Span, }, - #[note(ast_passes_impl)] + #[note("inherent impls cannot have `[const]` trait bounds")] Impl { #[primary_span] span: Span, }, - #[note(ast_passes_trait_assoc_ty)] + #[note("associated types in non-`const` traits cannot have `[const]` trait bounds")] TraitAssocTy { #[primary_span] span: Span, }, - #[note(ast_passes_trait_impl_assoc_ty)] + #[note("associated types in non-const impls cannot have `[const]` trait bounds")] TraitImplAssocTy { #[primary_span] span: Span, }, - #[note(ast_passes_inherent_assoc_ty)] + #[note("inherent associated types cannot have `[const]` trait bounds")] InherentAssocTy { #[primary_span] span: Span, }, - #[note(ast_passes_struct)] + #[note("structs cannot have `[const]` trait bounds")] Struct { #[primary_span] span: Span, }, - #[note(ast_passes_enum)] + #[note("enums cannot have `[const]` trait bounds")] Enum { #[primary_span] span: Span, }, - #[note(ast_passes_union)] + #[note("unions cannot have `[const]` trait bounds")] Union { #[primary_span] span: Span, }, - #[note(ast_passes_anon_const)] + #[note("anonymous constants cannot have `[const]` trait bounds")] AnonConst { #[primary_span] span: Span, }, - #[note(ast_passes_object)] + #[note("trait objects cannot have `[const]` trait bounds")] TraitObject, - #[note(ast_passes_item)] + #[note("this item cannot have `[const]` trait bounds")] Item, } #[derive(Diagnostic)] -#[diag(ast_passes_const_and_coroutine)] +#[diag("functions cannot be both `const` and `{$coroutine_kind}`")] pub(crate) struct ConstAndCoroutine { #[primary_span] pub spans: Vec, - #[label(ast_passes_const)] + #[label("`const` because of this")] pub const_span: Span, - #[label(ast_passes_coroutine)] + #[label("`{$coroutine_kind}` because of this")] pub coroutine_span: Span, - #[label] + #[label("{\"\"}")] pub span: Span, pub coroutine_kind: &'static str, } #[derive(Diagnostic)] -#[diag(ast_passes_const_and_c_variadic)] +#[diag("functions cannot be both `const` and C-variadic")] pub(crate) struct ConstAndCVariadic { #[primary_span] pub spans: Vec, - #[label(ast_passes_const)] + #[label("`const` because of this")] pub const_span: Span, - #[label(ast_passes_variadic)] + #[label("C-variadic because of this")] pub variadic_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_coroutine_and_c_variadic)] +#[diag("functions cannot be both `{$coroutine_kind}` and C-variadic")] pub(crate) struct CoroutineAndCVariadic { #[primary_span] pub spans: Vec, pub coroutine_kind: &'static str, - #[label(ast_passes_const)] + #[label("`{$coroutine_kind}` because of this")] pub coroutine_span: Span, - #[label(ast_passes_variadic)] + #[label("C-variadic because of this")] pub variadic_span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_not_supported)] +#[diag("the `{$target}` target does not support c-variadic functions")] pub(crate) struct CVariadicNotSupported<'a> { #[primary_span] pub variadic_span: Span, @@ -742,29 +855,29 @@ pub(crate) struct CVariadicNotSupported<'a> { } #[derive(Diagnostic)] -#[diag(ast_passes_pattern_in_foreign, code = E0130)] +#[diag("patterns aren't allowed in foreign function declarations", code = E0130)] // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) pub(crate) struct PatternInForeign { #[primary_span] - #[label] + #[label("pattern not allowed in foreign function")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_pattern_in_bodiless, code = E0642)] +#[diag("patterns aren't allowed in functions without bodies", code = E0642)] // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) pub(crate) struct PatternInBodiless { #[primary_span] - #[label] + #[label("pattern not allowed in function without body")] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_equality_in_where)] -#[note] +#[diag("equality constraints are not yet supported in `where` clauses")] +#[note("see issue #20041 for more information")] pub(crate) struct EqualityInWhere { #[primary_span] - #[label] + #[label("not supported")] pub span: Span, #[subdiagnostic] pub assoc: Option, @@ -774,7 +887,7 @@ pub(crate) struct EqualityInWhere { #[derive(Subdiagnostic)] #[suggestion( - ast_passes_suggestion, + "if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax", code = "{param}: {path}", style = "verbose", applicability = "maybe-incorrect" @@ -788,7 +901,10 @@ pub(crate) struct AssociatedSuggestion { } #[derive(Subdiagnostic)] -#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax", + applicability = "maybe-incorrect" +)] pub(crate) struct AssociatedSuggestion2 { #[suggestion_part(code = "{args}")] pub span: Span, @@ -800,14 +916,14 @@ pub(crate) struct AssociatedSuggestion2 { } #[derive(Diagnostic)] -#[diag(ast_passes_feature_on_non_nightly, code = E0554)] +#[diag("`#![feature]` may not be used on the {$channel} release channel", code = E0554)] pub(crate) struct FeatureOnNonNightly { #[primary_span] pub span: Span, pub channel: &'static str, #[subdiagnostic] pub stable_features: Vec, - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the attribute", code = "", applicability = "machine-applicable")] pub sugg: Option, } @@ -820,13 +936,13 @@ impl Subdiagnostic for StableFeature { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.arg("name", self.name); diag.arg("since", self.since); - diag.help(fluent::ast_passes_stable_since); + diag.help(inline_fluent!("the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable")); } } #[derive(Diagnostic)] -#[diag(ast_passes_incompatible_features)] -#[help] +#[diag("`{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed")] +#[help("remove one of these features")] pub(crate) struct IncompatibleFeatures { #[primary_span] pub spans: Vec, @@ -835,28 +951,28 @@ pub(crate) struct IncompatibleFeatures { } #[derive(Diagnostic)] -#[diag(ast_passes_negative_bound_not_supported)] +#[diag("negative bounds are not supported")] pub(crate) struct NegativeBoundUnsupported { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_constraint_on_negative_bound)] +#[diag("associated type constraints not allowed on negative bounds")] pub(crate) struct ConstraintOnNegativeBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_negative_bound_with_parenthetical_notation)] +#[diag("parenthetical notation may not be used for negative bounds")] pub(crate) struct NegativeBoundWithParentheticalNotation { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_match_arm_with_no_body)] +#[diag("`match` arm with no body")] pub(crate) struct MatchArmWithNoBody { #[primary_span] pub span: Span, @@ -864,6 +980,7 @@ pub(crate) struct MatchArmWithNoBody { // any logic looking at the arm being replaced if there was a comma already or not for the // resulting code to be correct. #[suggestion( + "add a body after the pattern", code = " => {{ todo!() }}", applicability = "has-placeholders", style = "verbose" @@ -872,7 +989,7 @@ pub(crate) struct MatchArmWithNoBody { } #[derive(Diagnostic)] -#[diag(ast_passes_precise_capturing_not_allowed_here)] +#[diag("`use<...>` precise capturing syntax not allowed in {$loc}")] pub(crate) struct PreciseCapturingNotAllowedHere { #[primary_span] pub span: Span, @@ -880,39 +997,43 @@ pub(crate) struct PreciseCapturingNotAllowedHere { } #[derive(Diagnostic)] -#[diag(ast_passes_precise_capturing_duplicated)] +#[diag("duplicate `use<...>` precise capturing syntax")] pub(crate) struct DuplicatePreciseCapturing { #[primary_span] pub bound1: Span, - #[label] + #[label("second `use<...>` here")] pub bound2: Span, } #[derive(Diagnostic)] -#[diag(ast_passes_extern_without_abi)] -#[help] +#[diag("`extern` declarations without an explicit ABI are disallowed")] +#[help("prior to Rust 2024, a default ABI was inferred")] pub(crate) struct MissingAbi { #[primary_span] - #[suggestion(code = "extern \"\"", applicability = "has-placeholders")] + #[suggestion("specify an ABI", code = "extern \"\"", applicability = "has-placeholders")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(ast_passes_extern_without_abi_sugg)] +#[diag("`extern` declarations without an explicit ABI are deprecated")] pub(crate) struct MissingAbiSugg { - #[suggestion(code = "extern {default_abi}", applicability = "machine-applicable")] + #[suggestion( + "explicitly specify the {$default_abi} ABI", + code = "extern {default_abi}", + applicability = "machine-applicable" + )] pub span: Span, pub default_abi: ExternAbi, } #[derive(Diagnostic)] -#[diag(ast_passes_abi_custom_safe_foreign_function)] +#[diag("foreign functions with the \"custom\" ABI cannot be safe")] pub(crate) struct AbiCustomSafeForeignFunction { #[primary_span] pub span: Span, #[suggestion( - ast_passes_suggestion, + "remove the `safe` keyword from this definition", applicability = "maybe-incorrect", code = "", style = "verbose" @@ -921,14 +1042,14 @@ pub(crate) struct AbiCustomSafeForeignFunction { } #[derive(Diagnostic)] -#[diag(ast_passes_abi_custom_safe_function)] +#[diag("functions with the \"custom\" ABI must be unsafe")] pub(crate) struct AbiCustomSafeFunction { #[primary_span] pub span: Span, pub abi: ExternAbi, #[suggestion( - ast_passes_suggestion, + "add the `unsafe` keyword to this definition", applicability = "maybe-incorrect", code = "unsafe ", style = "verbose" @@ -937,14 +1058,14 @@ pub(crate) struct AbiCustomSafeFunction { } #[derive(Diagnostic)] -#[diag(ast_passes_abi_cannot_be_coroutine)] +#[diag("functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`")] pub(crate) struct AbiCannotBeCoroutine { #[primary_span] pub span: Span, pub abi: ExternAbi, #[suggestion( - ast_passes_suggestion, + "remove the `{$coroutine_kind_str}` keyword from this definition", applicability = "maybe-incorrect", code = "", style = "verbose" @@ -954,15 +1075,15 @@ pub(crate) struct AbiCannotBeCoroutine { } #[derive(Diagnostic)] -#[diag(ast_passes_abi_must_not_have_parameters_or_return_type)] -#[note] +#[diag("invalid signature for `extern {$abi}` function")] +#[note("functions with the {$abi} ABI cannot have any parameters or return type")] pub(crate) struct AbiMustNotHaveParametersOrReturnType { #[primary_span] pub spans: Vec, pub abi: ExternAbi, #[suggestion( - ast_passes_suggestion, + "remove the parameters and return type", applicability = "maybe-incorrect", code = "{padding}fn {symbol}()", style = "verbose" @@ -973,18 +1094,20 @@ pub(crate) struct AbiMustNotHaveParametersOrReturnType { } #[derive(Diagnostic)] -#[diag(ast_passes_abi_must_not_have_return_type)] -#[note] +#[diag("invalid signature for `extern {$abi}` function")] +#[note("functions with the {$abi} ABI cannot have a return type")] pub(crate) struct AbiMustNotHaveReturnType { #[primary_span] - #[help] + #[help("remove the return type")] pub span: Span, pub abi: ExternAbi, } #[derive(Diagnostic)] -#[diag(ast_passes_abi_x86_interrupt)] -#[note] +#[diag("invalid signature for `extern \"x86-interrupt\"` function")] +#[note( + "functions with the \"x86-interrupt\" ABI must be have either 1 or 2 parameters (but found {$param_count})" +)] pub(crate) struct AbiX86Interrupt { #[primary_span] pub spans: Vec, @@ -992,7 +1115,7 @@ pub(crate) struct AbiX86Interrupt { } #[derive(Diagnostic)] -#[diag(ast_passes_scalable_vector_not_tuple_struct)] +#[diag("scalable vectors must be tuple structs")] pub(crate) struct ScalableVectorNotTupleStruct { #[primary_span] pub span: Span, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 6376cab364db..1b1bbb1564c4 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,5 +1,6 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token}; +use rustc_errors::inline_fluent; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features}; use rustc_session::Session; use rustc_session::parse::{feature_err, feature_warn}; @@ -124,7 +125,7 @@ impl<'a> PostExpansionVisitor<'a> { &self, non_lifetime_binders, non_lt_param_spans, - crate::fluent_generated::ast_passes_forbidden_non_lifetime_param + inline_fluent!("only lifetime parameters can be used in this context") ); // FIXME(non_lifetime_binders): Const bound params are pretty broken. diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 06795a6be81e..2630348c49c1 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -11,5 +11,3 @@ pub mod ast_validation; mod errors; pub mod feature_gate; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index c24a4ca53219..37e856cd6d50 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -9,7 +9,6 @@ anstyle = "1.0.13" jiff = { version = "0.2.5", default-features = false, features = ["std"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 02298dbf8267..0a6f57f72e5d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -114,7 +114,6 @@ pub fn default_translator() -> Translator { pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ // tidy-alphabetical-start - rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, rustc_const_eval::DEFAULT_LOCALE_RESOURCE, From 67c6cd99b721309b32c3d4f484da4a856f32bef5 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 22:33:13 +0100 Subject: [PATCH 74/81] Convert to inline diagnostics in `rustc_pattern_analysis` --- Cargo.lock | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_pattern_analysis/Cargo.toml | 2 - compiler/rustc_pattern_analysis/messages.ftl | 31 ---------- compiler/rustc_pattern_analysis/src/errors.rs | 61 +++++++++++++------ compiler/rustc_pattern_analysis/src/lib.rs | 3 - 7 files changed, 41 insertions(+), 60 deletions(-) delete mode 100644 compiler/rustc_pattern_analysis/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 9c98946c9d39..1c97ec790d4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3796,7 +3796,6 @@ dependencies = [ "rustc_mir_transform", "rustc_parse", "rustc_passes", - "rustc_pattern_analysis", "rustc_public", "rustc_resolve", "rustc_session", @@ -4451,7 +4450,6 @@ dependencies = [ "rustc_arena", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index c24a4ca53219..653bf3902a26 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -33,7 +33,6 @@ rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_transform = { path = "../rustc_mir_transform" } rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } -rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } rustc_public = { path = "../rustc_public", features = ["rustc_internal"] } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 02298dbf8267..0ec8520217e1 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -125,7 +125,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, - rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml index a59f7bbeb9e5..a644c6a7c01a 100644 --- a/compiler/rustc_pattern_analysis/Cargo.toml +++ b/compiler/rustc_pattern_analysis/Cargo.toml @@ -11,7 +11,6 @@ rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena", optional = true } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_errors = { path = "../rustc_errors", optional = true } -rustc_fluent_macro = { path = "../rustc_fluent_macro", optional = true } rustc_hir = { path = "../rustc_hir", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } @@ -36,7 +35,6 @@ rustc = [ "dep:rustc_arena", "dep:rustc_data_structures", "dep:rustc_errors", - "dep:rustc_fluent_macro", "dep:rustc_hir", "dep:rustc_macros", "dep:rustc_middle", diff --git a/compiler/rustc_pattern_analysis/messages.ftl b/compiler/rustc_pattern_analysis/messages.ftl deleted file mode 100644 index d3a3107f8e89..000000000000 --- a/compiler/rustc_pattern_analysis/messages.ftl +++ /dev/null @@ -1,31 +0,0 @@ -pattern_analysis_excluside_range_missing_gap = multiple ranges are one apart - .label = this range doesn't match `{$gap}` because `..` is an exclusive range - .suggestion = use an inclusive range instead - -pattern_analysis_excluside_range_missing_max = exclusive range missing `{$max}` - .label = this range doesn't match `{$max}` because `..` is an exclusive range - .suggestion = use an inclusive range instead - -pattern_analysis_mixed_deref_pattern_constructors = mix of deref patterns and normal constructors - .deref_pattern_label = matches on the result of dereferencing `{$smart_pointer_ty}` - .normal_constructor_label = matches directly on `{$smart_pointer_ty}` - -pattern_analysis_non_exhaustive_omitted_pattern = some variants are not matched explicitly - .help = ensure that all variants are matched explicitly by adding the suggested match arms - .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found - -pattern_analysis_non_exhaustive_omitted_pattern_lint_on_arm = the lint level must be set on the whole match - .help = it no longer has any effect to set the lint level on an individual match arm - .label = remove this attribute - .suggestion = set the lint level on the whole match - -pattern_analysis_overlapping_range_endpoints = multiple patterns overlap on their endpoints - .label = ... with this range - .note = you likely meant to write mutually exclusive ranges - -pattern_analysis_uncovered = {$count -> - [1] pattern `{$witness_1}` - [2] patterns `{$witness_1}` and `{$witness_2}` - [3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}` - *[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and {$remainder} more - } not covered diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs index 156ba9737673..64d4ff422043 100644 --- a/compiler/rustc_pattern_analysis/src/errors.rs +++ b/compiler/rustc_pattern_analysis/src/errors.rs @@ -6,7 +6,14 @@ use rustc_span::Span; use crate::rustc::{RustcPatCtxt, WitnessPat}; #[derive(Subdiagnostic)] -#[label(pattern_analysis_uncovered)] +#[label( + "{$count -> + [1] pattern `{$witness_1}` + [2] patterns `{$witness_1}` and `{$witness_2}` + [3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}` + *[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and {$remainder} more + } not covered" +)] pub struct Uncovered { #[primary_span] span: Span, @@ -40,10 +47,10 @@ impl Uncovered { } #[derive(LintDiagnostic)] -#[diag(pattern_analysis_overlapping_range_endpoints)] -#[note] +#[diag("multiple patterns overlap on their endpoints")] +#[note("you likely meant to write mutually exclusive ranges")] pub struct OverlappingRangeEndpoints { - #[label] + #[label("... with this range")] pub range: Span, #[subdiagnostic] pub overlap: Vec, @@ -66,10 +73,14 @@ impl Subdiagnostic for Overlap { } #[derive(LintDiagnostic)] -#[diag(pattern_analysis_excluside_range_missing_max)] +#[diag("exclusive range missing `{$max}`")] pub struct ExclusiveRangeMissingMax { - #[label] - #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")] + #[label("this range doesn't match `{$max}` because `..` is an exclusive range")] + #[suggestion( + "use an inclusive range instead", + code = "{suggestion}", + applicability = "maybe-incorrect" + )] /// This is an exclusive range that looks like `lo..max` (i.e. doesn't match `max`). pub first_range: Span, /// Suggest `lo..=max` instead. @@ -78,10 +89,14 @@ pub struct ExclusiveRangeMissingMax { } #[derive(LintDiagnostic)] -#[diag(pattern_analysis_excluside_range_missing_gap)] +#[diag("multiple ranges are one apart")] pub struct ExclusiveRangeMissingGap { - #[label] - #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")] + #[label("this range doesn't match `{$gap}` because `..` is an exclusive range")] + #[suggestion( + "use an inclusive range instead", + code = "{suggestion}", + applicability = "maybe-incorrect" + )] /// This is an exclusive range that looks like `lo..gap` (i.e. doesn't match `gap`). pub first_range: Span, pub gap: String, // a printed pattern @@ -113,9 +128,11 @@ impl Subdiagnostic for GappedRange { } #[derive(LintDiagnostic)] -#[diag(pattern_analysis_non_exhaustive_omitted_pattern)] -#[help] -#[note] +#[diag("some variants are not matched explicitly")] +#[help("ensure that all variants are matched explicitly by adding the suggested match arms")] +#[note( + "the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found" +)] pub(crate) struct NonExhaustiveOmittedPattern<'tcx> { pub scrut_ty: Ty<'tcx>, #[subdiagnostic] @@ -123,25 +140,29 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> { } #[derive(LintDiagnostic)] -#[diag(pattern_analysis_non_exhaustive_omitted_pattern_lint_on_arm)] -#[help] +#[diag("the lint level must be set on the whole match")] +#[help("it no longer has any effect to set the lint level on an individual match arm")] pub(crate) struct NonExhaustiveOmittedPatternLintOnArm { - #[label] + #[label("remove this attribute")] pub lint_span: Span, - #[suggestion(code = "#[{lint_level}({lint_name})]\n", applicability = "maybe-incorrect")] + #[suggestion( + "set the lint level on the whole match", + code = "#[{lint_level}({lint_name})]\n", + applicability = "maybe-incorrect" + )] pub suggest_lint_on_match: Option, pub lint_level: &'static str, pub lint_name: &'static str, } #[derive(Diagnostic)] -#[diag(pattern_analysis_mixed_deref_pattern_constructors)] +#[diag("mix of deref patterns and normal constructors")] pub(crate) struct MixedDerefPatternConstructors<'tcx> { #[primary_span] pub spans: Vec, pub smart_pointer_ty: Ty<'tcx>, - #[label(pattern_analysis_deref_pattern_label)] + #[label("matches on the result of dereferencing `{$smart_pointer_ty}`")] pub deref_pattern_label: Span, - #[label(pattern_analysis_normal_constructor_label)] + #[label("matches directly on `{$smart_pointer_ty}`")] pub normal_constructor_label: Span, } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 265284086377..9ffc237c6329 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -19,9 +19,6 @@ pub mod pat_column; pub mod rustc; pub mod usefulness; -#[cfg(feature = "rustc")] -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - use std::fmt; pub use rustc_index::{Idx, IndexVec}; // re-exported to avoid rustc_index version issues From e55eb4566152bbed506f4916ddec3817c2a76f42 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 4 Feb 2026 16:27:09 +0100 Subject: [PATCH 75/81] Convert to inline diagnostics in `rustc_errors` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_errors/Cargo.toml | 1 - compiler/rustc_errors/messages.ftl | 48 ----------------- compiler/rustc_errors/src/diagnostic_impls.rs | 54 ++++++++++++------- compiler/rustc_errors/src/json/tests.rs | 3 +- compiler/rustc_errors/src/lib.rs | 13 +++-- compiler/rustc_session/src/session.rs | 3 +- 8 files changed, 45 insertions(+), 79 deletions(-) delete mode 100644 compiler/rustc_errors/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 9c98946c9d39..a5882a14faf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3846,7 +3846,6 @@ dependencies = [ "rustc_data_structures", "rustc_error_codes", "rustc_error_messages", - "rustc_fluent_macro", "rustc_hashes", "rustc_index", "rustc_lint_defs", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 02298dbf8267..085953bc4b84 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -118,7 +118,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, rustc_const_eval::DEFAULT_LOCALE_RESOURCE, - rustc_errors::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, rustc_middle::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 81eecca3199f..a81fc496c828 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -14,7 +14,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_errors/messages.ftl b/compiler/rustc_errors/messages.ftl deleted file mode 100644 index ad2e206260d5..000000000000 --- a/compiler/rustc_errors/messages.ftl +++ /dev/null @@ -1,48 +0,0 @@ -errors_delayed_at_with_newline = - delayed at {$emitted_at} - {$note} - -errors_delayed_at_without_newline = - delayed at {$emitted_at} - {$note} - -errors_expected_lifetime_parameter = - expected lifetime {$count -> - [1] parameter - *[other] parameters - } - -errors_indicate_anonymous_lifetime = - indicate the anonymous {$count -> - [1] lifetime - *[other] lifetimes - } - -errors_invalid_flushed_delayed_diagnostic_level = - `flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug` - -errors_target_inconsistent_architecture = - inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}` - -errors_target_inconsistent_pointer_width = - inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}` - -errors_target_invalid_address_space = - invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err} - -errors_target_invalid_alignment = - invalid alignment for `{$cause}` in "data-layout": `{$align}` is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {""} - } - -errors_target_invalid_bits = - invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err} - -errors_target_invalid_bits_size = {$err} - -errors_target_invalid_datalayout_pointer_spec = - unknown pointer specification `{$err}` in datalayout string - -errors_target_missing_alignment = - missing alignment for `{$cause}` in "data-layout" diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 435d16a83806..c36afc6fc889 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -7,8 +7,7 @@ use rustc_span::{Span, Symbol}; use crate::diagnostic::DiagLocation; use crate::{ - Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, - fluent_generated as fluent, + Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, inline_fluent, }; impl IntoDiagArg for DiagLocation { @@ -44,43 +43,48 @@ impl Diagnostic<'_, G> for TargetDataLayoutErrors<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { - Diag::new(dcx, level, fluent::errors_target_invalid_address_space) + Diag::new(dcx, level, inline_fluent!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("addr_space", addr_space) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_bits) + Diag::new(dcx, level, inline_fluent!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("kind", kind) .with_arg("bit", bit) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::MissingAlignment { cause } => { - Diag::new(dcx, level, fluent::errors_target_missing_alignment) + Diag::new(dcx, level, inline_fluent!("missing alignment for `{$cause}` in \"data-layout\"")) .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_alignment) - .with_arg("cause", cause) - .with_arg("err_kind", err.diag_ident()) - .with_arg("align", err.align()) + Diag::new(dcx, level, inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }")) + .with_arg("cause", cause) + .with_arg("err_kind", err.diag_ident()) + .with_arg("align", err.align()) } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { - Diag::new(dcx, level, fluent::errors_target_inconsistent_architecture) - .with_arg("dl", dl) - .with_arg("target", target) + Diag::new(dcx, level, inline_fluent!( + "inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`" + )) + .with_arg("dl", dl).with_arg("target", target) } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { - Diag::new(dcx, level, fluent::errors_target_inconsistent_pointer_width) - .with_arg("pointer_size", pointer_size) - .with_arg("target", target) + Diag::new(dcx, level, inline_fluent!( + "inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`" + )).with_arg("pointer_size", pointer_size).with_arg("target", target) } TargetDataLayoutErrors::InvalidBitsSize { err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_bits_size).with_arg("err", err) + Diag::new(dcx, level, inline_fluent!("{$err}")).with_arg("err", err) } TargetDataLayoutErrors::UnknownPointerSpecification { err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_datalayout_pointer_spec) + Diag::new(dcx, level, inline_fluent!("unknown pointer specification `{$err}` in datalayout string")) .with_arg("err", err) } } @@ -99,7 +103,12 @@ impl Subdiagnostic for SingleLabelManySpans { } #[derive(Subdiagnostic)] -#[label(errors_expected_lifetime_parameter)] +#[label( + "expected lifetime {$count -> + [1] parameter + *[other] parameters + }" +)] pub struct ExpectedLifetimeParameter { #[primary_span] pub span: Span, @@ -107,7 +116,14 @@ pub struct ExpectedLifetimeParameter { } #[derive(Subdiagnostic)] -#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")] +#[suggestion( + "indicate the anonymous {$count -> + [1] lifetime + *[other] lifetimes + }", + code = "{suggestion}", + style = "verbose" +)] pub struct IndicateAnonymousLifetime { #[primary_span] pub span: Span, diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index c1c9ecf7198f..6f99930c433b 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -45,8 +45,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { rustc_span::create_default_session_globals_then(|| { let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); sm.new_source_file(filename(&sm, "test.rs"), code.to_owned()); - let translator = - Translator::with_fallback_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false); + let translator = Translator::with_fallback_bundle(vec![], false); let output = Arc::new(Mutex::new(Vec::new())); let je = JsonEmitter::new( diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 68d825a4514a..f89a2af71022 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -92,8 +92,6 @@ pub mod translation; pub type PResult<'a, T> = Result>; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24); @@ -1531,7 +1529,9 @@ impl DiagCtxtInner { // the usual `Diag`/`DiagCtxt` level, so we must augment `bug` // in a lower-level fashion. bug.arg("level", bug.level); - let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level; + let msg = inline_fluent!( + "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`" + ); let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call bug.sub(Note, msg, bug.span.primary_span().unwrap().into()); } @@ -1573,10 +1573,13 @@ impl DelayedDiagInner { // lower-level fashion. let mut diag = self.inner; let msg = match self.note.status() { - BacktraceStatus::Captured => crate::fluent_generated::errors_delayed_at_with_newline, + BacktraceStatus::Captured => inline_fluent!( + "delayed at {$emitted_at} +{$note}" + ), // Avoid the needless newline when no backtrace has been captured, // the display impl should just be a single line. - _ => crate::fluent_generated::errors_delayed_at_without_newline, + _ => inline_fluent!("delayed at {$emitted_at} - {$note}"), }; diag.arg("emitted_at", diag.emitted_at.clone()); diag.arg("note", self.note); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 26efa03c898c..298b25088151 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1432,8 +1432,7 @@ impl EarlyDiagCtxt { fn mk_emitter(output: ErrorOutputType) -> Box { // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will // need to reference every crate that might emit an early error for translation to work. - let translator = - Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); + let translator = Translator::with_fallback_bundle(vec![], false); let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { HumanReadableErrorType { short, unicode } => Box::new( From edeb02f3828aedb3dac3c32553842e6a4d01d422 Mon Sep 17 00:00:00 2001 From: "Eddy (Eduard) Stefes" Date: Thu, 5 Feb 2026 13:36:18 +0100 Subject: [PATCH 76/81] disable s390x vector intrinsics if softfloat is enabled we will add an explicit incompatibility of softfloat and vector feature in rutsc s390x-unknown-none-softfloat target specification. Therefore we need to disable vector intrinsics here to be able to compile core for this target. --- library/stdarch/crates/core_arch/src/s390x/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/s390x/mod.rs b/library/stdarch/crates/core_arch/src/s390x/mod.rs index 7d3b3f2d99aa..5b85020072d8 100644 --- a/library/stdarch/crates/core_arch/src/s390x/mod.rs +++ b/library/stdarch/crates/core_arch/src/s390x/mod.rs @@ -2,6 +2,11 @@ pub(crate) mod macros; +/// the float and vector registers overlap therefore we cannot use any vector +/// extensions if softfloat is enabled. + +#[cfg(not(target_abi = "softfloat"))] mod vector; +#[cfg(not(target_abi = "softfloat"))] #[unstable(feature = "stdarch_s390x", issue = "130869")] pub use self::vector::*; From bce8c00e2f6bbd0d68a42fc7ee09b9eae6303f33 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 01:13:41 +0100 Subject: [PATCH 77/81] Remove the 4 failing tests from rustdoc-gui --- tests/rustdoc-gui/headers-color.goml | 71 ----- tests/rustdoc-gui/notable-trait.goml | 256 ------------------- tests/rustdoc-gui/search-filter.goml | 86 ------- tests/rustdoc-gui/search-result-display.goml | 114 --------- 4 files changed, 527 deletions(-) delete mode 100644 tests/rustdoc-gui/headers-color.goml delete mode 100644 tests/rustdoc-gui/notable-trait.goml delete mode 100644 tests/rustdoc-gui/search-filter.goml delete mode 100644 tests/rustdoc-gui/search-result-display.goml diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml deleted file mode 100644 index 81346fc12d06..000000000000 --- a/tests/rustdoc-gui/headers-color.goml +++ /dev/null @@ -1,71 +0,0 @@ -// This test check for headings text and background colors for the different themes. - -include: "utils.goml" - -define-function: ( - "check-colors", - [theme, color, code_header_color, focus_background_color, headings_color], - block { - go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" - // This is needed so that the text color is computed. - show-text: true - call-function: ("switch-theme", {"theme": |theme|}) - assert-css: ( - ".impl", - {"color": |color|, "background-color": "rgba(0, 0, 0, 0)"}, - ALL, - ) - assert-css: ( - ".impl .code-header", - {"color": |code_header_color|, "background-color": "rgba(0, 0, 0, 0)"}, - ALL, - ) - go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#impl-Foo" - assert-css: ( - "#impl-Foo", - {"color": |color|, "background-color": |focus_background_color|}, - ) - go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#method.must_use" - assert-css: ( - "#method\.must_use", - {"color": |color|, "background-color": |focus_background_color|}, - ALL, - ) - go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" - assert-css: (".section-header a", {"color": |color|}, ALL) - go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" - // We select headings (h2, h3, h...). - assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL) - }, -) - -call-function: ( - "check-colors", - { - "theme": "ayu", - "color": "#c5c5c5", - "code_header_color": "#e6e1cf", - "focus_background_color": "rgba(255, 236, 164, 0.06)", - "headings_color": "#c5c5c5", - }, -) -call-function: ( - "check-colors", - { - "theme": "dark", - "color": "#ddd", - "code_header_color": "#ddd", - "focus_background_color": "#494a3d", - "headings_color": "#ddd", - }, -) -call-function: ( - "check-colors", - { - "theme": "light", - "color": "black", - "code_header_color": "black", - "focus_background_color": "#fdffd3", - "headings_color": "black", - }, -) diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml deleted file mode 100644 index 8e4c180e0ef1..000000000000 --- a/tests/rustdoc-gui/notable-trait.goml +++ /dev/null @@ -1,256 +0,0 @@ -// This test checks the position of the `i` for the notable traits. -include: "utils.goml" -go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" -show-text: true - -define-function: ( - "check-notable-tooltip-position", - [x, i_x], - block { - // Checking they have the same y position. - compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - {"y": 1}, - ) - // Checking they don't have the same x position. - compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ["x"], - ) - // The `i` should be *after* the type. - assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", - {"x": |x|}, - ) - assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - {"x": |i_x|}, - ) - }, -) - -define-function: ( - "check-notable-tooltip-position-complete", - [x, i_x, popover_x], - block { - call-function: ("check-notable-tooltip-position", {"x": |x|, "i_x": |i_x|}) - assert-count: ("//*[@class='tooltip popover']", 0) - click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" - assert-count: ("//*[@class='tooltip popover']", 1) - compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - "//*[@class='tooltip popover']", - {"y": 30} - ) - compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - "//*[@class='tooltip popover']", - ["x"] - ) - assert-position: ( - "//*[@class='tooltip popover']", - {"x": |popover_x|} - ) - click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" - move-cursor-to: "//h1" - assert-count: ("//*[@class='tooltip popover']", 0) - }, -) - -// We start with a wide screen. -set-window-size: (1100, 600) -call-function: ("check-notable-tooltip-position-complete", { - "x": 682, - "i_x": 960, - "popover_x": 468, -}) - -// Now only the `i` should be on the next line. -set-window-size: (1055, 600) -compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ["y", "x"], -) - -// Now both the `i` and the struct name should be on the next line. -set-window-size: (980, 600) -call-function: ("check-notable-tooltip-position", { - "x": 250, - "i_x": 528, -}) - -go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" -// This is needed to ensure that the text color is computed. -show-text: true - -// Now check the colors. -define-function: ( - "check-colors", - [theme, header_color, content_color, type_color, trait_color, link_color], - block { - call-function: ("switch-theme", {"theme": |theme|}) - - assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - {"color": |content_color|}, - ALL, - ) - - move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" - wait-for-count: (".tooltip.popover", 1) - - assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - {"color": |link_color|}, - ALL, - ) - - assert-css: ( - ".tooltip.popover h3", - {"color": |header_color|}, - ALL, - ) - assert-css: ( - ".tooltip.popover pre", - {"color": |content_color|}, - ALL, - ) - assert-css: ( - ".tooltip.popover pre a.struct", - {"color": |type_color|}, - ALL, - ) - assert-css: ( - ".tooltip.popover pre a.trait", - {"color": |trait_color|}, - ALL, - ) - }, -) - -call-function: ( - "check-colors", - { - "theme": "ayu", - "link_color": "#39afd7", - "content_color": "#e6e1cf", - "header_color": "#fff", - "type_color": "#ffa0a5", - "trait_color": "#39afd7", - }, -) - -call-function: ( - "check-colors", - { - "theme": "dark", - "link_color": "#d2991d", - "content_color": "#ddd", - "header_color": "#ddd", - "type_color": "#2dbfb8", - "trait_color": "#b78cf2", - }, -) - -call-function: ( - "check-colors", - { - "theme": "light", - "link_color": "#3873ad", - "content_color": "black", - "header_color": "black", - "type_color": "#ad378a", - "trait_color": "#6e4fc9", - }, -) - -// Checking on mobile now. -set-window-size: (650, 600) -wait-for-size: ("body", {"width": 650}) -call-function: ("check-notable-tooltip-position-complete", { - "x": 26, - "i_x": 305, - "popover_x": 0, -}) - -reload: - -// Check that pressing escape works -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -move-cursor-to: "//*[@class='tooltip popover']" -assert-count: ("//*[@class='tooltip popover']", 1) -press-key: "Escape" -assert-count: ("//*[@class='tooltip popover']", 0) -assert: "#method\.create_an_iterator_from_read .tooltip:focus" - -// Check that clicking outside works. -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -assert-count: ("//*[@class='tooltip popover']", 1) -click: ".main-heading h1" -assert-count: ("//*[@class='tooltip popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" - -// Check that pressing tab over and over works. -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -move-cursor-to: "//*[@class='tooltip popover']" -assert-count: ("//*[@class='tooltip popover']", 1) -press-key: "Tab" -press-key: "Tab" -press-key: "Tab" -press-key: "Tab" -press-key: "Tab" -press-key: "Tab" -press-key: "Tab" -assert-count: ("//*[@class='tooltip popover']", 0) -assert: "#method\.create_an_iterator_from_read .tooltip:focus" - -define-function: ( - "setup-popup", - [], - block { - store-window-property: {"scrollY": scroll} - click: "#method\.create_an_iterator_from_read .fn" - // We ensure that the scroll position changed. - assert-window-property-false: {"scrollY": |scroll|} - // Store the new position. - store-window-property: {"scrollY": scroll} - click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" - wait-for: "//*[@class='tooltip popover']" - click: ".main-heading h1" - } -) - -// Now we check that the focus isn't given back to the wrong item when opening -// another popover. -call-function: ("setup-popup", {}) -click: ".main-heading h1" -// We ensure we didn't come back to the previous focused item. -assert-window-property-false: {"scrollY": |scroll|} - -// Same but with Escape handling. -call-function: ("setup-popup", {}) -press-key: "Escape" -// We ensure we didn't come back to the previous focused item. -assert-window-property-false: {"scrollY": |scroll|} - -// Opening the mobile sidebar should close the popover. -set-window-size: (650, 600) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -assert-count: ("//*[@class='tooltip popover']", 1) -click: ".sidebar-menu-toggle" -assert: "//*[@class='sidebar shown']" -assert-count: ("//*[@class='tooltip popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" - -// Also check the focus handling for the settings button. -set-window-size: (1100, 600) -reload: -assert-count: ("//*[@class='tooltip popover']", 0) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -wait-for-count: ("//*[@class='tooltip popover']", 1) -call-function: ("open-settings-menu", {}) -wait-for-count: ("//*[@class='tooltip popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml deleted file mode 100644 index 6bd7eaa92063..000000000000 --- a/tests/rustdoc-gui/search-filter.goml +++ /dev/null @@ -1,86 +0,0 @@ -// Checks that the crate search filtering is handled correctly and changes the results. -include: "utils.goml" -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -show-text: true -call-function: ("perform-search", {"query": "test"}) -assert-text: ("#results .externcrate", "test_docs") - -wait-for: "#crate-search" -// We now want to change the crate filter. -click: "#crate-search" -// We select "lib2" option then press enter to change the filter. -press-key: "ArrowDown" -press-key: "ArrowDown" -press-key: "ArrowDown" -press-key: "ArrowDown" -press-key: "ArrowDown" -press-key: "Enter" -// Waiting for the search results to appear... -wait-for: "#search-tabs" -wait-for-false: "#search-tabs .count.loading" -assert-document-property: ({"URL": "&filter-crate="}, CONTAINS) -// We check that there is no more "test_docs" appearing. -assert-false: "#results .externcrate" -// We also check that "lib2" is the filter crate. -assert-property: ("#crate-search", {"value": "lib2"}) - -// Now we check that leaving the search results and putting them back keeps the -// crate filtering. -press-key: "Escape" -wait-for-css: ("#main-content", {"display": "block"}) -click: "#search-button" -wait-for: ".search-input" -wait-for-css: ("#main-content", {"display": "none"}) -// We check that there is no more "test_docs" appearing. -assert-false: "#results .externcrate" -assert-property: ("#crate-search", {"value": "lib2"}) - -// Selecting back "All crates" -click: "#crate-search" -press-key: "ArrowUp" -press-key: "ArrowUp" -press-key: "ArrowUp" -press-key: "ArrowUp" -press-key: "ArrowUp" -press-key: "Enter" -// Waiting for the search results to appear... -wait-for: "#search-tabs" -wait-for-false: "#search-tabs .count.loading" -assert-property: ("#crate-search", {"value": "all crates"}) - -// Checking that the URL parameter is taken into account for crate filtering. -go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=test&filter-crate=lib2" -wait-for: "#crate-search" -assert-property: ("#crate-search", {"value": "lib2"}) -assert-false: "#results .externcrate" - -// Checking that the text for the "title" is correct (the "all crates" comes from the "` is correctly handled when it goes to next line. -// To do so we need to update the length of one of its `