Skip to content

Commit e2c96cc

Browse files
committed
Auto merge of #147363 - Zalathar:rollup-d9kd06g, r=Zalathar
Rollup of 7 pull requests Successful merges: - #147288 (compiletest: Make `DirectiveLine` responsible for name/value splitting) - #147309 (Add documentation about unwinding to wasm targets) - #147310 (Mark `PatternTypo` suggestion as maybe incorrect) - #147320 (Avoid to suggest pattern match on the similarly named in fn signature) - #147328 (Implement non-poisoning `Mutex::with_mut`, `RwLock::with` and `RwLock::with_mut`) - #147337 (Make `fmt::Write` a diagnostic item) - #147349 (Improve the advice given by panic_immediate_abort) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 227ac7c + a0a4905 commit e2c96cc

File tree

22 files changed

+442
-171
lines changed

22 files changed

+442
-171
lines changed

compiler/rustc_passes/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,7 @@ pub(crate) struct UnusedVarAssignedOnly {
13651365
#[multipart_suggestion(
13661366
passes_unused_var_typo,
13671367
style = "verbose",
1368-
applicability = "machine-applicable"
1368+
applicability = "maybe-incorrect"
13691369
)]
13701370
pub(crate) struct PatternTypo {
13711371
#[suggestion_part(code = "{code}")]

compiler/rustc_passes/src/liveness.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,10 @@ impl<'tcx> Liveness<'_, 'tcx> {
16911691
if ln == self.exit_ln { false } else { self.assigned_on_exit(ln, var) };
16921692

16931693
let mut typo = None;
1694-
for (hir_id, _, span) in &hir_ids_and_spans {
1694+
let filtered_hir_ids_and_spans = hir_ids_and_spans.iter().filter(|(hir_id, ..)| {
1695+
!matches!(self.ir.tcx.parent_hir_node(*hir_id), hir::Node::Param(_))
1696+
});
1697+
for (hir_id, _, span) in filtered_hir_ids_and_spans.clone() {
16951698
let ty = self.typeck_results.node_type(*hir_id);
16961699
if let ty::Adt(adt, _) = ty.peel_refs().kind() {
16971700
let name = Symbol::intern(&name);
@@ -1717,7 +1720,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
17171720
}
17181721
}
17191722
if typo.is_none() {
1720-
for (hir_id, _, span) in &hir_ids_and_spans {
1723+
for (hir_id, _, span) in filtered_hir_ids_and_spans {
17211724
let ty = self.typeck_results.node_type(*hir_id);
17221725
// Look for consts of the same type with similar names as well, not just unit
17231726
// structs and variants.

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ symbols! {
236236
File,
237237
FileType,
238238
FmtArgumentsNew,
239+
FmtWrite,
239240
Fn,
240241
FnMut,
241242
FnOnce,

library/core/src/fmt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ pub struct Error;
115115
/// [`std::io::Write`]: ../../std/io/trait.Write.html
116116
/// [flushable]: ../../std/io/trait.Write.html#tymethod.flush
117117
#[stable(feature = "rust1", since = "1.0.0")]
118+
#[rustc_diagnostic_item = "FmtWrite"]
118119
pub trait Write {
119120
/// Writes a string slice into this writer, returning whether the write
120121
/// succeeded.

library/core/src/panicking.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ use crate::panic::{Location, PanicInfo};
3535
#[cfg(feature = "panic_immediate_abort")]
3636
compile_error!(
3737
"panic_immediate_abort is now a real panic strategy! \
38-
Enable it with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
38+
Enable it with `panic = \"immediate-abort\"` in Cargo.toml, \
39+
or with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
3940
);
4041

4142
// First we define the two main entry points that all panics go through.

library/std/src/sync/nonpoison/mutex.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,40 @@ impl<T: ?Sized> Mutex<T> {
376376
pub const fn data_ptr(&self) -> *mut T {
377377
self.data.get()
378378
}
379+
380+
/// Acquires the mutex and provides mutable access to the underlying data by passing
381+
/// a mutable reference to the given closure.
382+
///
383+
/// This method acquires the lock, calls the provided closure with a mutable reference
384+
/// to the data, and returns the result of the closure. The lock is released after
385+
/// the closure completes, even if it panics.
386+
///
387+
/// # Examples
388+
///
389+
/// ```
390+
/// #![feature(lock_value_accessors, nonpoison_mutex)]
391+
///
392+
/// use std::sync::nonpoison::Mutex;
393+
///
394+
/// let mutex = Mutex::new(2);
395+
///
396+
/// let result = mutex.with_mut(|data| {
397+
/// *data += 3;
398+
///
399+
/// *data + 5
400+
/// });
401+
///
402+
/// assert_eq!(*mutex.lock(), 5);
403+
/// assert_eq!(result, 10);
404+
/// ```
405+
#[unstable(feature = "lock_value_accessors", issue = "133407")]
406+
// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
407+
pub fn with_mut<F, R>(&self, f: F) -> R
408+
where
409+
F: FnOnce(&mut T) -> R,
410+
{
411+
f(&mut self.lock())
412+
}
379413
}
380414

381415
#[unstable(feature = "nonpoison_mutex", issue = "134645")]

library/std/src/sync/nonpoison/rwlock.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,68 @@ impl<T: ?Sized> RwLock<T> {
498498
pub const fn data_ptr(&self) -> *mut T {
499499
self.data.get()
500500
}
501+
502+
/// Locks this `RwLock` with shared read access to the underlying data by passing
503+
/// a reference to the given closure.
504+
///
505+
/// This method acquires the lock, calls the provided closure with a reference
506+
/// to the data, and returns the result of the closure. The lock is released after
507+
/// the closure completes, even if it panics.
508+
///
509+
/// # Examples
510+
///
511+
/// ```
512+
/// #![feature(lock_value_accessors, nonpoison_rwlock)]
513+
///
514+
/// use std::sync::nonpoison::RwLock;
515+
///
516+
/// let rwlock = RwLock::new(2);
517+
/// let result = rwlock.with(|data| *data + 3);
518+
///
519+
/// assert_eq!(result, 5);
520+
/// ```
521+
#[unstable(feature = "lock_value_accessors", issue = "133407")]
522+
// #[unstable(feature = "nonpoison_rwlock", issue = "134645")]
523+
pub fn with<F, R>(&self, f: F) -> R
524+
where
525+
F: FnOnce(&T) -> R,
526+
{
527+
f(&self.read())
528+
}
529+
530+
/// Locks this `RwLock` with exclusive write access to the underlying data by passing
531+
/// a mutable reference to the given closure.
532+
///
533+
/// This method acquires the lock, calls the provided closure with a mutable reference
534+
/// to the data, and returns the result of the closure. The lock is released after
535+
/// the closure completes, even if it panics.
536+
///
537+
/// # Examples
538+
///
539+
/// ```
540+
/// #![feature(lock_value_accessors, nonpoison_rwlock)]
541+
///
542+
/// use std::sync::nonpoison::RwLock;
543+
///
544+
/// let rwlock = RwLock::new(2);
545+
///
546+
/// let result = rwlock.with_mut(|data| {
547+
/// *data += 3;
548+
///
549+
/// *data + 5
550+
/// });
551+
///
552+
/// assert_eq!(*rwlock.read(), 5);
553+
/// assert_eq!(result, 10);
554+
/// ```
555+
#[unstable(feature = "lock_value_accessors", issue = "133407")]
556+
// #[unstable(feature = "nonpoison_rwlock", issue = "134645")]
557+
pub fn with_mut<F, R>(&self, f: F) -> R
558+
where
559+
F: FnOnce(&mut T) -> R,
560+
{
561+
f(&mut self.write())
562+
}
501563
}
502564

503565
#[unstable(feature = "nonpoison_rwlock", issue = "134645")]

library/std/tests/sync/mutex.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,3 +549,17 @@ fn panic_while_mapping_unlocked_poison() {
549549

550550
drop(lock);
551551
}
552+
553+
#[test]
554+
fn test_mutex_with_mut() {
555+
let mutex = std::sync::nonpoison::Mutex::new(2);
556+
557+
let result = mutex.with_mut(|value| {
558+
*value += 3;
559+
560+
*value + 5
561+
});
562+
563+
assert_eq!(*mutex.lock(), 5);
564+
assert_eq!(result, 10);
565+
}

library/std/tests/sync/rwlock.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,3 +861,25 @@ fn panic_while_mapping_write_unlocked_poison() {
861861

862862
drop(lock);
863863
}
864+
865+
#[test]
866+
fn test_rwlock_with() {
867+
let rwlock = std::sync::nonpoison::RwLock::new(2);
868+
let result = rwlock.with(|value| *value + 3);
869+
870+
assert_eq!(result, 5);
871+
}
872+
873+
#[test]
874+
fn test_rwlock_with_mut() {
875+
let rwlock = std::sync::nonpoison::RwLock::new(2);
876+
877+
let result = rwlock.with_mut(|value| {
878+
*value += 3;
879+
880+
*value + 5
881+
});
882+
883+
assert_eq!(*rwlock.read(), 5);
884+
assert_eq!(result, 10);
885+
}

src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ $ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unkno
157157
```
158158

159159
Here the `mvp` "cpu" is a placeholder in LLVM for disabling all supported
160-
features by default. Cargo's `-Zbuild-std` feature, a Nightly Rust feature, is
160+
features by default. Cargo's [`-Zbuild-std`] feature, a Nightly Rust feature, is
161161
then used to recompile the standard library in addition to your own code. This
162162
will produce a binary that uses only the original WebAssembly features by
163163
default and no proposals since its inception.
@@ -207,3 +207,63 @@ conditionally compile code instead. This is notably different to the way native
207207
platforms such as x86\_64 work, and this is due to the fact that WebAssembly
208208
binaries must only contain code the engine understands. Native binaries work so
209209
long as the CPU doesn't execute unknown code dynamically at runtime.
210+
211+
## Unwinding
212+
213+
By default the `wasm32-unknown-unknown` target is compiled with `-Cpanic=abort`.
214+
Historically this was due to the fact that there was no way to catch panics in
215+
wasm, but since mid-2025 the WebAssembly [`exception-handling`
216+
proposal](https://github.com/WebAssembly/exception-handling) reached
217+
stabilization. LLVM has support for this proposal as well and when this is all
218+
combined together it's possible to enable `-Cpanic=unwind` on wasm targets.
219+
220+
Compiling wasm targets with `-Cpanic=unwind` is not as easy as just passing
221+
`-Cpanic=unwind`, however:
222+
223+
```sh
224+
$ rustc foo.rs -Cpanic=unwind --target wasm32-unknown-unknown
225+
error: the crate `panic_unwind` does not have the panic strategy `unwind`
226+
```
227+
228+
Notably the precompiled standard library that is shipped through Rustup is
229+
compiled with `-Cpanic=abort`, not `-Cpanic=unwind`. While this is the case
230+
you're going to be required to use Cargo's [`-Zbuild-std`] feature to build with
231+
unwinding support:
232+
233+
```sh
234+
$ RUSTFLAGS='-Cpanic=unwind' cargo +nightly build --target wasm32-unknown-unknown -Zbuild-std
235+
```
236+
237+
Note, however, that as of 2025-10-03 LLVM is still using the "legacy exception
238+
instructions" by default, not the officially standard version of the
239+
exception-handling proposal:
240+
241+
```sh
242+
$ wasm-tools validate target/wasm32-unknown-unknown/debug/foo.wasm
243+
error: <sysroot>/library/std/src/sys/backtrace.rs:161:5
244+
function `std::sys::backtrace::__rust_begin_short_backtrace` failed to validate
245+
246+
Caused by:
247+
0: func 2 failed to validate
248+
1: legacy_exceptions feature required for try instruction (at offset 0x880)
249+
```
250+
251+
Fixing this requires passing `-Cllvm-args=-wasm-use-legacy-eh=false` to the Rust
252+
compiler as well:
253+
254+
```sh
255+
$ RUSTFLAGS='-Cpanic=unwind -Cllvm-args=-wasm-use-legacy-eh=false' cargo +nightly build --target wasm32-unknown-unknown -Zbuild-std
256+
$ wasm-tools validate target/wasm32-unknown-unknown/debug/foo.wasm
257+
```
258+
259+
At this time there are no concrete plans for adding new targets to the Rust
260+
compiler which have `-Cpanic=unwind` enabled-by-default. The most likely route
261+
to having this enabled is that in a few years when the `exception-handling`
262+
target feature is enabled by default in LLVM (due to browsers/runtime support
263+
propagating widely enough) the targets will switch to using `-Cpanic=unwind` by
264+
default. This is not for certain, however, and will likely be accompanied with
265+
either an MCP or an RFC about changing all wasm targets in the same manner. In
266+
the meantime using `-Cpanic=unwind` will require using [`-Zbuild-std`] and
267+
passing the appropriate flags to rustc.
268+
269+
[`-Zbuild-std`]: ../../cargo/reference/unstable.html#build-std

0 commit comments

Comments
 (0)