diff --git a/RELEASES.md b/RELEASES.md index f180d740a3d17..a8ebb8343c017 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,17 @@ +Version 1.94.1 (2026-03-26) +=========================== + + + +* [Fix `std::thread::spawn` on wasm32-wasip1-threads](https://github.com/rust-lang/rust/pull/153634) +* [Remove new methods added to `std::os::windows::fs::OpenOptionsExt`](https://github.com/rust-lang/rust/pull/153491) + The new methods were unstable, but the trait itself is not sealed and so + cannot be extended with non-default methods. +* [[Clippy] Fix ICE in `match_same_arms`](https://github.com/rust-lang/rust-clippy/pull/16685) +* [[Cargo] Update tar to 0.4.45](https://github.com/rust-lang/cargo/pull/16769) + This resolves CVE-2026-33055 and CVE-2026-33056. Users of crates.io are not affected. + See [blog](https://blog.rust-lang.org/2026/03/21/cve-2026-33056/) for more details. + Version 1.94.0 (2026-03-05) ========================== diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index 73f3e589e2432..7fd46b31f7d83 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -138,6 +138,8 @@ impl FileExt for fs::File { } /// Windows-specific extensions to [`fs::OpenOptions`]. +// WARNING: This trait is not sealed. DON'T add any new methods! +// Add them to OpenOptionsExt2 instead. #[stable(feature = "open_options_ext", since = "1.10.0")] pub trait OpenOptionsExt { /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`] @@ -305,18 +307,6 @@ pub trait OpenOptionsExt { /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut Self; - - /// If set to `true`, prevent the "last access time" of the file from being changed. - /// - /// Default to `false`. - #[unstable(feature = "windows_freeze_file_times", issue = "149715")] - fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; - - /// If set to `true`, prevent the "last write time" of the file from being changed. - /// - /// Default to `false`. - #[unstable(feature = "windows_freeze_file_times", issue = "149715")] - fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; } #[stable(feature = "open_options_ext", since = "1.10.0")] @@ -345,7 +335,28 @@ impl OpenOptionsExt for OpenOptions { self.as_inner_mut().security_qos_flags(flags); self } +} + +#[unstable(feature = "windows_freeze_file_times", issue = "149715")] +pub trait OpenOptionsExt2: Sealed { + /// If set to `true`, prevent the "last access time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; + + /// If set to `true`, prevent the "last write time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; +} + +#[unstable(feature = "sealed", issue = "none")] +impl Sealed for OpenOptions {} +#[unstable(feature = "windows_freeze_file_times", issue = "149715")] +impl OpenOptionsExt2 for OpenOptions { fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self { self.as_inner_mut().freeze_last_access_time(freeze); self diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 6f23c28c04d6a..430e699e098e6 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -49,7 +49,10 @@ impl Thread { // WASI does not support threading via pthreads. While wasi-libc provides // pthread stubs, pthread_create returns EAGAIN, which causes confusing // errors. We return UNSUPPORTED_PLATFORM directly instead. - if cfg!(target_os = "wasi") { + + // NOTE: exempt `wasm32-wasip1-threads` from this check as `emnapi` has a working pthread + // implementation. See . + if cfg!(all(target_os = "wasi", not(all(target_env = "p1", target_feature = "atomics")))) { return Err(io::Error::UNSUPPORTED_PLATFORM); } diff --git a/src/tools/cargo b/src/tools/cargo index 85eff7c80277b..292f395c297d4 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 85eff7c80277b57f78b11e28d14154ab12fcf643 +Subproject commit 292f395c297d4f99171325b0842ac4ea4ff3b386 diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index c20217563d62b..3976529f96120 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExpr, PatExprKind, PatKind, RangeEnd}; use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty; +use rustc_middle::ty::{self, TypeckResults}; use rustc_span::{ByteSymbol, ErrorGuaranteed, Span, Symbol}; use super::MATCH_SAME_ARMS; @@ -61,7 +61,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { let check_eq_with_pat = |expr_a: &Expr<'_>, expr_b: &Expr<'_>| { let mut local_map: HirIdMap = HirIdMap::default(); - let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| { + let eq_fallback = |a_typeck_results: &TypeckResults<'tcx>, + a: &Expr<'_>, + b_typeck_results: &TypeckResults<'tcx>, + b: &Expr<'_>| { if let Some(a_id) = a.res_local_id() && let Some(b_id) = b.res_local_id() && let entry = match local_map.entry(a_id) { @@ -71,7 +74,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { } // the names technically don't have to match; this makes the lint more conservative && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id) - && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b) + && a_typeck_results.expr_ty(a) == b_typeck_results.expr_ty(b) && pat_contains_local(lhs.pat, a_id) && pat_contains_local(rhs.pat, b_id) { diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs index 7b10c37de42df..d2e593fc17df8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp}; use rustc_lint::LateContext; +use rustc_middle::ty::TypeckResults; use rustc_middle::ty::adjustment::Adjust; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol}; @@ -136,7 +137,9 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // .map(|y| y[.acceptable_method()].unwrap()) && let simple_equal = (receiver.res_local_id() == Some(filter_param_id) && map_arg_peeled.res_local_id() == Some(map_param_id)) - && let eq_fallback = (|a: &Expr<'_>, b: &Expr<'_>| { + && let eq_fallback = + (|a_typeck_results: &TypeckResults<'tcx>, a: &Expr<'_>, + b_typeck_results: &TypeckResults<'tcx>, b: &Expr<'_>| { // in `filter(|x| ..)`, replace `*x` with `x` let a_path = if !is_filter_param_ref && let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind @@ -144,7 +147,7 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // let the filter closure arg and the map closure arg be equal a_path.res_local_id() == Some(filter_param_id) && b.res_local_id() == Some(map_param_id) - && cx.typeck_results().expr_ty_adjusted(a) == cx.typeck_results().expr_ty_adjusted(b) + && a_typeck_results.expr_ty_adjusted(a) == b_typeck_results.expr_ty_adjusted(b) }) && (simple_equal || SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(receiver, map_arg_peeled)) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c7bb3a064a093..df121d24b6aea 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -26,7 +26,8 @@ use std::slice; /// Callback that is called when two expressions are not equal in the sense of `SpanlessEq`, but /// other conditions would make them equal. -type SpanlessEqCallback<'a> = dyn FnMut(&Expr<'_>, &Expr<'_>) -> bool + 'a; +type SpanlessEqCallback<'a, 'tcx> = + dyn FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a; /// Determines how paths are hashed and compared for equality. #[derive(Copy, Clone, Debug, Default)] @@ -59,7 +60,7 @@ pub struct SpanlessEq<'a, 'tcx> { cx: &'a LateContext<'tcx>, maybe_typeck_results: Option<(&'tcx TypeckResults<'tcx>, &'tcx TypeckResults<'tcx>)>, allow_side_effects: bool, - expr_fallback: Option>>, + expr_fallback: Option>>, path_check: PathCheck, } @@ -94,7 +95,10 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { } #[must_use] - pub fn expr_fallback(self, expr_fallback: impl FnMut(&Expr<'_>, &Expr<'_>) -> bool + 'a) -> Self { + pub fn expr_fallback( + self, + expr_fallback: impl FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a, + ) -> Self { Self { expr_fallback: Some(Box::new(expr_fallback)), ..self @@ -639,7 +643,15 @@ impl HirEqInterExpr<'_, '_, '_> { ) => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) - || self.inner.expr_fallback.as_mut().is_some_and(|f| f(left, right)) + || self + .inner + .maybe_typeck_results + .is_some_and(|(left_typeck_results, right_typeck_results)| { + self.inner + .expr_fallback + .as_mut() + .is_some_and(|f| f(left_typeck_results, left, right_typeck_results, right)) + }) } fn eq_exprs(&mut self, left: &[Expr<'_>], right: &[Expr<'_>]) -> bool { diff --git a/src/tools/clippy/tests/ui/match_same_arms.fixed b/src/tools/clippy/tests/ui/match_same_arms.fixed index 31684a5759fe9..8b16fd3193f5f 100644 --- a/src/tools/clippy/tests/ui/match_same_arms.fixed +++ b/src/tools/clippy/tests/ui/match_same_arms.fixed @@ -140,3 +140,19 @@ fn main() { _ => false, }; } + +fn issue16678() { + // ICE in Rust 1.94.0 + match true { + true => { + fn wrapper(_arg: ()) { + _arg; + } + }, + false => { + fn wrapper(_arg: ()) { + _arg; + } + }, + } +} diff --git a/src/tools/clippy/tests/ui/match_same_arms.rs b/src/tools/clippy/tests/ui/match_same_arms.rs index 39bee01bac22b..3b2d585c579d3 100644 --- a/src/tools/clippy/tests/ui/match_same_arms.rs +++ b/src/tools/clippy/tests/ui/match_same_arms.rs @@ -149,3 +149,19 @@ fn main() { _ => false, }; } + +fn issue16678() { + // ICE in Rust 1.94.0 + match true { + true => { + fn wrapper(_arg: ()) { + _arg; + } + }, + false => { + fn wrapper(_arg: ()) { + _arg; + } + }, + } +} diff --git a/src/version b/src/version index 8db4a57b3d020..df83a51c6cb9a 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.94.0 +1.94.1