Auto merge of #154211 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum

[stable] 1.94.1 release


This backports:

* [STABLE] library: wasm32-wasip1-threads has functional pthreads rust-lang/rust#153634
* Move freeze_* methods to OpenOptionsExt2 rust-lang/rust#153491
* [Clippy] Fix ICE in match_same_arms rust-lang/rust-clippy#16685

Cargo:

* [stable 1.94] Fix symlink_and_directory when running in a long target dir name (rust-lang/cargo#16777)
* Fix symlink_and_directory when running in a long target dir name (rust-lang/cargo#16775)
* [stable 1.94] Update tar to 0.4.45 (rust-lang/cargo#16769)
* test: Remove unused docker ip_address (rust-lang/cargo#16636)
* Increase cache_lock test timeout (rust-lang/cargo#16545)
* chore: Updated compiler errors for Rust 1.93 (rust-lang/cargo#16543)
* test(build-std): Update error message (rust-lang/cargo#16658)
* fix: `--remap-path-scope` stabilized in 1.95-nightly (rust-lang/cargo#16536)
* fix(script): surpress `unused_features` lint for embedded (rust-lang/cargo#16714)
* test(git): Mark a test as non-deterministic (rust-lang/cargo#16706)
* test(replace): Mark a test as non-deterministic (rust-lang/cargo#16700)
This commit is contained in:
bors
2026-03-22 21:19:42 +00:00
10 changed files with 102 additions and 24 deletions
+14
View File
@@ -1,3 +1,17 @@
Version 1.94.1 (2026-03-26)
===========================
<a id="1.94.1"></a>
* [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)
==========================
+23 -12
View File
@@ -138,6 +138,8 @@ fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
}
/// 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 @@ fn security_qos_flags(&mut self, flags: u32) -> &mut 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
+4 -1
View File
@@ -49,7 +49,10 @@ pub unsafe fn new(stack: usize, init: Box<ThreadInit>) -> io::Result<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 <https://github.com/rust-lang/rust/issues/153475>.
if cfg!(all(target_os = "wasi", not(all(target_env = "p1", target_feature = "atomics")))) {
return Err(io::Error::UNSUPPORTED_PLATFORM);
}
@@ -12,7 +12,7 @@
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<HirId> = 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)
{
@@ -9,6 +9,7 @@
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 @@ pub fn check_map_call(
// .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 @@ pub fn check_map_call(
// 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))
+16 -4
View File
@@ -26,7 +26,8 @@
/// 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<Box<SpanlessEqCallback<'a>>>,
expr_fallback: Option<Box<SpanlessEqCallback<'a, 'tcx>>>,
path_check: PathCheck,
}
@@ -94,7 +95,10 @@ pub fn paths_by_resolution(self) -> Self {
}
#[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 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
) => 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 {
@@ -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;
}
},
}
}
@@ -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;
}
},
}
}
+1 -1
View File
@@ -1 +1 @@
1.94.0
1.94.1