Skip to content

Commit e0b833e

Browse files
committed
cleanup eval() functions on our const types
1 parent 3e1515b commit e0b833e

File tree

29 files changed

+211
-382
lines changed

29 files changed

+211
-382
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -733,11 +733,7 @@ fn codegen_stmt<'tcx>(
733733
}
734734
Rvalue::Repeat(ref operand, times) => {
735735
let operand = codegen_operand(fx, operand);
736-
let times = fx
737-
.monomorphize(times)
738-
.eval(fx.tcx, ParamEnv::reveal_all())
739-
.try_to_bits(fx.tcx.data_layout.pointer_size)
740-
.unwrap();
736+
let times = fx.monomorphize(times).try_to_target_usize(fx.tcx).unwrap();
741737
if operand.layout().size.bytes() == 0 {
742738
// Do nothing for ZST's
743739
} else if fx.clif_type(operand.layout().ty) == Some(types::I8) {

compiler/rustc_codegen_cranelift/src/constant.rs

+3-25
Original file line numberDiff line numberDiff line change
@@ -67,34 +67,12 @@ pub(crate) fn eval_mir_constant<'tcx>(
6767
fx: &FunctionCx<'_, '_, 'tcx>,
6868
constant: &Constant<'tcx>,
6969
) -> (ConstValue<'tcx>, Ty<'tcx>) {
70-
let constant_kind = fx.monomorphize(constant.literal);
71-
let uv = match constant_kind {
72-
ConstantKind::Ty(const_) => match const_.kind() {
73-
ty::ConstKind::Unevaluated(uv) => uv.expand(),
74-
ty::ConstKind::Value(val) => {
75-
return (fx.tcx.valtree_to_const_val((const_.ty(), val)), const_.ty());
76-
}
77-
err => span_bug!(
78-
constant.span,
79-
"encountered bad ConstKind after monomorphizing: {:?}",
80-
err
81-
),
82-
},
83-
ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _)
84-
if fx.tcx.is_static(def) =>
85-
{
86-
span_bug!(constant.span, "MIR constant refers to static");
87-
}
88-
ConstantKind::Unevaluated(uv, _) => uv,
89-
ConstantKind::Val(val, _) => return (val, constant_kind.ty()),
90-
};
91-
9270
// This cannot fail because we checked all required_consts in advance.
9371
let val = fx
94-
.tcx
95-
.const_eval_resolve(ty::ParamEnv::reveal_all(), uv, Some(constant.span))
72+
.monomorphize(constant.literal)
73+
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
9674
.expect("erroneous constant not captured by required_consts");
97-
(val, constant_kind.ty())
75+
(val, constant.ty())
9876
}
9977

10078
pub(crate) fn codegen_constant_operand<'tcx>(

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -670,10 +670,8 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
670670
// avoiding collisions and will make the emitted type names shorter.
671671
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
672672
let mut hasher = StableHasher::new();
673-
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all());
674-
hcx.while_hashing_spans(false, |hcx| {
675-
ct.to_valtree().hash_stable(hcx, &mut hasher)
676-
});
673+
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), None);
674+
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
677675
hasher.finish::<Hash64>()
678676
});
679677

compiler/rustc_codegen_ssa/src/mir/constant.rs

+5-21
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2121
}
2222

2323
pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> {
24-
let ct = self.monomorphize(constant.literal);
25-
let uv = match ct {
26-
mir::ConstantKind::Ty(ct) => match ct.kind() {
27-
ty::ConstKind::Unevaluated(uv) => uv.expand(),
28-
ty::ConstKind::Value(val) => {
29-
return self.cx.tcx().valtree_to_const_val((ct.ty(), val));
30-
}
31-
err => span_bug!(
32-
constant.span,
33-
"encountered bad ConstKind after monomorphizing: {:?}",
34-
err
35-
),
36-
},
37-
mir::ConstantKind::Unevaluated(uv, _) => uv,
38-
mir::ConstantKind::Val(val, _) => return val,
39-
};
40-
4124
// This cannot fail because we checked all required_consts in advance.
42-
self.cx
43-
.tcx()
44-
.const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None)
25+
self.monomorphize(constant.literal)
26+
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
4527
.expect("erroneous constant not captured by required_consts")
4628
}
4729

4830
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
4931
/// that the given `constant` is an `ConstantKind::Unevaluated` and must be convertible to
5032
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
33+
///
34+
/// Note that this function is cursed, since usually MIR consts should not be evaluated to valtrees!
5135
pub fn eval_unevaluated_mir_constant_to_valtree(
5236
&self,
5337
constant: &mir::Constant<'tcx>,
@@ -67,7 +51,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6751
// `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but
6852
// the user pass through arbitrary expressions.
6953
// FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a real
70-
// const generic.
54+
// const generic, and get rid of this entire function.
7155
other => span_bug!(constant.span, "{other:#?}"),
7256
};
7357
let uv = self.monomorphize(uv);

compiler/rustc_const_eval/src/const_eval/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::errors::MaxNumNodesInConstErr;
44
use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar};
55
use rustc_middle::mir;
6-
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
6+
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
77
use rustc_middle::ty::{self, Ty, TyCtxt};
88
use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
99

@@ -70,15 +70,19 @@ pub(crate) fn eval_to_valtree<'tcx>(
7070
Ok(valtree) => Ok(Some(valtree)),
7171
Err(err) => {
7272
let did = cid.instance.def_id();
73+
let span = tcx.hir().span_if_local(did);
7374
let global_const_id = cid.display(tcx);
7475
match err {
7576
ValTreeCreationError::NodesOverflow => {
76-
let span = tcx.hir().span_if_local(did);
77-
tcx.sess.emit_err(MaxNumNodesInConstErr { span, global_const_id });
78-
77+
let g = tcx.sess.emit_err(MaxNumNodesInConstErr { span, global_const_id });
78+
Err(ErrorHandled::Reported(g.into(), span.unwrap_or(DUMMY_SP)))
79+
}
80+
ValTreeCreationError::NonSupportedType | ValTreeCreationError::Other => {
81+
// Sadly we cannot report an error or `delay_span_bug` here; pattern
82+
// construction calls this function speculatively needs the `None` to fall back
83+
// to MIR constant value.
7984
Ok(None)
8085
}
81-
ValTreeCreationError::NonSupportedType | ValTreeCreationError::Other => Ok(None),
8286
}
8387
}
8488
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use rustc_span::Span;
2020
use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout};
2121

2222
use super::{
23-
AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace,
24-
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, Pointer, PointerArithmetic,
25-
Projectable, Provenance, Scalar, StackPopJump,
23+
AllocId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta,
24+
Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable,
25+
Provenance, Scalar, StackPopJump,
2626
};
2727
use crate::errors::{self, ErroneousConstUsed};
2828
use crate::util;
@@ -1078,23 +1078,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10781078
})
10791079
}
10801080

1081-
pub fn eval_global(
1081+
pub fn eval_mir_constant(
10821082
&self,
1083-
gid: GlobalId<'tcx>,
1083+
val: &mir::ConstantKind<'tcx>,
10841084
span: Option<Span>,
1085-
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
1086-
// For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
1087-
// and thus don't care about the parameter environment. While we could just use
1088-
// `self.param_env`, that would mean we invoke the query to evaluate the static
1089-
// with different parameter environments, thus causing the static to be evaluated
1090-
// multiple times.
1091-
let param_env = if self.tcx.is_static(gid.instance.def_id()) {
1092-
ty::ParamEnv::reveal_all()
1093-
} else {
1094-
self.param_env
1095-
};
1096-
let val = self.ctfe_query(span, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?;
1097-
self.raw_const_to_mplace(val)
1085+
layout: Option<TyAndLayout<'tcx>>,
1086+
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
1087+
let const_val = self.ctfe_query(span, |tcx| val.eval(*tcx, self.param_env, span))?;
1088+
self.const_val_to_op(const_val, val.ty(), layout)
10981089
}
10991090

11001091
#[must_use]

compiler/rustc_const_eval/src/interpret/operand.rs

+4-53
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ use either::{Either, Left, Right};
88
use rustc_hir::def::Namespace;
99
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
1010
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
11-
use rustc_middle::ty::{ConstInt, Ty, ValTree};
11+
use rustc_middle::ty::{ConstInt, Ty};
1212
use rustc_middle::{mir, ty};
13-
use rustc_span::Span;
1413
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size};
1514

1615
use super::{
17-
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId,
18-
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer,
19-
Projectable, Provenance, Scalar,
16+
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, InterpCx,
17+
InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable,
18+
Provenance, Scalar,
2019
};
2120

2221
/// An `Immediate` represents a single immediate self-contained Rust value.
@@ -693,54 +692,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
693692
Ok(op)
694693
}
695694

696-
fn eval_ty_constant(
697-
&self,
698-
val: ty::Const<'tcx>,
699-
span: Option<Span>,
700-
) -> InterpResult<'tcx, ValTree<'tcx>> {
701-
Ok(match val.kind() {
702-
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => {
703-
throw_inval!(TooGeneric)
704-
}
705-
// FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated
706-
ty::ConstKind::Expr(_) => throw_inval!(TooGeneric),
707-
ty::ConstKind::Error(reported) => {
708-
throw_inval!(AlreadyReported(reported.into()))
709-
}
710-
ty::ConstKind::Unevaluated(uv) => {
711-
let instance = self.resolve(uv.def, uv.args)?;
712-
let cid = GlobalId { instance, promoted: None };
713-
self.ctfe_query(span, |tcx| tcx.eval_to_valtree(self.param_env.and(cid)))?
714-
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"))
715-
}
716-
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
717-
span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}")
718-
}
719-
ty::ConstKind::Value(valtree) => valtree,
720-
})
721-
}
722-
723-
pub fn eval_mir_constant(
724-
&self,
725-
val: &mir::ConstantKind<'tcx>,
726-
span: Option<Span>,
727-
layout: Option<TyAndLayout<'tcx>>,
728-
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
729-
match *val {
730-
mir::ConstantKind::Ty(ct) => {
731-
let ty = ct.ty();
732-
let valtree = self.eval_ty_constant(ct, span)?;
733-
let const_val = self.tcx.valtree_to_const_val((ty, valtree));
734-
self.const_val_to_op(const_val, ty, layout)
735-
}
736-
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
737-
mir::ConstantKind::Unevaluated(uv, _) => {
738-
let instance = self.resolve(uv.def, uv.args)?;
739-
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
740-
}
741-
}
742-
}
743-
744695
pub(crate) fn const_val_to_op(
745696
&self,
746697
val_val: ConstValue<'tcx>,

compiler/rustc_infer/src/infer/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub use self::RegionVariableOrigin::*;
66
pub use self::SubregionOrigin::*;
77
pub use self::ValuePairs::*;
88
pub use combine::ObligationEmittingRelation;
9-
use rustc_data_structures::undo_log::UndoLogs;
109

1110
use self::opaque_types::OpaqueTypeStorage;
1211
pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
@@ -17,6 +16,7 @@ use rustc_data_structures::fx::FxIndexMap;
1716
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1817
use rustc_data_structures::sync::Lrc;
1918
use rustc_data_structures::undo_log::Rollback;
19+
use rustc_data_structures::undo_log::UndoLogs;
2020
use rustc_data_structures::unify as ut;
2121
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
2222
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -36,7 +36,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtx
3636
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
3737
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
3838
use rustc_span::symbol::Symbol;
39-
use rustc_span::Span;
39+
use rustc_span::{Span, DUMMY_SP};
4040

4141
use std::cell::{Cell, RefCell};
4242
use std::fmt;
@@ -1552,15 +1552,15 @@ impl<'tcx> InferCtxt<'tcx> {
15521552
// variables
15531553
let tcx = self.tcx;
15541554
if args.has_non_region_infer() {
1555-
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
1555+
if let Some(ct) = tcx
1556+
.thir_abstract_const(unevaluated.def)
1557+
.map_err(|e| ErrorHandled::Reported(e.into(), DUMMY_SP))?
1558+
{
15561559
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
15571560
if let Err(e) = ct.error_reported() {
1558-
return Err(ErrorHandled::Reported(
1559-
e.into(),
1560-
span.unwrap_or(rustc_span::DUMMY_SP),
1561-
));
1561+
return Err(ErrorHandled::Reported(e.into(), span.unwrap_or(DUMMY_SP)));
15621562
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
1563-
return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
1563+
return Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP)));
15641564
} else {
15651565
args = replace_param_and_infer_args_with_placeholder(tcx, args);
15661566
}

compiler/rustc_middle/src/mir/interpret/error.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_errors::{
1111
};
1212
use rustc_macros::HashStable;
1313
use rustc_session::CtfeBacktrace;
14-
use rustc_span::{def_id::DefId, Span, DUMMY_SP};
14+
use rustc_span::{def_id::DefId, Span};
1515
use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange};
1616

1717
use std::borrow::Cow;
@@ -27,13 +27,6 @@ pub enum ErrorHandled {
2727
TooGeneric(Span),
2828
}
2929

30-
impl From<ErrorGuaranteed> for ErrorHandled {
31-
#[inline]
32-
fn from(error: ErrorGuaranteed) -> ErrorHandled {
33-
ErrorHandled::Reported(error.into(), DUMMY_SP)
34-
}
35-
}
36-
3730
impl ErrorHandled {
3831
pub fn with_span(self, span: Span) -> Self {
3932
match self {
@@ -80,6 +73,8 @@ TrivialTypeTraversalAndLiftImpls! { ErrorHandled }
8073

8174
pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
8275
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
76+
/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
77+
/// This is needed in `thir::pattern::lower_inline_const`.
8378
pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
8479

8580
pub fn struct_error<'tcx>(

0 commit comments

Comments
 (0)