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

clippy doesn't properly model whether a type is allowed to be uninit #10407

Closed
Noratrieb opened this issue Feb 26, 2023 · 1 comment · Fixed by #10520
Closed

clippy doesn't properly model whether a type is allowed to be uninit #10407

Noratrieb opened this issue Feb 26, 2023 · 1 comment · Fixed by #10520
Assignees
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have

Comments

@Noratrieb
Copy link
Member

Noratrieb commented Feb 26, 2023

Summary

The uninit_vec and uninit_assumed_init lints use a helper to check whether a type may be uninit.

pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
match *ty.kind() {
ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),
ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did()),
_ => false,
}
}

This helper is incorrect for newtypes around MaybeUninit<T>, ZSTs and unions in general.

This should be fixed by just deleting this helper function and using rustc's check_validity_of_init (the name may change in rust-lang/rust#108505). It doesn't currently support uninit checks but that should be really easy to add upstream (and needed for rust-lang/rust#100423 anyways).

Lint Name

uninit_vec,uninit_assumed_init

Reproducer

I tried this code:

use core::mem::MaybeUninit;

#[repr(transparent)]
struct Transparent<T>(MaybeUninit<T>);

pub fn foo<T>() {
    let mut vec = Vec::<Transparent<T>>::new();
    vec.reserve(20);
    unsafe { vec.set_len(20) };
}

I saw this happen:

error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
 --> src/lib.rs:8:5
  |
8 |     vec.reserve(20);
  |     ^^^^^^^^^^^^^^^^
9 |     unsafe { vec.set_len(20) };
  |              ^^^^^^^^^^^^^^^
  |
  = help: initialize the buffer or wrap the content in `MaybeUninit`
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
  = note: `#[deny(clippy::uninit_vec)]` on by default

I expected to see this happen: Everything is fine

Version

rustc 1.69.0-nightly (34e6673a0 2023-02-25)
binary: rustc
commit-hash: 34e6673a0473e90ef01a18eb575392c9e3859747
commit-date: 2023-02-25
host: x86_64-unknown-linux-gnu
release: 1.69.0-nightly
LLVM version: 15.0.7

Additional Labels

No response

@Noratrieb Noratrieb added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Feb 26, 2023
@Noratrieb
Copy link
Member Author

@rustbot claim

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Mar 4, 2023
…ompiler-errors

Allow checking whether a type allows being uninitialized

This is useful for clippy ([rust-lang/clippy#10407](rust-lang/rust-clippy#10407)) and for the future `MaybeUninit::assume_init` panics (rust-lang#100423).
@bors bors closed this as completed in 7b3c4aa Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant