Skip to content

Commit f2ba411

Browse files
committed
Auto merge of rust-lang#130950 - compiler-errors:yeet-eval, r=BoxyUwU
Continue to get rid of `ty::Const::{try_}eval*` This PR mostly does: * Removes all of the `try_eval_*` and `eval_*` helpers from `ty::Const`, and replace their usages with `try_to_*`. * Remove `ty::Const::eval`. * Rename `ty::Const::normalize` to `ty::Const::normalize_internal`. This function is still used in the normalization code itself. * Fix some weirdness around the `TransmuteFrom` goal. I'm happy to split it out further; for example, I could probably land the first part which removes the helpers, or the changes to codegen which are more obvious than the changes to tools. r? BoxyUwU Part of rust-lang#130704
2 parents fb32dd4 + 5cf8107 commit f2ba411

File tree

58 files changed

+407
-338
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+407
-338
lines changed

compiler/rustc_borrowck/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,10 @@ fn do_mir_borrowck<'tcx>(
187187

188188
let location_table = LocationTable::new(body);
189189

190-
let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
190+
let move_data = MoveData::gather_moves(body, tcx, |_| true);
191191
let promoted_move_data = promoted
192192
.iter_enumerated()
193-
.map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, param_env, |_| true)));
193+
.map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true)));
194194

195195
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
196196
.into_engine(tcx, body)

compiler/rustc_borrowck/src/type_check/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11281128
}
11291129
let projected_ty = curr_projected_ty.projection_ty_core(
11301130
tcx,
1131-
self.param_env,
11321131
proj,
11331132
|this, field, ()| {
11341133
let ty = this.field_ty(tcx, field);
@@ -1919,7 +1918,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19191918
// than 1.
19201919
// If the length is larger than 1, the repeat expression will need to copy the
19211920
// element, so we require the `Copy` trait.
1922-
if len.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
1921+
if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) {
19231922
match operand {
19241923
Operand::Copy(..) | Operand::Constant(..) => {
19251924
// These are always okay: direct use of a const, or a value that can evidently be copied.

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
133133
.expect_const()
134134
.try_to_valtree()
135135
.expect("expected monomorphic const in codegen")
136+
.0
136137
.unwrap_branch();
137138

138139
assert_eq!(x.layout(), y.layout());
@@ -806,8 +807,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
806807
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => m.load_scalar(fx),
807808
ty::Array(elem, len)
808809
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
809-
&& len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
810-
== Some(expected_bytes) =>
810+
&& len
811+
.try_to_target_usize(fx.tcx)
812+
.expect("expected monomorphic const in codegen")
813+
== expected_bytes =>
811814
{
812815
m.force_stack(fx).0.load(
813816
fx,
@@ -907,8 +910,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
907910
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {}
908911
ty::Array(elem, len)
909912
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
910-
&& len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
911-
== Some(expected_bytes) => {}
913+
&& len
914+
.try_to_target_usize(fx.tcx)
915+
.expect("expected monomorphic const in codegen")
916+
== expected_bytes => {}
912917
_ => {
913918
fx.tcx.dcx().span_fatal(
914919
span,

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
7676
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
7777
ty::Array(elem, len)
7878
if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8))
79-
&& len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
80-
== Some(expected_bytes) =>
79+
&& len
80+
.try_to_target_usize(bx.tcx)
81+
.expect("expected monomorphic const in codegen")
82+
== expected_bytes =>
8183
{
8284
let place = PlaceRef::alloca(bx, args[0].layout);
8385
args[0].val.store(bx, place);
@@ -696,8 +698,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
696698
}
697699
ty::Array(elem, len)
698700
if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8))
699-
&& len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
700-
== Some(expected_bytes) =>
701+
&& len
702+
.try_to_target_usize(bx.tcx)
703+
.expect("expected monomorphic const in codegen")
704+
== expected_bytes =>
701705
{
702706
// Zero-extend iN to the array length:
703707
let ze = bx.zext(result, bx.type_ix(expected_bytes * 8));

compiler/rustc_codegen_llvm/src/intrinsic.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1179,8 +1179,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11791179
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
11801180
ty::Array(elem, len)
11811181
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
1182-
&& len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
1183-
== Some(expected_bytes) =>
1182+
&& len
1183+
.try_to_target_usize(bx.tcx)
1184+
.expect("expected monomorphic const in codegen")
1185+
== expected_bytes =>
11841186
{
11851187
let place = PlaceRef::alloca(bx, args[0].layout);
11861188
args[0].val.store(bx, place);
@@ -1245,12 +1247,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12451247
}
12461248

12471249
if name == sym::simd_shuffle_generic {
1248-
let idx = fn_args[2]
1249-
.expect_const()
1250-
.eval(tcx, ty::ParamEnv::reveal_all(), span)
1251-
.unwrap()
1252-
.1
1253-
.unwrap_branch();
1250+
let idx = fn_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
12541251
let n = idx.len() as u64;
12551252

12561253
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
@@ -1469,8 +1466,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
14691466
}
14701467
ty::Array(elem, len)
14711468
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
1472-
&& len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all())
1473-
== Some(expected_bytes) =>
1469+
&& len
1470+
.try_to_target_usize(bx.tcx)
1471+
.expect("expected monomorphic const in codegen")
1472+
== expected_bytes =>
14741473
{
14751474
// Zero-extend iN to the array length:
14761475
let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8));

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
2323
use rustc_middle::ty::{
2424
self, ExistentialProjection, GenericArgKind, GenericArgsRef, ParamEnv, Ty, TyCtxt,
2525
};
26-
use rustc_span::DUMMY_SP;
2726
use rustc_target::abi::Integer;
2827
use smallvec::SmallVec;
2928

@@ -685,21 +684,25 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
685684
ty::ConstKind::Param(param) => {
686685
write!(output, "{}", param.name)
687686
}
688-
ty::ConstKind::Value(ty, _) => {
687+
ty::ConstKind::Value(ty, valtree) => {
689688
match ty.kind() {
690689
ty::Int(ity) => {
691690
// FIXME: directly extract the bits from a valtree instead of evaluating an
692691
// already evaluated `Const` in order to get the bits.
693-
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
692+
let bits = ct
693+
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
694+
.expect("expected monomorphic const in codegen");
694695
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
695696
write!(output, "{val}")
696697
}
697698
ty::Uint(_) => {
698-
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
699+
let val = ct
700+
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
701+
.expect("expected monomorphic const in codegen");
699702
write!(output, "{val}")
700703
}
701704
ty::Bool => {
702-
let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
705+
let val = ct.try_to_bool().expect("expected monomorphic const in codegen");
703706
write!(output, "{val}")
704707
}
705708
_ => {
@@ -711,8 +714,9 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
711714
// avoiding collisions and will make the emitted type names shorter.
712715
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
713716
let mut hasher = StableHasher::new();
714-
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
715-
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
717+
hcx.while_hashing_spans(false, |hcx| {
718+
(ty, valtree).hash_stable(hcx, &mut hasher)
719+
});
716720
hasher.finish::<Hash64>()
717721
});
718722

compiler/rustc_const_eval/src/const_eval/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
4343

4444
// We go to `usize` as we cannot allocate anything bigger anyway.
4545
let (field_count, variant, down) = match ty.kind() {
46-
ty::Array(_, len) => (len.eval_target_usize(tcx.tcx, param_env) as usize, None, op),
46+
ty::Array(_, len) => (len.try_to_target_usize(tcx.tcx)? as usize, None, op),
4747
ty::Adt(def, _) if def.variants().is_empty() => {
4848
return None;
4949
}

compiler/rustc_const_eval/src/interpret/cast.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
391391
let ptr = self.read_pointer(src)?;
392392
let val = Immediate::new_slice(
393393
ptr,
394-
length.eval_target_usize(*self.tcx, self.param_env),
394+
length
395+
.try_to_target_usize(*self.tcx)
396+
.expect("expected monomorphic const in const eval"),
395397
self,
396398
);
397399
self.write_immediate(val, dest)

compiler/rustc_hir_analysis/src/check/check.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,11 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
10371037
return;
10381038
}
10391039

1040-
if let Some(len) = len_const.try_eval_target_usize(tcx, tcx.param_env(def.did())) {
1040+
// FIXME(repr_simd): This check is nice, but perhaps unnecessary due to the fact
1041+
// we do not expect users to implement their own `repr(simd)` types. If they could,
1042+
// this check is easily side-steppable by hiding the const behind normalization.
1043+
// The consequence is that the error is, in general, only observable post-mono.
1044+
if let Some(len) = len_const.try_to_target_usize(tcx) {
10411045
if len == 0 {
10421046
struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
10431047
return;

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
7676

7777
let (size, ty) = match elem_ty.kind() {
7878
ty::Array(ty, len) => {
79-
if let Some(len) =
80-
len.try_eval_target_usize(self.tcx, self.tcx.param_env(adt.did()))
81-
{
79+
if let Some(len) = len.try_to_target_usize(self.tcx) {
8280
(len, *ty)
8381
} else {
8482
return None;

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14871487
}
14881488
}
14891489
} else if self.tcx.features().generic_const_exprs {
1490-
ct.normalize(self.tcx, self.param_env)
1490+
ct.normalize_internal(self.tcx, self.param_env)
14911491
} else {
14921492
ct
14931493
}

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2601,7 +2601,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
26012601
ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field, init))
26022602
}
26032603
Array(ty, len) => {
2604-
if matches!(len.try_eval_target_usize(cx.tcx, cx.param_env), Some(v) if v > 0) {
2604+
if matches!(len.try_to_target_usize(cx.tcx), Some(v) if v > 0) {
26052605
// Array length known at array non-empty -- recurse.
26062606
ty_find_init_error(cx, *ty, init)
26072607
} else {

compiler/rustc_lint/src/unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
346346
None
347347
}
348348
}
349-
ty::Array(ty, len) => match len.try_eval_target_usize(cx.tcx, cx.param_env) {
349+
ty::Array(ty, len) => match len.try_to_target_usize(cx.tcx) {
350350
// If the array is empty we don't lint, to avoid false positives
351351
Some(0) | None => None,
352352
// If the array is definitely non-empty, we can do `#[must_use]` checking.

compiler/rustc_middle/src/mir/consts.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt::{self, Debug, Display, Formatter};
22

3+
use either::Either;
34
use rustc_hir::def_id::DefId;
45
use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
56
use rustc_session::RemapFileNameExt;
@@ -320,8 +321,14 @@ impl<'tcx> Const<'tcx> {
320321
Const::Ty(_, c) => {
321322
// We want to consistently have a "clean" value for type system constants (i.e., no
322323
// data hidden in the padding), so we always go through a valtree here.
323-
let (ty, val) = c.eval(tcx, param_env, span)?;
324-
Ok(tcx.valtree_to_const_val((ty, val)))
324+
match c.eval_valtree(tcx, param_env, span) {
325+
Ok((ty, val)) => Ok(tcx.valtree_to_const_val((ty, val))),
326+
Err(Either::Left(_bad_ty)) => Err(tcx
327+
.dcx()
328+
.delayed_bug("`mir::Const::eval` called on a non-valtree-compatible type")
329+
.into()),
330+
Err(Either::Right(e)) => Err(e),
331+
}
325332
}
326333
Const::Unevaluated(uneval, _) => {
327334
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`

compiler/rustc_middle/src/mir/tcx.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'tcx> PlaceTy<'tcx> {
5555
/// `PlaceElem`, where we can just use the `Ty` that is already
5656
/// stored inline on field projection elems.
5757
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
58-
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, ty| ty, |_, ty| ty)
58+
self.projection_ty_core(tcx, &elem, |_, _, ty| ty, |_, ty| ty)
5959
}
6060

6161
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@@ -66,7 +66,6 @@ impl<'tcx> PlaceTy<'tcx> {
6666
pub fn projection_ty_core<V, T>(
6767
self,
6868
tcx: TyCtxt<'tcx>,
69-
param_env: ty::ParamEnv<'tcx>,
7069
elem: &ProjectionElem<V, T>,
7170
mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
7271
mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>,
@@ -93,7 +92,9 @@ impl<'tcx> PlaceTy<'tcx> {
9392
ty::Slice(..) => self.ty,
9493
ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from),
9594
ty::Array(inner, size) if from_end => {
96-
let size = size.eval_target_usize(tcx, param_env);
95+
let size = size
96+
.try_to_target_usize(tcx)
97+
.expect("expected subslice projection on fixed-size array");
9798
let len = size - from - to;
9899
Ty::new_array(tcx, *inner, len)
99100
}

0 commit comments

Comments
 (0)