Skip to content

Commit c44324a

Browse files
committed
Auto merge of #113677 - bryangarza:unevaluated-const-ice_issue-110892, r=davidtwco
Safe Transmute: Fix ICE (due to UnevaluatedConst) This patch updates the code that looks at the `Assume` type when evaluating if transmutation is possible. An ICE was being triggered in the case that the `Assume` parameter contained an unevaluated const (in this test case, due to a function with missing parameter names). Fixes #110892
2 parents 0f16bd3 + ef50e20 commit c44324a

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

compiler/rustc_middle/src/ty/consts.rs

+8
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ impl<'tcx> Const<'tcx> {
294294
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
295295
}
296296

297+
/// Attempts to convert to a `ValTree`
298+
pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
299+
match self.kind() {
300+
ty::ConstKind::Value(valtree) => Some(valtree),
301+
_ => None,
302+
}
303+
}
304+
297305
#[inline]
298306
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
299307
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it

compiler/rustc_transmute/src/lib.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ mod rustc {
7878
use rustc_middle::ty::ParamEnv;
7979
use rustc_middle::ty::Ty;
8080
use rustc_middle::ty::TyCtxt;
81+
use rustc_middle::ty::ValTree;
8182

8283
/// The source and destination types of a transmutation.
8384
#[derive(TypeVisitable, Debug, Clone, Copy)]
@@ -148,7 +149,17 @@ mod rustc {
148149
);
149150

150151
let variant = adt_def.non_enum_variant();
151-
let fields = c.to_valtree().unwrap_branch();
152+
let fields = match c.try_to_valtree() {
153+
Some(ValTree::Branch(branch)) => branch,
154+
_ => {
155+
return Some(Self {
156+
alignment: true,
157+
lifetimes: true,
158+
safety: true,
159+
validity: true,
160+
});
161+
}
162+
};
152163

153164
let get_field = |name| {
154165
let (field_idx, _) = variant
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// check-fail
2+
#![feature(generic_const_exprs, transmutability)]
3+
#![allow(incomplete_features)]
4+
5+
mod assert {
6+
use std::mem::{Assume, BikeshedIntrinsicFrom};
7+
8+
pub fn is_transmutable<
9+
Src,
10+
Dst,
11+
Context,
12+
const ASSUME_ALIGNMENT: bool,
13+
const ASSUME_LIFETIMES: bool,
14+
const ASSUME_SAFETY: bool,
15+
const ASSUME_VALIDITY: bool,
16+
>()
17+
where
18+
Dst: BikeshedIntrinsicFrom<
19+
Src,
20+
Context,
21+
{ from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
22+
>,
23+
{}
24+
25+
// This should not cause an ICE
26+
const fn from_options(
27+
, //~ ERROR expected parameter name, found `,`
28+
, //~ ERROR expected parameter name, found `,`
29+
, //~ ERROR expected parameter name, found `,`
30+
, //~ ERROR expected parameter name, found `,`
31+
) -> Assume {} //~ ERROR mismatched types
32+
}
33+
34+
fn main() {
35+
struct Context;
36+
#[repr(C)] struct Src;
37+
#[repr(C)] struct Dst;
38+
39+
assert::is_transmutable::<Src, Dst, Context, false, false, { true }, false>();
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error: expected parameter name, found `,`
2+
--> $DIR/issue-110892.rs:27:9
3+
|
4+
LL | ,
5+
| ^ expected parameter name
6+
7+
error: expected parameter name, found `,`
8+
--> $DIR/issue-110892.rs:28:9
9+
|
10+
LL | ,
11+
| ^ expected parameter name
12+
13+
error: expected parameter name, found `,`
14+
--> $DIR/issue-110892.rs:29:9
15+
|
16+
LL | ,
17+
| ^ expected parameter name
18+
19+
error: expected parameter name, found `,`
20+
--> $DIR/issue-110892.rs:30:9
21+
|
22+
LL | ,
23+
| ^ expected parameter name
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/issue-110892.rs:31:10
27+
|
28+
LL | const fn from_options(
29+
| ------------ implicitly returns `()` as its body has no tail or `return` expression
30+
...
31+
LL | ) -> Assume {}
32+
| ^^^^^^ expected `Assume`, found `()`
33+
34+
error: aborting due to 5 previous errors
35+
36+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)