github-actions[bot] opened issue #13765:
Unsoundness in
Error::downcast_mut()
Details Status unsound Package anyhowVersion 1.0.102URL https://github.com/dtolnay/anyhow/issues/451 Date 2026-06-25 Affected versions of this crate violate borrow rules, resulting in undefined behavior, when the user adds context to an error via
Error::contextand then later callsError::downcast_muton the returnedError.The flaw was corrected in commit
6e8c000by revising how the mutable reference is constructed, avoiding inclusion of a shared reference in the resulting borrow chain.Example
use anyhow::Error; use std::fmt; #[derive(Debug)] struct ErrorContext(&'static str); impl fmt::Display for ErrorContext { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } fn main() { let mut error = Error::msg("inner error").context(ErrorContext("old context")); let context: &mut ErrorContext = error.downcast_mut().unwrap(); context.0 = "new context"; println!("{:?}", error); }Miri output
error: Undefined Behavior: trying to retag from <1538> for Unique permission at alloc602[0x38], but that tag only grants SharedReadOnly permission for this location --> src/ptr.rs:170:18 | 170 | unsafe { &mut *self.ptr.as_ptr() } | ^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc602[0x38..0x48] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information help: <1538> was created by a SharedReadOnly retag at offsets [0x38..0x48] --> src/ptr.rs:89:18 | 89 | ptr: NonNull::from(ptr), | ^^^^^^^^^^^^^^^^^^ = note: stack backtrace: 0: anyhow::ptr::Mut::<'_, ErrorContext>::deref_mut at src/ptr.rs:170:18: 170:41 1: anyhow::error::<impl anyhow::Error>::downcast_mut::<ErrorContext> at src/error.rs:560:18: 560:46 2: main at examples/downcast_mut.rs:15:38: 15:58See advisory page for additional details.
rvolosatovs closed issue #13765:
Unsoundness in
Error::downcast_mut()
Details Status unsound Package anyhowVersion 1.0.102URL https://github.com/dtolnay/anyhow/issues/451 Date 2026-06-25 Affected versions of this crate violate borrow rules, resulting in undefined behavior, when the user adds context to an error via
Error::contextand then later callsError::downcast_muton the returnedError.The flaw was corrected in commit
6e8c000by revising how the mutable reference is constructed, avoiding inclusion of a shared reference in the resulting borrow chain.Example
use anyhow::Error; use std::fmt; #[derive(Debug)] struct ErrorContext(&'static str); impl fmt::Display for ErrorContext { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } fn main() { let mut error = Error::msg("inner error").context(ErrorContext("old context")); let context: &mut ErrorContext = error.downcast_mut().unwrap(); context.0 = "new context"; println!("{:?}", error); }Miri output
error: Undefined Behavior: trying to retag from <1538> for Unique permission at alloc602[0x38], but that tag only grants SharedReadOnly permission for this location --> src/ptr.rs:170:18 | 170 | unsafe { &mut *self.ptr.as_ptr() } | ^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc602[0x38..0x48] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information help: <1538> was created by a SharedReadOnly retag at offsets [0x38..0x48] --> src/ptr.rs:89:18 | 89 | ptr: NonNull::from(ptr), | ^^^^^^^^^^^^^^^^^^ = note: stack backtrace: 0: anyhow::ptr::Mut::<'_, ErrorContext>::deref_mut at src/ptr.rs:170:18: 170:41 1: anyhow::error::<impl anyhow::Error>::downcast_mut::<ErrorContext> at src/error.rs:560:18: 560:46 2: main at examples/downcast_mut.rs:15:38: 15:58See advisory page for additional details.
Last updated: Jul 29 2026 at 05:03 UTC