Uh oh!
There was an error while loading. Please reload this page.
Conversation
rust-highfive
commented
Aug 9, 2022
r? @wesleywiser (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
rustbot
commented
Aug 10, 2022
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
This comment has been minimized.
This comment has been minimized.
ghost
commented
Aug 10, 2022
Did some tests compiling some representative rust programs, and it's worth noting that this would cause likely a fair chunk of nontrivial programs to warn (For example, Also the message might need adjusting, it currently says I still feel a warning is really the best choice to push crates to update their dependencies / remove their use of mem::uninit, but it's also probably worth keeping in mind just how many people will see it. |
and now that i think of it this is probably more @rustbot label -T-compiler T-lang i think. maybe not API? Not sure! |
Nominating for Lang Team discussion: should we lint on |
ghost
commented
Aug 11, 2022
This PR, as implemented, would be all uses, even definitely or possibly non-UB ones, since at the call-site, we might not know the type, and nearly all uses of mem::uninit are UB anyways. The best we could likely do and still be useful is to skip known non-UB calls, of which I doubt there really are any. And yeah, I don't know if this is T-Lang or T-Libs or both, but #98862 (comment) was nominated for T-libs and consensus seemed to be that a FCW was a good idea. |
Can we get a better understanding of the actual path most users will have to fixing this? Is it cargo update, or do they need to actually go and edit their Cargo.toml (moving to an entirely different crate or across semver versions)? And, if the majority of users do need to actually make a semver-incompatible change here, is that something we can help with (e.g., by pushing some key crates to release point releases of older versions)? I am pretty wary of false-positive warnings for uses of uninitialized that aren't currently UB, particularly if we're telling a very large amount of people to take some non-trivial action (e.g., more than cargo update). I think that sets a bad precedent and may discourage people from trusting such notices in the future. For example, looking at itoa (since you mentioned it), I believe we're warning as a result of this call. Given we've merged #99182, this is just slow but not actually language UB anymore. It's debatable whether it's library UB -- but it seems like, in general, not something we need a FCW to warn users to move off of in their dependencies: doing so would cause more noise than benefit, I think. It seems likely that we can detect at least this kind of case (concrete types, no generics), so I would expect it to be possible to avoid linting here. Maybe the invalid_value lint could be reused here (not familiar with its exact semantics). If that buys us avoiding warnings for ~10-20% of Rust users, that's still very significant, and seems not unlikely. |
ghost
commented
Aug 12, 2022
In the case of itoa specifically, this was brought up upstream in dtolnay/itoa#36 with the response
But yeah, the fix was made on a breaking change release of the library, (0.4.8 -> 1.0.0), so
Of the 1.7 million monthly downloads of itoa 0.4.8, that accounts for around 1.6 million of them.
As for more UB cases, a fair few cases of UB were found in #99389 (even where we needed to allow uninit Yeah, we could use a modified form of the invalid_value lint here. Invalid_value lints about known to be UB calls, but it also lints for mem::zeroed and MaybeUninit::uninit().assume_init() (and even unsafefnuninit<T>() -> T{ mem::uninitialized()}We could do a very targeted fix of "if it's known to be a |
After looking at more failures (by using the https://github.com/mTvare6/hello-world.rs repo as a repo that has a lot of dependencies, so the check runs on a lot of somewhat representative code), ignoring just I'll try and write a more targeted check, as a "invalid_values but only caring about mem::uninitialized and falling back to linting, instead of ignoring". For reference, the current set of hit crates on that repo is |
ghost
commented
Aug 12, 2022
Ignoring just known to be ints/floats/raw pointers (so a generic T will still lint) gets us |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Why is this so clever?
I think the idea is to just warn on all uses of this function. Basically this is a very strong form of deprecation. We might even do this via a new attribute rather than a specific lint -- #[extremely_deprecated] or so, which makes the existing deprecation lint into an FCW lint.
There was a problem hiding this comment.
Oh, looks like this was specifically requested by @Mark-Simulacrum. However my understanding from previous discussions was that we didn't want to differentiate here -- we want to slowly work towards removing that function entirely. If we had a time machine we'd erase it from history; lacking that we will remove it as much as we possibly can.
There was a problem hiding this comment.
Yeah, I'm not sure if we agreed on exactly when it should lint. #100342 (comment) seemed to say it's better off ignoring cases like [u8; 64] or similar.
"Basically just a lint looking for use of the mem_uninitialized diagnostic item" is what this was originally implemented as, and I can revert it back to that if we agree that's fine.
But if we wanted to reduce noise, then we could ignore things that are not UB (assuming the 0x01 filling or a hypothetical freeze).
Personally I think we've had MaybeUninit for long enough and that a full-on FCW for any mention of mem::uninitialized is warranted, but it would be noisy for some time while the ecosystem upgrades.
There was a problem hiding this comment.
Looking at it again, the guidance we got from the lang team is ambiguous, so I asked for clarification in that thread.
@rustbot label -I-lang-nominated -T-lang +T-libs-api +I-libs-api-nominated Given that this issue is spawned from #98862, which is tagged as libs-api, we are relabeling this to libs-api. Our sense is that the decision of what is UB remains T-lang purview, but the decision of the stdlib surface (e.g., whether to deprecate, remove things, etc) is T-libs-api. |
ghost
commented
Aug 27, 2022
Okay, I cleaned the code up and squashed commits. As for what we should do about things like I suspect not FCWing for I'm happy to make the reference tracking issue once we're happy with the situations that this will FCW for. I'm assuming it's my job to make that issue, in any case. As before, I'm unsure of the lint wording here, but I'll ask around to see if other people have better ideas for how to phrase it. But now, I think this is ready to @rustbot review |
ghost
commented
Aug 28, 2022
Errors now look like: (hyper, only the first one since there's 2 instances of the same exact error here) The package `hyper v0.13.10` currently triggers the following future incompatibility lints:
> warning: the type `[httparse::Header;100]` does not permit being left uninitialized
> --> /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.10/src/proto/h1/role.rs:120:77
> |
> 120 | let mut headers:[httparse::Header<'_>;MAX_HEADERS] = unsafe{ mem::uninitialized()};
> | ^^^^^^^^^^^^^^^^^^^^
> | |
> | this code causes undefined behavior when executed
> | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
> |
> = note: `#[allow(mem_uninitialized)]` on by default
> = note:for more information, see FIXME: fill this in
> note: references must be non-null(in this struct field)
> --> /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/httparse-1.7.1/src/lib.rs:660:5
> |
> 660 | pub name:&'a str,
> | ^^^^^^^^^^^^^^^^^
> Old Old crossbeam looks like The package `crossbeam v0.2.12` currently triggers the following future incompatibility lints:
> warning: the type `T` is generic, and might not permit being left uninitialized
> --> /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/crossbeam-0.2.12/src/sync/ms_queue.rs:66:45
> |
> 66 | payload:Payload::Data(unsafe{ mem::uninitialized()}),
> | ^^^^^^^^^^^^^^^^^^^^
> | |
> | this code causes undefined behavior when executed
> | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
> |
> = note: `#[allow(mem_uninitialized)]` on by default
> = note:for more information, see FIXME: fill this in
> = note:type might not be allowed to be left uninitialized
> > warning: the type `[std::cell::UnsafeCell<(T, std::sync::atomic::AtomicBool)>;32]` is generic, and might not permit being left uninitialized
> --> /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/crossbeam-0.2.12/src/sync/seg_queue.rs:40:28
> |
> 40 | data:unsafe{ mem::uninitialized()},
> | ^^^^^^^^^^^^^^^^^^^^
> | |
> | this code causes undefined behavior when executed
> | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
> |
> = note: `#[allow(mem_uninitialized)]` on by default
> = note:for more information, see FIXME: fill this in
> note:type might not be allowed to be left uninitialized(in this structfield)
> --> /home/jess/src/rust/library/core/src/cell.rs:1869:5
> |
> 1869 | value:T,
> | ^^^^^^^^
> |
RalfJung
commented
Aug 28, 2022
So when I have something like what hyper does in my own crate, I now get two warnings -- one from |
ghost
commented
Aug 28, 2022
Yeah. It's unfortunate. I could not emit an |
ghost
commented
Aug 28, 2022
This is now implemented. Output from doing fnmain(){let _x:char = unsafe{ std::mem::uninitialized()};}looks like # cargo +source check
Checking abcdef v0.1.0(/tmp/scratchaBCBdAv6h)
warning:use of deprecated function `std::mem::uninitialized`:use `mem::MaybeUninit` instead
--> src/main.rs:2:39
|
2 | let _x: char = unsafe{ std::mem::uninitialized()};
| ^^^^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
warning: the type `char` does not permit being left uninitialized
--> src/main.rs:2:29
|
2 | let _x: char = unsafe{ std::mem::uninitialized()};
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help:use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `#[warn(mem_uninitialized)]` on by default
= note:for more information, see FIXME: fill this in
= note: characters must be a valid Unicode codepoint
warning: `abcdef` (bin "abcdef") generated 2 warnings
Finished dev [unoptimized + debuginfo]target(s) in 0.07s
warning: the following packages contain code that will be rejected by a future version of Rust: abcdef v0.1.0(/tmp/scratchaBCBdAv6h)
note: to see what the problems were,use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 8`Might be a good idea to merge the checks for invalid_value and mem_uninitialized and pass in another argument indicating which form of the checks we're doing, since right now it is duplicated code. |
bors
commented
Aug 30, 2022
☔ The latest upstream changes (presumably #98919) made this pull request unmergeable. Please resolve the merge conflicts. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
wesleywiser
commented
Sep 7, 2022
The compiler changes look good to me but since this is r? rust-lang/libs |
thomcc
commented
Sep 7, 2022
I'm in favor of a FCW warning here, but will punt to someone on libs-api. |
ghost
commented
Sep 8, 2022
Created #101570 as a tracking issue for the FCW, and put that in the code. |
bors
commented
Sep 28, 2022
☔ The latest upstream changes (presumably #102377) made this pull request unmergeable. Please resolve the merge conflicts. |
Noratrieb
commented
Mar 14, 2023
any updates here? @joshtriplett @5225225 |
Noratrieb
commented
Mar 27, 2023
I don't think it's a good idea to add an FCW for |
ghost
commented
Mar 27, 2023
Makes sense. I'll adjust the code to instead lint for that. |
ghost
commented
May 29, 2023
Cleaning up old PRs that I won't get to, don't have the time. Happy to help anyone pick this up again, though. |
This PR adds a lint that will detect uses of
std::mem::uninitialized(using themem_uninitializeddiagnostic item) that are not definitely of "basic" types like int/float/raw pointer, and emit a FCW lint for it.For generic cases, we can't say it's definitely UB, just that it might be.
Background: #98862 (comment)