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

Add comment about UnsafeCell in MaybeUninit #66051

Closed
wants to merge 2 commits into from
Closed

Add comment about UnsafeCell in MaybeUninit #66051

wants to merge 2 commits into from

Conversation

pitdicker
Copy link
Contributor

The mention of UnsafeCell in MaybeUninit::as_ptr made me think MaybeUninit<UnsafeCell<T>> could be a valid alternative to UnsafeCell<MaybeUninit<T>>. But initialization via as_ptr just doesn't work out. Stumbled upon in matklad/once_cell#72 (comment).

@rust-highfive
Copy link
Collaborator

r? @shepmaster

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 3, 2019
@DutchGhost
Copy link
Contributor

This touches on #65216 a little bit

@Centril
Copy link
Contributor

Centril commented Nov 3, 2019

r? @RalfJung

@rust-highfive rust-highfive assigned RalfJung and unassigned shepmaster Nov 3, 2019
@@ -324,7 +324,7 @@ impl<T> MaybeUninit<T> {
/// Gets a pointer to the contained value. Reading from this pointer or turning it
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
/// Writing to memory that this pointer (non-transitively) points to is undefined behavior
/// (except inside an `UnsafeCell<T>`).
/// (except inside an `UnsafeCell<T>` when already initialized).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand the goal of this change. It is also not correct; the interior mutability exception is entirely orthogonal to initialization.

Could you elaborate a bit more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, maybe this change isn't helping to make things more clear...
This is roughly what I was doing:

let value: MaybeUninit<UnsafeCell<bool>> = MaybeUninit::uninit();
let slot = (&*value.as_ptr()).get() as *mut T;
slot.write(true);

But because UnsafeCell::get takes a reference, this would be invalid, right? There would temporary be a reference to an uninitialized UnsafeCell<bool>.

So I would think the exception that you can write through MaybeUninit::as_ptr when it wraps an UnsafeCell would only be correct if it was already initialized.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I would think the exception that you can write through MaybeUninit::as_ptr when it wraps an UnsafeCell would only be correct if it was already initialized.

No, the exception always applies. It's just you cannot make use of it through UnsafeCell::get. When writing unsafe code, you have to get all clauses of all constructs you use satisfied. Your example is fine as far as MaybeUninit::as_ptr is concerned -- it it what you are doing later that breaks it. Under some proposed memory model, if you use transmute to turn *const UnsafeCell<bool> into *mut bool, that is allowed and then you may use ptr:.write to initialize the bool.

@RalfJung
Copy link
Member

RalfJung commented Nov 3, 2019

This touches on #65216 a little bit

Why just "touches on"? Looks like, if done right, this PR should resolve that issue?
Your feedback on the proposed changes would thus be very welcome, @DutchGhost. :)

@pitdicker
Copy link
Contributor Author

I wouldn't have thought about transmuting the UnsafeCell as a solution. And as you say, my extra note is conflating two concepts.

I'll see if adding a note + example to UnsafeCell about how to use it when you have a *const UnsafeCell<T> works out (and maybe add some cross links from MaybeUninitialized::as_ptr etc.).

@DutchGhost
Copy link
Contributor

This touches on #65216 a little bit

Why just "touches on"? Looks like, if done right, this PR should resolve that issue?
Your feedback on the proposed changes would thus be very welcome, @DutchGhost. :)

In my opinion it would be so much more clearifying when there's a little code example with a MaybeUninit<UnsafeCell<T>> and UnsafeCell<MaybeUninit<T>>, and give the correct way of writing to the ptr, along with an explanation of why the write is sound.

But as you said here #65216 (comment), there are alot of other as_ptr() methods, and writing examples for each method seem tedious.

What I think could maybe solve this is to put some examples in the Nomicon, and just link to that in the docs. The Nomicon can then explain all the dark magic that's going on, and why it's actually sound.

@RalfJung
Copy link
Member

RalfJung commented Nov 4, 2019

Cc @danielhenrymantilla who's also currently doing some MaybeUninit docs work.

@RalfJung
Copy link
Member

RalfJung commented Nov 4, 2019

The thing is that transmuting the UnsafeCell is currently not a blessed operation. It works in my proposed model, but that's no guarantee.

We probably need a UnsafeCell<T>::get_raw(*const Self) -> *mut T. This is desirable for other reasons as well. Until then, just like we currently cannot gradually initialize structs, we cannot do that with UnsafeCell either.

@danielhenrymantilla
Copy link
Contributor

danielhenrymantilla commented Nov 4, 2019

We probably need a UnsafeCell<T>::get_raw(*const Self) -> *mut T. This is desirable for other reasons as well.

Agreed!

@RalfJung
Copy link
Member

RalfJung commented Nov 4, 2019

In my opinion it would be so much more clearifying when there's a little code example with a MaybeUninit<UnsafeCell> and UnsafeCell<MaybeUninit>, and give the correct way of writing to the ptr, along with an explanation of why the write is sound.

Agreed; once we have a blessed way of doing that we should have an example here. I originally thought the confusion was about UnsafeCell in general, but it seems it was specifically about the interaction with MaybeUninit so having an example here is totally appropriate.

@pitdicker
Copy link
Contributor Author

I just finished a documentation example, but it seems you guys have bigger concerns and idea's. Maybe it is better to close this PR?

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2019-11-04T17:06:25.1274306Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-11-04T17:06:25.1470557Z ##[command]git config gc.auto 0
2019-11-04T17:06:25.1564344Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-11-04T17:06:25.1628341Z ##[command]git config --get-all http.proxy
2019-11-04T17:06:25.1783119Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/66051/merge:refs/remotes/pull/66051/merge
---
2019-11-04T18:07:15.7922893Z .................................................................................................... 1600/9275
2019-11-04T18:07:21.6552609Z .................................................................................................... 1700/9275
2019-11-04T18:07:34.6131682Z ..............................................................i...............i..................... 1800/9275
2019-11-04T18:07:42.2348316Z .................................................................................................... 1900/9275
2019-11-04T18:07:57.9515589Z ....................................................iiiii........................................... 2000/9275
2019-11-04T18:08:09.1001415Z .................................................................................................... 2200/9275
2019-11-04T18:08:11.6786097Z .................................................................................................... 2300/9275
2019-11-04T18:08:15.2117528Z .................................................................................................... 2400/9275
2019-11-04T18:08:39.2890030Z .................................................................................................... 2500/9275
2019-11-04T18:08:39.2890030Z .................................................................................................... 2500/9275
2019-11-04T18:08:42.0246943Z .................................................................................................... 2600/9275
2019-11-04T18:08:50.1850345Z .................................................................................................... 2700/9275
2019-11-04T18:08:59.3865997Z ....................i............................................................................... 2800/9275
2019-11-04T18:09:08.4960101Z .................................................................................................... 2900/9275
2019-11-04T18:09:13.1705585Z ...................i................................................................................ 3000/9275
2019-11-04T18:09:22.0867572Z .................................................................................................... 3100/9275
2019-11-04T18:09:27.9306478Z .................................................................................................... 3200/9275
2019-11-04T18:09:37.4833871Z .ii................................................................................................. 3300/9275
2019-11-04T18:09:55.0684259Z ..............................................................................................i..... 3500/9275
2019-11-04T18:10:02.7172313Z .........................................i.......................................................... 3600/9275
2019-11-04T18:10:09.6262895Z .................................................................................................... 3700/9275
2019-11-04T18:10:16.2434028Z .................................................................................................... 3800/9275
---
2019-11-04T18:11:36.7203603Z ....................................................i...............i............................... 4800/9275
2019-11-04T18:11:46.0467855Z .................................................................................................... 4900/9275
2019-11-04T18:11:54.8762970Z .................................................................................................... 5000/9275
2019-11-04T18:12:01.0871844Z .................................................................................................... 5100/9275
2019-11-04T18:12:11.9445267Z .....................................................ii.ii...........i.............................. 5200/9275
2019-11-04T18:12:22.1807752Z .................................................................................................... 5400/9275
2019-11-04T18:12:32.7371562Z .................................................................................................... 5500/9275
2019-11-04T18:12:40.4142516Z ..........................i......................................................................... 5600/9275
2019-11-04T18:12:47.1229311Z .................................................................................................... 5700/9275
2019-11-04T18:12:47.1229311Z .................................................................................................... 5700/9275
2019-11-04T18:12:59.4485232Z .................................................................................................... 5800/9275
2019-11-04T18:13:11.6218250Z ...........ii...i..ii...........i................................................................... 5900/9275
2019-11-04T18:13:32.6917602Z .................................................................................................... 6100/9275
2019-11-04T18:13:41.1734952Z .................................................................................................... 6200/9275
2019-11-04T18:13:41.1734952Z .................................................................................................... 6200/9275
2019-11-04T18:13:55.5246604Z ..............................i..ii................................................................. 6300/9275
2019-11-04T18:14:16.6429728Z .................................................................................................i.. 6500/9275
2019-11-04T18:14:18.9916772Z .................................................................................................... 6600/9275
2019-11-04T18:14:21.3937321Z ...........................................................................i........................ 6700/9275
2019-11-04T18:14:24.1225500Z .................................................................................................... 6800/9275
---
2019-11-04T18:19:53.7064517Z  finished in 5.845
2019-11-04T18:19:53.7261618Z Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:19:53.9218857Z 
2019-11-04T18:19:53.9219365Z running 158 tests
2019-11-04T18:19:57.0262245Z iiiiii....iii......iii..iiii...i.............................i..i..................i....i........... 100/158
2019-11-04T18:19:59.0835893Z ii.i.i..iiii..............i.........iii.i.........ii......
2019-11-04T18:19:59.0842896Z 
2019-11-04T18:19:59.0846432Z  finished in 5.358
2019-11-04T18:19:59.1042276Z Check compiletest suite=codegen-units mode=codegen-units (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:19:59.2735206Z 
---
2019-11-04T18:20:01.3757843Z  finished in 2.268
2019-11-04T18:20:01.3919820Z Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:20:01.8945498Z 
2019-11-04T18:20:01.8945809Z running 9 tests
2019-11-04T18:20:01.8949250Z iiiiiiiii
2019-11-04T18:20:01.8949697Z 
2019-11-04T18:20:01.8949758Z  finished in 0.502
2019-11-04T18:20:01.9199809Z Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:20:02.0933029Z 
---
2019-11-04T18:20:22.4654824Z  finished in 20.547
2019-11-04T18:20:22.4879929Z Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:20:23.2569610Z 
2019-11-04T18:20:23.2569906Z running 123 tests
2019-11-04T18:20:48.3179231Z .iiiii...i.....i..i...i..i.i.i..i.ii..i.i.....i..i....ii..........iiii..........i...ii...i.......ii. 100/123
2019-11-04T18:20:53.1831072Z i.i.i......iii.i.....ii
2019-11-04T18:20:53.1831595Z 
2019-11-04T18:20:53.1836592Z  finished in 30.695
2019-11-04T18:20:53.1847198Z Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-04T18:20:53.1847570Z Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
---
2019-11-04T18:33:34.4878509Z 
2019-11-04T18:33:34.4879384Z    Doc-tests core
2019-11-04T18:33:39.7562019Z 
2019-11-04T18:33:39.7562609Z running 2411 tests
2019-11-04T18:33:51.1568811Z ......iiiii.........................................................F............................... 100/2411
2019-11-04T18:34:02.2398792Z .................................................................................ii................. 200/2411
2019-11-04T18:34:28.6296099Z ...i................................................................................................ 400/2411
2019-11-04T18:34:28.6296099Z ...i................................................................................................ 400/2411
2019-11-04T18:34:39.5479898Z ...................................................i..i.................iiii........................ 500/2411
2019-11-04T18:35:00.3658289Z .................................................................................................... 700/2411
2019-11-04T18:35:11.1312699Z .................................................................................................... 800/2411
2019-11-04T18:35:21.7717172Z .................................................................................................... 900/2411
2019-11-04T18:35:32.4124702Z .................................................................................................... 1000/2411
---
2019-11-04T18:38:10.2941042Z ---- cell.rs - cell::UnsafeCell (line 1498) stdout ----
2019-11-04T18:38:10.2941255Z error[E0107]: wrong number of type arguments: expected 1, found 0
2019-11-04T18:38:10.2941659Z  --> cell.rs:1503:19
2019-11-04T18:38:10.2941833Z   |
2019-11-04T18:38:10.2942000Z 8 | let inner: *const UnsafeCell = cell.as_ptr();
2019-11-04T18:38:10.2942157Z   |                   ^^^^^^^^^^ expected 1 type argument
2019-11-04T18:38:10.2942270Z 
2019-11-04T18:38:10.2942701Z error[E0605]: non-primitive cast: `std::mem::MaybeUninit<std::cell::UnsafeCell<bool>>` as `*mut bool`
2019-11-04T18:38:10.2943108Z   --> cell.rs:1505:11
2019-11-04T18:38:10.2943409Z 10 | let val = cell as *mut bool;
2019-11-04T18:38:10.2943557Z    |           ^^^^^^^^^^^^^^^^^
2019-11-04T18:38:10.2943899Z    |
2019-11-04T18:38:10.2943899Z    |
2019-11-04T18:38:10.2944043Z    = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
2019-11-04T18:38:10.2944493Z error: aborting due to 2 previous errors
2019-11-04T18:38:10.2944603Z 
2019-11-04T18:38:10.2944763Z Some errors have detailed explanations: E0107, E0605.
2019-11-04T18:38:10.2945168Z For more information about an error, try `rustc --explain E0107`.
---
2019-11-04T18:38:10.2947437Z 
2019-11-04T18:38:10.2986787Z error: test failed, to rerun pass '--doc'
2019-11-04T18:38:10.3004162Z 
2019-11-04T18:38:10.3004440Z 
2019-11-04T18:38:10.3005369Z command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "-Zconfig-profile" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-j" "2" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/checkout/src/libtest/Cargo.toml" "-p" "core" "--" "--quiet"
2019-11-04T18:38:10.3006450Z 
2019-11-04T18:38:10.3006604Z 
2019-11-04T18:38:10.3014908Z failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
2019-11-04T18:38:10.3015224Z Build completed unsuccessfully in 1:24:55
2019-11-04T18:38:10.3015224Z Build completed unsuccessfully in 1:24:55
2019-11-04T18:38:10.3071914Z == clock drift check ==
2019-11-04T18:38:10.3090238Z   local time: Mon Nov  4 18:38:10 UTC 2019
2019-11-04T18:38:10.4601450Z   network time: Mon, 04 Nov 2019 18:38:10 GMT
2019-11-04T18:38:10.4601519Z == end clock drift check ==
2019-11-04T18:38:11.1774392Z 
2019-11-04T18:38:11.1927320Z ##[error]Bash exited with code '1'.
2019-11-04T18:38:11.1964634Z ##[section]Starting: Checkout
2019-11-04T18:38:11.1967148Z ==============================================================================
2019-11-04T18:38:11.1967205Z Task         : Get sources
2019-11-04T18:38:11.1967253Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

///
/// If you have a raw reference to an `UnsafeCell` that can't be turned into a shared reference
/// (because for example the wrapped value may be uninitialized), use a pointer cast instead of
/// `get`:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should bless this pattern yet, while the memory model is still so much in flux.

I like your other improvements, but for the interaction with UnsafeCell I'm afraid just changing docs won't cut it at this point.

@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 9, 2019
@JohnCSimon
Copy link
Member

Ping from triage:
@pitdicker can you fix the build failures in this PR?
cc: @RalfJung

Thanks

@pitdicker
Copy link
Contributor Author

@JohnCSimon Thank you for the reminder. I think it is better to close this PR for now.

@pitdicker pitdicker closed this Nov 9, 2019
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Nov 13, 2019
…onSapin

add raw ptr variant of UnsafeCell::get

This has come up recently in rust-lang#66051 (Cc @Centril @pitdicker) as well as in discussion with @nikomatsakis and in unrelated discussion with @withoutboats.
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Nov 13, 2019
…onSapin

add raw ptr variant of UnsafeCell::get

This has come up recently in rust-lang#66051 (Cc @Centril @pitdicker) as well as in discussion with @nikomatsakis and in unrelated discussion with @withoutboats.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants