From f4c959769bdf6bc847e0e5158b5c39c01c159737 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 6 Sep 2022 09:39:30 +0200 Subject: [PATCH 1/2] Use `ManuallyDrop` instead of `mem::forget` in scopeguard With field retagging in SB, this causes UB because the read out value is invalidated by the move into `mem::forget`. Using `ManuallyDrop` avoids the problem. --- src/scopeguard.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/scopeguard.rs b/src/scopeguard.rs index f85e6ab0ed..382d06043e 100644 --- a/src/scopeguard.rs +++ b/src/scopeguard.rs @@ -1,6 +1,6 @@ // Extracted from the scopeguard crate use core::{ - mem, + mem::ManuallyDrop, ops::{Deref, DerefMut}, ptr, }; @@ -28,15 +28,13 @@ where #[inline] pub fn into_inner(guard: Self) -> T { // Cannot move out of Drop-implementing types, so - // ptr::read the value and forget the guard. + // ptr::read the value out of a ManuallyDrop + // Don't use mem::forget as that might invalidate value + let guard = ManuallyDrop::new(guard); unsafe { let value = ptr::read(&guard.value); - // read the closure so that it is dropped, and assign it to a local - // variable to ensure that it is only dropped after the guard has - // been forgotten. (In case the Drop impl of the closure, or that - // of any consumed captured variable, panics). - let _dropfn = ptr::read(&guard.dropfn); - mem::forget(guard); + // read the closure so that it is dropped + let _ = ptr::read(&guard.dropfn); value } } From 1f751c632388909403bf32fe0d57268efe01c268 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 6 Sep 2022 09:41:24 +0200 Subject: [PATCH 2/2] Enable `-Zmiri-retag-fields` in CI Now that the bug is fixed, this can be enabled. Field retagging is required to justify some of the `noalias` optimizations that rustc performs currently. --- ci/miri.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/miri.sh b/ci/miri.sh index 68d6af61c6..9d845d833b 100644 --- a/ci/miri.sh +++ b/ci/miri.sh @@ -9,4 +9,4 @@ rustup toolchain install nightly --component miri rustup override set nightly cargo miri setup -cargo miri test +MIRIFLAGS='-Zmiri-retag-fields' cargo miri test