You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Running cargo miri test --doc in this repo, Miri is reporting Stacked Borrows violations in the implementation of both TwiceCell and TwiceLock.
If you feel strongly that we should define Rust's semantics in such a way that the code in this crate has well-defined behavior, consider minimizing what this crate needs to do and engaging with the operational semantics team about it in https://github.com/rust-lang/unsafe-code-guidelines.
Otherwise, consider adjusting to code to conform with Stacked Borrows's model, such as by using more raw pointers internally instead of references. From inspecting some of the Miri output below, there is a good chance you're going to be seeing miscompiles due to this stuff, either already or in the future.
↓ full output ↓
test src/lib.rs - TwiceCell (line 26) ... FAILEDtest src/lib.rs - TwiceCell<A,B>::get_or_try_init (line 237) ... FAILEDtest src/lib.rs - TwiceCell<A,B>::set (line 99) ... oktest src/lib.rs - TwiceCell<A,B>::get_or_init (line 170) ... FAILEDtest src/lib.rs - TwiceCell<A,B>::get_mut_or_try_init (line 275) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::from (line 1020) ... oktest src/lib.rs - TwiceCell<A,B>::replace (line 347) ... oktest src/lib.rs - TwiceCell<A,B>::into_inner (line 325) ... oktest src/lib.rs - TwiceCell<A,B>::get_mut_or_init (line 197) ... FAILEDtest src/lib.rs - TwiceCell<A,B>::try_insert (line 128) ... oktest src/lib.rs - TwiceLock<A,B>::get_or_init (line 695) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::get_mut_or_init (line 727) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::replace (line 860) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::set (line 606) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::get_or_try_init (line 768) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::try_insert (line 644) ... FAILEDtest src/lib.rs - TwiceLock<A,B>::get_mut_or_try_init (line 820) ... FAILEDfailures:---- src/lib.rs - TwiceCell (line 26) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1636> because that would remove [SharedReadOnly for <1558>] which is strongly protected --> src/lib.rs:149:29 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1636> because that would remove [SharedReadOnly for <1558>] which is strongly protected | = 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 informationhelp: <1636> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:149:35 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^help: <1558> is this argument --> src/lib.rs:307:36 |307 | fn try_init<F, E>(&self, f: F, a: &A) -> Result<&B, E> | ^ = note: BACKTRACE (of the first span): = note: inside `twice_cell::TwiceCell::<&str, usize>::try_insert` at src/lib.rs:149:29: 149:51note: inside `twice_cell::TwiceCell::<&str, usize>::try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_or_init<{closure@src/lib.rs:10:30: 10:33}>::{closure#0}}, void::Void>` --> src/lib.rs:312:26 |312 | if let Ok(val) = self.try_insert(val) { | ^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_or_try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_or_init<{closure@src/lib.rs:10:30: 10:33}>::{closure#0}}, void::Void>` --> src/lib.rs:256:32 |256 | Either::Left(a) => self.try_init(f, a), | ^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_or_init::<{closure@src/lib.rs:10:30: 10:33}>` --> src/lib.rs:184:9 |184 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_26_0` --> src/lib.rs:33:13 |10 | let value = cell.get_or_init(|s| s.len()); // <- set a `B` value based on the inital `A` value! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:36:3 |13 | } _doctest_main_src_lib_rs_26_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceCell<A,B>::get_or_try_init (line 237) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1690> because that would remove [SharedReadOnly for <1631>] which is strongly protected --> src/lib.rs:149:29 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1690> because that would remove [SharedReadOnly for <1631>] which is strongly protected | = 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 informationhelp: <1690> was created by a SharedReadWrite retag at offsets [0x0..0x8] --> src/lib.rs:149:35 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^help: <1631> is this argument --> src/lib.rs:307:36 |307 | fn try_init<F, E>(&self, f: F, a: &A) -> Result<&B, E> | ^ = note: BACKTRACE (of the first span): = note: inside `twice_cell::TwiceCell::<i32, i32>::try_insert` at src/lib.rs:149:29: 149:51note: inside `twice_cell::TwiceCell::<i32, i32>::try_init::<{closure@src/lib.rs:10:34: 10:56}, ()>` --> src/lib.rs:312:26 |312 | if let Ok(val) = self.try_insert(val) { | ^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<i32, i32>::get_or_try_init::<{closure@src/lib.rs:10:34: 10:56}, ()>` --> src/lib.rs:256:32 |256 | Either::Left(a) => self.try_init(f, a), | ^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_237_0` --> src/lib.rs:244:13 |10 | let value = cell.get_or_try_init(|n| -> Result<i32, ()> { | _____________^11 | | Ok(n * 4)12 | | }); | |__^note: inside `main` --> src/lib.rs:249:3 |15 | } _doctest_main_src_lib_rs_237_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceCell<A,B>::get_or_init (line 170) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1598> because that would remove [SharedReadOnly for <1520>] which is strongly protected --> src/lib.rs:149:29 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1598> because that would remove [SharedReadOnly for <1520>] which is strongly protected | = 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 informationhelp: <1598> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:149:35 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^help: <1520> is this argument --> src/lib.rs:307:36 |307 | fn try_init<F, E>(&self, f: F, a: &A) -> Result<&B, E> | ^ = note: BACKTRACE (of the first span): = note: inside `twice_cell::TwiceCell::<&str, usize>::try_insert` at src/lib.rs:149:29: 149:51note: inside `twice_cell::TwiceCell::<&str, usize>::try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>` --> src/lib.rs:312:26 |312 | if let Ok(val) = self.try_insert(val) { | ^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_or_try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>` --> src/lib.rs:256:32 |256 | Either::Left(a) => self.try_init(f, a), | ^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_or_init::<{closure@src/lib.rs:8:30: 8:33}>` --> src/lib.rs:184:9 |184 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_170_0` --> src/lib.rs:175:13 |8 | let value = cell.get_or_init(|s| s.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:179:3 |12 | } _doctest_main_src_lib_rs_170_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceCell<A,B>::get_mut_or_try_init (line 275) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1898> because that would remove [SharedReadOnly for <1744>] which is strongly protected --> src/lib.rs:149:29 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1898> because that would remove [SharedReadOnly for <1744>] which is strongly protected | = 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 informationhelp: <1898> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:149:35 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^help: <1744> is this argument --> src/lib.rs:307:36 |307 | fn try_init<F, E>(&self, f: F, a: &A) -> Result<&B, E> | ^ = note: BACKTRACE (of the first span): = note: inside `twice_cell::TwiceCell::<&str, i32>::try_insert` at src/lib.rs:149:29: 149:51note: inside `twice_cell::TwiceCell::<&str, i32>::try_init::<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>` --> src/lib.rs:312:26 |312 | if let Ok(val) = self.try_insert(val) { | ^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, i32>::get_mut_or_try_init::<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>` --> src/lib.rs:296:13 |296 | self.try_init(f, a)?; | ^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_275_0` --> src/lib.rs:285:13 |13 | let value = cell.get_mut_or_try_init(|_| "1234".parse()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:289:3 |17 | } _doctest_main_src_lib_rs_275_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceCell<A,B>::get_mut_or_init (line 197) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1608> because that would remove [SharedReadOnly for <1530>] which is strongly protected --> src/lib.rs:149:29 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1608> because that would remove [SharedReadOnly for <1530>] which is strongly protected | = 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 informationhelp: <1608> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:149:35 |149 | let slot = unsafe { &mut *self.inner.get() }; | ^^^^^^^^^^^^^^^^help: <1530> is this argument --> src/lib.rs:307:36 |307 | fn try_init<F, E>(&self, f: F, a: &A) -> Result<&B, E> | ^ = note: BACKTRACE (of the first span): = note: inside `twice_cell::TwiceCell::<&str, usize>::try_insert` at src/lib.rs:149:29: 149:51note: inside `twice_cell::TwiceCell::<&str, usize>::try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>` --> src/lib.rs:312:26 |312 | if let Ok(val) = self.try_insert(val) { | ^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_mut_or_try_init::<{closure@twice_cell::TwiceCell<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>` --> src/lib.rs:296:13 |296 | self.try_init(f, a)?; | ^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceCell::<&str, usize>::get_mut_or_init::<{closure@src/lib.rs:8:34: 8:37}>` --> src/lib.rs:215:9 |215 | self.get_mut_or_try_init(|a| Ok::<B, Void>(f(a))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_197_0` --> src/lib.rs:202:13 |8 | let value = cell.get_mut_or_init(|s| s.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:210:3 |16 | } _doctest_main_src_lib_rs_197_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::get_or_init (line 695) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <2101> because that would remove [SharedReadOnly for <2056>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <2101> because that would remove [SharedReadOnly for <2056>] which is strongly protected | = 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 informationhelp: <2101> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <2056> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span): = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, usize>::initialize::<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, usize>::get_or_try_init::<{closure@twice_cell::TwiceLock<&str, usize>::get_or_init<{closure@src/lib.rs:8:30: 8:33}>::{closure#0}}, void::Void>` --> src/lib.rs:797:32 |797 | Either::Left(a) => self.initialize(f, a)?, | ^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, usize>::get_or_init::<{closure@src/lib.rs:8:30: 8:33}>` --> src/lib.rs:710:9 |710 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_695_0` --> src/lib.rs:700:13 |8 | let value = cell.get_or_init(|s| s.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:704:3 |12 | } _doctest_main_src_lib_rs_695_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::get_mut_or_init (line 727) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <1995> because that would remove [SharedReadOnly for <1950>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <1995> because that would remove [SharedReadOnly for <1950>] which is strongly protected | = 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 informationhelp: <1995> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <1950> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span): = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, usize>::initialize::<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, usize>::get_mut_or_try_init::<{closure@twice_cell::TwiceLock<&str, usize>::get_mut_or_init<{closure@src/lib.rs:8:34: 8:37}>::{closure#0}}, void::Void>` --> src/lib.rs:844:13 |844 | self.initialize(f, a)?; | ^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, usize>::get_mut_or_init::<{closure@src/lib.rs:8:34: 8:37}>` --> src/lib.rs:746:9 |746 | self.get_mut_or_try_init(|a| Ok::<B, Void>(f(a))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_727_0` --> src/lib.rs:732:13 |8 | let value = cell.get_mut_or_init(|s| s.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:740:3 |16 | } _doctest_main_src_lib_rs_727_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::replace (line 860) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <2170> because that would remove [SharedReadOnly for <2082>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <2170> because that would remove [SharedReadOnly for <2082>] which is strongly protected | = 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 informationhelp: <2170> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <2082> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span): = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<i32, &str>::initialize<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<i32, &str>::initialize<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<i32, &str>::initialize<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<i32, &str>::initialize<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<i32, &str>::initialize<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<i32, &str>::initialize::<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<i32, &str>::get_or_try_init::<{closure@twice_cell::TwiceLock<i32, &str>::get_or_init<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:797:32 |797 | Either::Left(a) => self.initialize(f, a)?, | ^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<i32, &str>::get_or_init::<{closure@twice_cell::TwiceLock<i32, &str>::try_insert::{closure#0}}>` --> src/lib.rs:710:9 |710 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<i32, &str>::try_insert` --> src/lib.rs:669:19 |669 | let res = self.get_or_init(move |_| unsafe { safe_value.take().unwrap_unchecked() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<i32, &str>::set` --> src/lib.rs:626:15 |626 | match self.try_insert(value) { | ^^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_860_0` --> src/lib.rs:869:1 |12 | cell.set("hello").unwrap(); | ^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:873:3 |16 | } _doctest_main_src_lib_rs_860_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::set (line 606) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <8674> because that would remove [SharedReadOnly for <8604>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <8674> because that would remove [SharedReadOnly for <8604>] which is strongly protected | = 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 informationhelp: <8674> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <8604> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span) on thread `unnamed-1`: = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, i32>::initialize::<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, i32>::get_or_try_init::<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:797:32 |797 | Either::Left(a) => self.initialize(f, a)?, | ^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, i32>::get_or_init::<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>` --> src/lib.rs:710:9 |710 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, i32>::try_insert` --> src/lib.rs:669:19 |669 | let res = self.get_or_init(move |_| unsafe { safe_value.take().unwrap_unchecked() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, i32>::set` --> src/lib.rs:626:15 |626 | match self.try_insert(value) { | ^^^^^^^^^^^^^^^^^^^^^^note: inside closure --> src/lib.rs:616:20 |12 | assert_eq!(CELL.set(92), Ok(())); | ^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::get_or_try_init (line 768) stdout ----Test executable failed (exit status: 1).stderr:thread 'main' panicked at src/lib.rs:912:31:Box<dyn Any>note: run with `RUST_BACKTRACE=1` environment variable to display a backtracenote: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effecterror: Undefined Behavior: not granting access to tag <14917> because that would remove [SharedReadOnly for <14879>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <14917> because that would remove [SharedReadOnly for <14879>] which is strongly protected | = 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 informationhelp: <14917> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <14879> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span): = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:12:34: 12:58}, ()>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:12:34: 12:58}, ()>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:12:34: 12:58}, ()>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:12:34: 12:58}, ()>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:12:34: 12:58}, ()>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, usize>::initialize::<{closure@src/lib.rs:12:34: 12:58}, ()>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, usize>::get_or_try_init::<{closure@src/lib.rs:12:34: 12:58}, ()>` --> src/lib.rs:797:32 |797 | Either::Left(a) => self.initialize(f, a)?, | ^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_768_0` --> src/lib.rs:777:13 |12 | let value = cell.get_or_try_init(|s| -> Result<usize, ()> { | _____________^13 | | Ok(s.len())14 | | }); | |__^note: inside `main` --> src/lib.rs:782:3 |17 | } _doctest_main_src_lib_rs_768_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::try_insert (line 644) stdout ----Test executable failed (exit status: 1).stderr:error: Undefined Behavior: not granting access to tag <8670> because that would remove [SharedReadOnly for <8600>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <8670> because that would remove [SharedReadOnly for <8600>] which is strongly protected | = 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 informationhelp: <8670> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <8600> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span) on thread `unnamed-1`: = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, i32>::initialize<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, i32>::initialize::<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, i32>::get_or_try_init::<{closure@twice_cell::TwiceLock<&str, i32>::get_or_init<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>::{closure#0}}, void::Void>` --> src/lib.rs:797:32 |797 | Either::Left(a) => self.initialize(f, a)?, | ^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, i32>::get_or_init::<{closure@twice_cell::TwiceLock<&str, i32>::try_insert::{closure#0}}>` --> src/lib.rs:710:9 |710 | self.get_or_try_init(|a| Ok::<B, Void>(f(a))).void_unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `twice_cell::TwiceLock::<&str, i32>::try_insert` --> src/lib.rs:669:19 |669 | let res = self.get_or_init(move |_| unsafe { safe_value.take().unwrap_unchecked() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside closure --> src/lib.rs:655:20 |13 | assert_eq!(CELL.try_insert(92), Ok(&92)); | ^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error---- src/lib.rs - TwiceLock<A,B>::get_mut_or_try_init (line 820) stdout ----Test executable failed (exit status: 1).stderr:thread 'main' panicked at src/lib.rs:912:31:Box<dyn Any>note: run with `RUST_BACKTRACE=1` environment variable to display a backtracenote: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effecterror: Undefined Behavior: not granting access to tag <14260> because that would remove [SharedReadOnly for <14134>] which is strongly protected --> src/lib.rs:910:34 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <14260> because that would remove [SharedReadOnly for <14134>] which is strongly protected | = 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 informationhelp: <14260> was created by a SharedReadWrite retag at offsets [0x0..0x10] --> src/lib.rs:910:36 |910 | unsafe { (*slot.get()).b = ManuallyDrop::new(value) }; | ^^^^^^^^^^help: <14134> is this argument --> src/lib.rs:906:39 |906 | self.once.call_once_force(|_| { | _______________________________________^907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |_____________^ = note: BACKTRACE (of the first span): = note: inside closure at src/lib.rs:910:34: 910:76 = note: inside closure at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:40: 217:60 = note: inside `std::sync::Once::call_once_force::<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>::{closure#0}::{closure#0}}>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/poison/once.rs:217:9: 217:61note: inside closure --> src/lib.rs:906:13 |906 | / self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | }); | |______________^ = note: inside `<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19 = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:584:40: 584:43 = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>::{closure#0}}>>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:547:19: 547:88 = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@twice_cell::TwiceLock<&str, usize>::initialize<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>::{closure#0}}>, ()>` at $RUSTUP_HOME/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33note: inside `twice_cell::TwiceLock::<&str, usize>::initialize::<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>` --> src/lib.rs:905:9 |905 | / std::panic::catch_unwind(AssertUnwindSafe(|| {906 | | self.once.call_once_force(|_| {907 | | match f(a) {908 | | Ok(value) => {... |914 | | });915 | | })) | |___________^note: inside `twice_cell::TwiceLock::<&str, usize>::get_mut_or_try_init::<{closure@src/lib.rs:13:38: 13:41}, std::num::ParseIntError>` --> src/lib.rs:844:13 |844 | self.initialize(f, a)?; | ^^^^^^^^^^^^^^^^^^^^^note: inside `main::_doctest_main_src_lib_rs_820_0` --> src/lib.rs:830:13 |13 | let value = cell.get_mut_or_try_init(|_| "1234".parse()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: inside `main` --> src/lib.rs:835:3 |18 | } _doctest_main_src_lib_rs_820_0() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtraceerror: aborting due to 1 previous error
The text was updated successfully, but these errors were encountered:
Thanks for raising this (and for your PRs). I'm now running Miri in CI, but I'm not sure how best to ensure I'm doing alright by her -- I suppose writing some integration tests that just use twice-cell in the expected way and running those under Miri could help. And I wonder if this is a good fit for loom...
Running
cargo miri test --doc
in this repo, Miri is reporting Stacked Borrows violations in the implementation of bothTwiceCell
andTwiceLock
.If you feel strongly that we should define Rust's semantics in such a way that the code in this crate has well-defined behavior, consider minimizing what this crate needs to do and engaging with the operational semantics team about it in https://github.com/rust-lang/unsafe-code-guidelines.
Otherwise, consider adjusting to code to conform with Stacked Borrows's model, such as by using more raw pointers internally instead of references. From inspecting some of the Miri output below, there is a good chance you're going to be seeing miscompiles due to this stuff, either already or in the future.
↓ full output ↓
The text was updated successfully, but these errors were encountered: