about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-06 20:23:41 +0200
committerGitHub <noreply@github.com>2024-08-06 20:23:41 +0200
commit8912318a4cdf64d8c0186665d54897cb49eb4c8a (patch)
tree7955a22309520b4c32bb8c25d9a9e717b5fe26f8
parent4b29f42ffc2104a74a3e6572d36adfe309e45dbd (diff)
parentfdf3b31165be835879220cfea1cc6a2112452bf6 (diff)
downloadrust-8912318a4cdf64d8c0186665d54897cb49eb4c8a.tar.gz
rust-8912318a4cdf64d8c0186665d54897cb49eb4c8a.zip
Rollup merge of #128720 - y21:issue119620, r=compiler-errors
Pass the right `ParamEnv` to `might_permit_raw_init_strict`

Fixes #119620

`might_permit_raw_init_strict` currently passes an empty `ParamEnv` to the `InterpCx`, instead of the actual `ParamEnv` that was passed in to `check_validity_requirement` at callsite.

This leads to ICEs such as the linked issue where for `UnsafeCell<*mut T>` we initially get the layout with the right `ParamEnv` (which suceeds because it can prove that `T: Sized` and therefore `UnsafeCell<*mut T>` has a known layout) but then do the rest with an empty `ParamEnv` where `T: Sized` is not known to hold so getting the layout for `*mut T` later fails.

This runs into an assertion in other layout code where it's making the (valid) assumption that, when we already have a layout for a struct (`UnsafeCell<*mut T>`), getting the layout of one of its fields (`*mut T`) should also succeed, which wasn't the case here due to using the wrong `ParamEnv`.

So, this PR changes it to just use the same `ParamEnv` all the way throughout.
-rw-r--r--compiler/rustc_const_eval/src/util/check_validity_requirement.rs10
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.rs7
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.stderr38
3 files changed, 36 insertions, 19 deletions
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 4b6b1e453b8..cbd1fdeea2a 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -1,6 +1,6 @@
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement};
-use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
 use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
 
 use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
@@ -30,10 +30,10 @@ pub fn check_validity_requirement<'tcx>(
         return Ok(!layout.abi.is_uninhabited());
     }
 
+    let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env };
     if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
-        might_permit_raw_init_strict(layout, tcx, kind)
+        might_permit_raw_init_strict(layout, &layout_cx, kind)
     } else {
-        let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env };
         might_permit_raw_init_lax(layout, &layout_cx, kind)
     }
 }
@@ -42,12 +42,12 @@ pub fn check_validity_requirement<'tcx>(
 /// details.
 fn might_permit_raw_init_strict<'tcx>(
     ty: TyAndLayout<'tcx>,
-    tcx: TyCtxt<'tcx>,
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
     kind: ValidityRequirement,
 ) -> Result<bool, &'tcx LayoutError<'tcx>> {
     let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
 
-    let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
+    let mut cx = InterpCx::new(cx.tcx, rustc_span::DUMMY_SP, cx.param_env, machine);
 
     let allocated = cx
         .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
diff --git a/src/tools/clippy/tests/ui/uninit_vec.rs b/src/tools/clippy/tests/ui/uninit_vec.rs
index c069b9adf2d..58729a97d57 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.rs
+++ b/src/tools/clippy/tests/ui/uninit_vec.rs
@@ -1,6 +1,7 @@
 #![warn(clippy::uninit_vec)]
 
 use std::mem::MaybeUninit;
+use std::cell::UnsafeCell;
 
 #[derive(Default)]
 struct MyVec {
@@ -12,6 +13,12 @@ union MyOwnMaybeUninit {
     uninit: (),
 }
 
+// https://github.com/rust-lang/rust/issues/119620
+unsafe fn requires_paramenv<S>() {
+    let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);
+    vec.set_len(1);
+}
+
 fn main() {
     // with_capacity() -> set_len() should be detected
     let mut vec: Vec<u8> = Vec::with_capacity(1000);
diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr
index 8e93466c2cc..e8b77d653f0 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.stderr
+++ b/src/tools/clippy/tests/ui/uninit_vec.stderr
@@ -1,5 +1,17 @@
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:17:5
+  --> tests/ui/uninit_vec.rs:18:5
+   |
+LL |     let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     vec.set_len(1);
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: initialize the buffer or wrap the content in `MaybeUninit`
+   = note: `-D clippy::uninit-vec` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`
+
+error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
+  --> tests/ui/uninit_vec.rs:24:5
    |
 LL |     let mut vec: Vec<u8> = Vec::with_capacity(1000);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,11 +20,9 @@ LL |         vec.set_len(200);
    |         ^^^^^^^^^^^^^^^^
    |
    = help: initialize the buffer or wrap the content in `MaybeUninit`
-   = note: `-D clippy::uninit-vec` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:24:5
+  --> tests/ui/uninit_vec.rs:31:5
    |
 LL |     vec.reserve(1000);
    |     ^^^^^^^^^^^^^^^^^^
@@ -23,7 +33,7 @@ LL |         vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` on empty `Vec` creates out-of-bound values
-  --> tests/ui/uninit_vec.rs:31:5
+  --> tests/ui/uninit_vec.rs:38:5
    |
 LL |     let mut vec: Vec<u8> = Vec::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +42,7 @@ LL |         vec.set_len(200);
    |         ^^^^^^^^^^^^^^^^
 
 error: calling `set_len()` on empty `Vec` creates out-of-bound values
-  --> tests/ui/uninit_vec.rs:38:5
+  --> tests/ui/uninit_vec.rs:45:5
    |
 LL |     let mut vec: Vec<u8> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +51,7 @@ LL |         vec.set_len(200);
    |         ^^^^^^^^^^^^^^^^
 
 error: calling `set_len()` on empty `Vec` creates out-of-bound values
-  --> tests/ui/uninit_vec.rs:44:5
+  --> tests/ui/uninit_vec.rs:51:5
    |
 LL |     let mut vec: Vec<u8> = Vec::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +60,7 @@ LL |         vec.set_len(200);
    |         ^^^^^^^^^^^^^^^^
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:61:5
+  --> tests/ui/uninit_vec.rs:68:5
    |
 LL |     let mut vec: Vec<u8> = Vec::with_capacity(1000);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +71,7 @@ LL |         vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:71:5
+  --> tests/ui/uninit_vec.rs:78:5
    |
 LL |     my_vec.vec.reserve(1000);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +82,7 @@ LL |         my_vec.vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:77:5
+  --> tests/ui/uninit_vec.rs:84:5
    |
 LL |     my_vec.vec = Vec::with_capacity(1000);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +93,7 @@ LL |         my_vec.vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:52:9
+  --> tests/ui/uninit_vec.rs:59:9
    |
 LL |         let mut vec: Vec<u8> = Vec::with_capacity(1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -94,7 +104,7 @@ LL |         vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:56:9
+  --> tests/ui/uninit_vec.rs:63:9
    |
 LL |         vec.reserve(1000);
    |         ^^^^^^^^^^^^^^^^^^
@@ -105,7 +115,7 @@ LL |         vec.set_len(200);
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
-  --> tests/ui/uninit_vec.rs:132:9
+  --> tests/ui/uninit_vec.rs:139:9
    |
 LL |         let mut vec: Vec<T> = Vec::with_capacity(1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -115,5 +125,5 @@ LL |             vec.set_len(10);
    |
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors