mirror of https://github.com/rust-lang/rust.git
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
This commit is contained in:
commit
c44324a4fe
|
@ -294,6 +294,14 @@ impl<'tcx> Const<'tcx> {
|
||||||
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
|
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to convert to a `ValTree`
|
||||||
|
pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
|
||||||
|
match self.kind() {
|
||||||
|
ty::ConstKind::Value(valtree) => Some(valtree),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
|
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
|
||||||
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
||||||
|
|
|
@ -78,6 +78,7 @@ mod rustc {
|
||||||
use rustc_middle::ty::ParamEnv;
|
use rustc_middle::ty::ParamEnv;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
use rustc_middle::ty::ValTree;
|
||||||
|
|
||||||
/// The source and destination types of a transmutation.
|
/// The source and destination types of a transmutation.
|
||||||
#[derive(TypeVisitable, Debug, Clone, Copy)]
|
#[derive(TypeVisitable, Debug, Clone, Copy)]
|
||||||
|
@ -148,7 +149,17 @@ mod rustc {
|
||||||
);
|
);
|
||||||
|
|
||||||
let variant = adt_def.non_enum_variant();
|
let variant = adt_def.non_enum_variant();
|
||||||
let fields = c.to_valtree().unwrap_branch();
|
let fields = match c.try_to_valtree() {
|
||||||
|
Some(ValTree::Branch(branch)) => branch,
|
||||||
|
_ => {
|
||||||
|
return Some(Self {
|
||||||
|
alignment: true,
|
||||||
|
lifetimes: true,
|
||||||
|
safety: true,
|
||||||
|
validity: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let get_field = |name| {
|
let get_field = |name| {
|
||||||
let (field_idx, _) = variant
|
let (field_idx, _) = variant
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
// check-fail
|
||||||
|
#![feature(generic_const_exprs, transmutability)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
mod assert {
|
||||||
|
use std::mem::{Assume, BikeshedIntrinsicFrom};
|
||||||
|
|
||||||
|
pub fn is_transmutable<
|
||||||
|
Src,
|
||||||
|
Dst,
|
||||||
|
Context,
|
||||||
|
const ASSUME_ALIGNMENT: bool,
|
||||||
|
const ASSUME_LIFETIMES: bool,
|
||||||
|
const ASSUME_SAFETY: bool,
|
||||||
|
const ASSUME_VALIDITY: bool,
|
||||||
|
>()
|
||||||
|
where
|
||||||
|
Dst: BikeshedIntrinsicFrom<
|
||||||
|
Src,
|
||||||
|
Context,
|
||||||
|
{ from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
|
||||||
|
>,
|
||||||
|
{}
|
||||||
|
|
||||||
|
// This should not cause an ICE
|
||||||
|
const fn from_options(
|
||||||
|
, //~ ERROR expected parameter name, found `,`
|
||||||
|
, //~ ERROR expected parameter name, found `,`
|
||||||
|
, //~ ERROR expected parameter name, found `,`
|
||||||
|
, //~ ERROR expected parameter name, found `,`
|
||||||
|
) -> Assume {} //~ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
struct Context;
|
||||||
|
#[repr(C)] struct Src;
|
||||||
|
#[repr(C)] struct Dst;
|
||||||
|
|
||||||
|
assert::is_transmutable::<Src, Dst, Context, false, false, { true }, false>();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
error: expected parameter name, found `,`
|
||||||
|
--> $DIR/issue-110892.rs:27:9
|
||||||
|
|
|
||||||
|
LL | ,
|
||||||
|
| ^ expected parameter name
|
||||||
|
|
||||||
|
error: expected parameter name, found `,`
|
||||||
|
--> $DIR/issue-110892.rs:28:9
|
||||||
|
|
|
||||||
|
LL | ,
|
||||||
|
| ^ expected parameter name
|
||||||
|
|
||||||
|
error: expected parameter name, found `,`
|
||||||
|
--> $DIR/issue-110892.rs:29:9
|
||||||
|
|
|
||||||
|
LL | ,
|
||||||
|
| ^ expected parameter name
|
||||||
|
|
||||||
|
error: expected parameter name, found `,`
|
||||||
|
--> $DIR/issue-110892.rs:30:9
|
||||||
|
|
|
||||||
|
LL | ,
|
||||||
|
| ^ expected parameter name
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-110892.rs:31:10
|
||||||
|
|
|
||||||
|
LL | const fn from_options(
|
||||||
|
| ------------ implicitly returns `()` as its body has no tail or `return` expression
|
||||||
|
...
|
||||||
|
LL | ) -> Assume {}
|
||||||
|
| ^^^^^^ expected `Assume`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue