Skip to content

Commit 26c96e3

Browse files
committed
Auto merge of #103227 - lcnr:bye-bye-unevaluated-const, r=oli-obk
stop using `ty::UnevaluatedConst` directly best reviewed commit by commit. simplifies #99798 because we now don't have to expand `ty::UnevaluatedConst` to `ty::Const`. I also remember some other places where using `ty::UnevaluatedConst` directly was annoying and caused issues, though I don't quite remember what they were rn '^^ r? `@oli-obk` cc `@JulianKnodt`
2 parents 3022afe + b93713f commit 26c96e3

File tree

30 files changed

+131
-191
lines changed

30 files changed

+131
-191
lines changed

compiler/rustc_hir_analysis/src/check/dropck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
192192
(
193193
ty::PredicateKind::ConstEvaluatable(a),
194194
ty::PredicateKind::ConstEvaluatable(b),
195-
) => tcx.try_unify_abstract_consts(self_param_env.and((a, b))),
195+
) => relator.relate(predicate.rebind(a), predicate.rebind(b)).is_ok(),
196196
(
197197
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, lt_a)),
198198
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_b, lt_b)),

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,8 +1101,6 @@ fn check_type_defn<'tcx, F>(
11011101

11021102
// Explicit `enum` discriminant values must const-evaluate successfully.
11031103
if let Some(discr_def_id) = variant.explicit_discr {
1104-
let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id());
1105-
11061104
let cause = traits::ObligationCause::new(
11071105
tcx.def_span(discr_def_id),
11081106
wfcx.body_id,
@@ -1112,10 +1110,7 @@ fn check_type_defn<'tcx, F>(
11121110
cause,
11131111
wfcx.param_env,
11141112
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
1115-
ty::UnevaluatedConst::new(
1116-
ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
1117-
discr_substs,
1118-
),
1113+
ty::Const::from_anon_const(tcx, discr_def_id),
11191114
))
11201115
.to_predicate(tcx),
11211116
));

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,10 @@ fn const_evaluatable_predicates_of<'tcx>(
318318
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
319319
let def_id = self.tcx.hir().local_def_id(c.hir_id);
320320
let ct = ty::Const::from_anon_const(self.tcx, def_id);
321-
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
321+
if let ty::ConstKind::Unevaluated(_) = ct.kind() {
322322
let span = self.tcx.hir().span(c.hir_id);
323323
self.preds.insert((
324-
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
324+
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct))
325325
.to_predicate(self.tcx),
326326
span,
327327
));

compiler/rustc_middle/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#![feature(drain_filter)]
5656
#![feature(intra_doc_pointers)]
5757
#![feature(yeet_expr)]
58+
#![feature(result_option_inspect)]
5859
#![feature(const_option)]
5960
#![recursion_limit = "512"]
6061
#![allow(rustc::potential_query_instability)]

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::mir;
44
use crate::ty::subst::InternalSubsts;
55
use crate::ty::visit::TypeVisitable;
66
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
7+
use rustc_hir::def::DefKind;
78
use rustc_hir::def_id::DefId;
9+
use rustc_session::lint;
810
use rustc_span::{Span, DUMMY_SP};
911

1012
impl<'tcx> TyCtxt<'tcx> {
@@ -83,7 +85,29 @@ impl<'tcx> TyCtxt<'tcx> {
8385
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
8486
Ok(Some(instance)) => {
8587
let cid = GlobalId { instance, promoted: None };
86-
self.const_eval_global_id_for_typeck(param_env, cid, span)
88+
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
89+
// We are emitting the lint here instead of in `is_const_evaluatable`
90+
// as we normalize obligations before checking them, and normalization
91+
// uses this function to evaluate this constant.
92+
//
93+
// @lcnr believes that successfully evaluating even though there are
94+
// used generic parameters is a bug of evaluation, so checking for it
95+
// here does feel somewhat sensible.
96+
if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
97+
assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
98+
let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
99+
if mir_body.is_polymorphic {
100+
let Some(local_def_id) = ct.def.did.as_local() else { return };
101+
self.struct_span_lint_hir(
102+
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
103+
self.hir().local_def_id_to_hir_id(local_def_id),
104+
self.def_span(ct.def.did),
105+
"cannot use constants which depend on generic parameters in types",
106+
|err| err,
107+
)
108+
}
109+
}
110+
})
87111
}
88112
Ok(None) => Err(ErrorHandled::TooGeneric),
89113
Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ impl<'tcx> Const<'tcx> {
263263
self.try_eval_usize(tcx, param_env)
264264
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
265265
}
266+
267+
pub fn is_ct_infer(self) -> bool {
268+
matches!(self.kind(), ty::ConstKind::Infer(_))
269+
}
266270
}
267271

268272
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Const<'tcx> {

compiler/rustc_middle/src/ty/consts/kind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::ScalarInt;
1515

1616
/// An unevaluated (potentially generic) constant used in the type-system.
1717
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
18-
#[derive(Hash, HashStable)]
18+
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
1919
pub struct UnevaluatedConst<'tcx> {
2020
pub def: ty::WithOptConstParam<DefId>,
2121
pub substs: SubstsRef<'tcx>,

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ impl FlagComputation {
3434
result.flags
3535
}
3636

37-
pub fn for_unevaluated_const(uv: ty::UnevaluatedConst<'_>) -> TypeFlags {
38-
let mut result = FlagComputation::new();
39-
result.add_unevaluated_const(uv);
40-
result.flags
41-
}
42-
4337
fn add_flags(&mut self, flags: TypeFlags) {
4438
self.flags = self.flags | flags;
4539
}
@@ -256,7 +250,7 @@ impl FlagComputation {
256250
self.add_substs(substs);
257251
}
258252
ty::PredicateKind::ConstEvaluatable(uv) => {
259-
self.add_unevaluated_const(uv);
253+
self.add_const(uv);
260254
}
261255
ty::PredicateKind::ConstEquate(expected, found) => {
262256
self.add_const(expected);
@@ -289,7 +283,10 @@ impl FlagComputation {
289283
fn add_const(&mut self, c: ty::Const<'_>) {
290284
self.add_ty(c.ty());
291285
match c.kind() {
292-
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
286+
ty::ConstKind::Unevaluated(uv) => {
287+
self.add_substs(uv.substs);
288+
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
289+
}
293290
ty::ConstKind::Infer(infer) => {
294291
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
295292
match infer {
@@ -313,11 +310,6 @@ impl FlagComputation {
313310
}
314311
}
315312

316-
fn add_unevaluated_const(&mut self, ct: ty::UnevaluatedConst<'_>) {
317-
self.add_substs(ct.substs);
318-
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
319-
}
320-
321313
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
322314
self.add_substs(projection.substs);
323315
match projection.term.unpack() {

compiler/rustc_middle/src/ty/fold.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,6 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
126126
c.super_fold_with(self)
127127
}
128128

129-
fn fold_ty_unevaluated(
130-
&mut self,
131-
uv: ty::UnevaluatedConst<'tcx>,
132-
) -> ty::UnevaluatedConst<'tcx> {
133-
uv.super_fold_with(self)
134-
}
135-
136129
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
137130
p.super_fold_with(self)
138131
}
@@ -169,13 +162,6 @@ pub trait FallibleTypeFolder<'tcx>: Sized {
169162
c.try_super_fold_with(self)
170163
}
171164

172-
fn try_fold_ty_unevaluated(
173-
&mut self,
174-
c: ty::UnevaluatedConst<'tcx>,
175-
) -> Result<ty::UnevaluatedConst<'tcx>, Self::Error> {
176-
c.try_super_fold_with(self)
177-
}
178-
179165
fn try_fold_predicate(
180166
&mut self,
181167
p: ty::Predicate<'tcx>,
@@ -215,13 +201,6 @@ where
215201
Ok(self.fold_const(c))
216202
}
217203

218-
fn try_fold_ty_unevaluated(
219-
&mut self,
220-
c: ty::UnevaluatedConst<'tcx>,
221-
) -> Result<ty::UnevaluatedConst<'tcx>, !> {
222-
Ok(self.fold_ty_unevaluated(c))
223-
}
224-
225204
fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> {
226205
Ok(self.fold_predicate(p))
227206
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ pub enum PredicateKind<'tcx> {
683683
Coerce(CoercePredicate<'tcx>),
684684

685685
/// Constant initializer must evaluate successfully.
686-
ConstEvaluatable(ty::UnevaluatedConst<'tcx>),
686+
ConstEvaluatable(ty::Const<'tcx>),
687687

688688
/// Constants must be equal. The first component is the const that is expected.
689689
ConstEquate(Const<'tcx>, Const<'tcx>),

0 commit comments

Comments
 (0)