diff --git a/shells/nu_plugin_polars/files/patch-rust-1.97.0 b/shells/nu_plugin_polars/files/patch-rust-1.97.0 new file mode 100644 index 000000000000..a7478fd20425 --- /dev/null +++ b/shells/nu_plugin_polars/files/patch-rust-1.97.0 @@ -0,0 +1,131 @@ +From 87e3457c095c98fcac554548ee80f56e0cfb80ae Mon Sep 17 00:00:00 2001 +From: YangJie +Date: Mon, 20 Apr 2026 23:31:00 +0800 +Subject: [PATCH] fix: replace transmute UB in error constructors with safe + alternatives (#58) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +## Summary + +`pie()` used `unsafe { mem::transmute(kind) }` to create a +`ParseIntError` from an `IntErrorKind`, and `tfie()` used `unsafe { +mem::transmute(()) }` to create a `TryFromIntError`. Both rely on +unstable internal layouts of standard library types. + +Starting with Rust nightly `nightly-2026-04-18` (commit `e9e32aca5`, +2026-04-17) on Linux x86_64, `TryFromIntError` grew from 0 to 1 byte, +causing `tfie()` to fail at compile time: + +``` +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> src/error.rs:16:14 + | +16 | unsafe { mem::transmute(()) } + | ^^^^^^^^^^^^^^ + | + = note: source type: `()` (0 bits) + = note: target type: `TryFromIntError` (8 bits) +``` + +`pie()` still compiles today but is equally fragile — it depends on +`IntErrorKind` and `ParseIntError` having the same layout. + +## Changes + +Replace both functions with safe stdlib operations: + +- **`pie(kind)`**: `unsafe { mem::transmute(kind) }` → match on +`IntErrorKind` and trigger real parse errors via `from_str_radix`. Stays +`const fn`. +- **`tfie()`**: `unsafe { mem::transmute(()) }` → +`u8::try_from(-1i8).unwrap_err()`. No longer `const fn` since `TryFrom` +isn't const-stable yet, but no call site uses it in const context. + +Other changes per review feedback: +- Use `unreachable!()` for the wildcard match arm (internal-only input) +- Remove `IntErrorKind::Zero` from `pie()` (not used by the library) + +## Verification + +- All 207 existing tests pass on stable, nightly (macOS), and nightly +(Linux x86_64 via Docker) +- Confirmed the original code **fails to compile** on +`nightly-2026-04-18` Linux x86_64 +- Confirmed the fix **compiles and passes** on `nightly-2026-04-18` +Linux x86_64 +- All CI lint checks pass: `cargo fmt`, `cargo clippy` (workspace, +serde, macros, llvm-intrinsics) +--- + src/error.rs | 42 +++++++++++++++++++++++++++--------------- + 1 file changed, 27 insertions(+), 15 deletions(-) + +diff --git a/src/error.rs b/src/error.rs +index be09e79..117dd5a 100644 +--- cargo-crates/ethnum-1.5.2/src/error.rs ++++ cargo-crates/ethnum-1.5.2/src/error.rs +@@ -1,25 +1,41 @@ +-//! Module with hacks for creating error variants for standard library errors +-//! without public interfaces. ++//! Module with safe helpers for creating error variants for standard library ++//! errors without public constructors. + +-use core::{ +- mem, +- num::{IntErrorKind, ParseIntError, TryFromIntError}, +-}; ++use core::num::{IntErrorKind, ParseIntError, TryFromIntError}; + +-/// Returns a `ParseIntError` from an `IntErrorKind`. ++/// Returns a `ParseIntError` with the specified `IntErrorKind`. + pub const fn pie(kind: IntErrorKind) -> ParseIntError { +- unsafe { mem::transmute(kind) } ++ match kind { ++ IntErrorKind::Empty => u8_parse_error(""), ++ IntErrorKind::InvalidDigit => u8_parse_error("?"), ++ IntErrorKind::PosOverflow => u8_parse_error("256"), ++ IntErrorKind::NegOverflow => i8_parse_error("-129"), ++ _ => unreachable!(), ++ } ++} ++ ++const fn u8_parse_error(s: &str) -> ParseIntError { ++ let Err(err) = u8::from_str_radix(s, 10) else { ++ panic!("not a parse error!"); ++ }; ++ err ++} ++ ++const fn i8_parse_error(s: &str) -> ParseIntError { ++ let Err(err) = i8::from_str_radix(s, 10) else { ++ panic!("not a parse error!"); ++ }; ++ err + } + + /// Returns a `TryFromIntError`. +-pub const fn tfie() -> TryFromIntError { +- unsafe { mem::transmute(()) } ++pub fn tfie() -> TryFromIntError { ++ u8::try_from(-1i8).unwrap_err() + } + + #[cfg(test)] + mod tests { + use super::*; +- use core::num::NonZeroU32; + + #[test] + #[allow(clippy::from_str_radix_10)] +@@ -40,10 +56,6 @@ mod tests { + pie(IntErrorKind::NegOverflow), + i8::from_str_radix("-1337", 10).unwrap_err(), + ); +- assert_eq!( +- pie(IntErrorKind::Zero), +- "0".parse::().unwrap_err(), +- ); + } + + #[test]