Skip to content

Commit 087a013

Browse files
Don't ICE in might_permit_raw_init if reference is polymorphic
1 parent 0b439b1 commit 087a013

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

compiler/rustc_const_eval/src/util/might_permit_raw_init.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
2-
use rustc_middle::ty::{ParamEnv, TyCtxt};
2+
use rustc_middle::ty::{ParamEnv, TyCtxt, TypeVisitable};
33
use rustc_session::Limit;
44
use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants};
55

@@ -108,7 +108,12 @@ fn might_permit_raw_init_lax<'tcx>(
108108

109109
// Special magic check for references and boxes (i.e., special pointer types).
110110
if let Some(pointee) = this.ty.builtin_deref(false) {
111-
let pointee = cx.layout_of(pointee.ty).expect("need to be able to compute layouts");
111+
let Ok(pointee) = cx.layout_of(pointee.ty) else {
112+
// Reference is too polymorphic, it has a layout but the pointee does not.
113+
// So we must assume that there may be some substitution that is valid.
114+
assert!(pointee.ty.needs_subst());
115+
return true;
116+
};
112117
// We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied.
113118
if pointee.align.abi.bytes() > 1 {
114119
// 0x01-filling is not aligned.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- // MIR for `generic` before InstCombine
2+
+ // MIR for `generic` after InstCombine
3+
4+
fn generic() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/dont_yeet_assert.rs:+0:21: +0:21
6+
let _1: (); // in scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61
7+
8+
bb0: {
9+
StorageLive(_1); // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61
10+
- _1 = assert_mem_uninitialized_valid::<&T>() -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61
11+
- // mir::Constant
12+
- // + span: $DIR/dont_yeet_assert.rs:10:5: 10:59
13+
- // + user_ty: UserType(0)
14+
- // + literal: Const { ty: extern "rust-intrinsic" fn() {assert_mem_uninitialized_valid::<&T>}, val: Value(<ZST>) }
15+
+ goto -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61
16+
}
17+
18+
bb1: {
19+
StorageDead(_1); // scope 0 at $DIR/dont_yeet_assert.rs:+1:61: +1:62
20+
_0 = const (); // scope 0 at $DIR/dont_yeet_assert.rs:+0:21: +2:2
21+
return; // scope 0 at $DIR/dont_yeet_assert.rs:+2:2: +2:2
22+
}
23+
}
24+

tests/mir-opt/dont_yeet_assert.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: --crate-type=lib
2+
// unit-test: InstCombine
3+
4+
#![feature(core_intrinsics)]
5+
6+
// Want to make sure this assertion isn't compiled away in generic code.
7+
8+
// EMIT_MIR dont_yeet_assert.generic.InstCombine.diff
9+
pub fn generic<T>() {
10+
core::intrinsics::assert_mem_uninitialized_valid::<&T>();
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// compile-flags: --crate-type=lib -Zmir-enable-passes=+InstCombine
2+
// build-pass
3+
4+
#![feature(core_intrinsics)]
5+
6+
pub fn generic<T>() {
7+
core::intrinsics::assert_mem_uninitialized_valid::<&T>();
8+
}

0 commit comments

Comments
 (0)