Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miri compatibility #6

Open
dtolnay opened this issue Jan 15, 2025 · 1 comment
Open

Miri compatibility #6

dtolnay opened this issue Jan 15, 2025 · 1 comment

Comments

@dtolnay
Copy link
Contributor

dtolnay commented Jan 15, 2025

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) ... FAILED
test src/lib.rs - TwiceCell<A,B>::get_or_try_init (line 237) ... FAILED
test src/lib.rs - TwiceCell<A,B>::set (line 99) ... ok
test src/lib.rs - TwiceCell<A,B>::get_or_init (line 170) ... FAILED
test src/lib.rs - TwiceCell<A,B>::get_mut_or_try_init (line 275) ... FAILED
test src/lib.rs - TwiceLock<A,B>::from (line 1020) ... ok
test src/lib.rs - TwiceCell<A,B>::replace (line 347) ... ok
test src/lib.rs - TwiceCell<A,B>::into_inner (line 325) ... ok
test src/lib.rs - TwiceCell<A,B>::get_mut_or_init (line 197) ... FAILED
test src/lib.rs - TwiceCell<A,B>::try_insert (line 128) ... ok
test src/lib.rs - TwiceLock<A,B>::get_or_init (line 695) ... FAILED
test src/lib.rs - TwiceLock<A,B>::get_mut_or_init (line 727) ... FAILED
test src/lib.rs - TwiceLock<A,B>::replace (line 860) ... FAILED
test src/lib.rs - TwiceLock<A,B>::set (line 606) ... FAILED
test src/lib.rs - TwiceLock<A,B>::get_or_try_init (line 768) ... FAILED
test src/lib.rs - TwiceLock<A,B>::try_insert (line 644) ... FAILED
test src/lib.rs - TwiceLock<A,B>::get_mut_or_try_init (line 820) ... FAILED

failures:

---- 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 information
help: <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:51
note: 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 backtrace

error: 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 information
help: <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:51
note: 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 backtrace

error: 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 information
help: <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:51
note: 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 backtrace

error: 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 information
help: <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:51
note: 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 backtrace

error: 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 information
help: <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:51
note: 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 backtrace

error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 backtrace
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: 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 backtrace
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
error: 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 information
help: <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:61
note: 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:33
note: 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 backtrace

error: aborting due to 1 previous error
@caass
Copy link
Owner

caass commented Jan 16, 2025

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants