Skip to content

Commit c524c7d

Browse files
committed
Auto merge of rust-lang#98588 - b-naber:valtrees-cleanup, r=lcnr
Use only ty::Unevaluated<'tcx, ()> in type system r? `@lcnr`
2 parents 95a992a + d77248e commit c524c7d

File tree

59 files changed

+384
-324
lines changed

Some content is hidden

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

59 files changed

+384
-324
lines changed

compiler/rustc_borrowck/src/renumber.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_index::vec::IndexVec;
22
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
33
use rustc_middle::mir::visit::{MutVisitor, TyContext};
44
use rustc_middle::mir::{Body, Location, Promoted};
5+
use rustc_middle::mir::{Constant, ConstantKind};
56
use rustc_middle::ty::subst::SubstsRef;
67
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
78

@@ -37,6 +38,21 @@ where
3738
})
3839
}
3940

41+
// FIXME(valtrees): This function is necessary because `fold_regions`
42+
// panics for mir constants in the visitor.
43+
//
44+
// Once `visit_mir_constant` is removed we can also remove this function
45+
// and just use `renumber_regions`.
46+
fn renumber_regions_in_mir_constant<'tcx>(
47+
infcx: &InferCtxt<'_, 'tcx>,
48+
value: ConstantKind<'tcx>,
49+
) -> ConstantKind<'tcx> {
50+
infcx.tcx.super_fold_regions(value, |_region, _depth| {
51+
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
52+
infcx.next_nll_region_var(origin)
53+
})
54+
}
55+
4056
struct NllVisitor<'a, 'tcx> {
4157
infcx: &'a InferCtxt<'a, 'tcx>,
4258
}
@@ -48,6 +64,13 @@ impl<'a, 'tcx> NllVisitor<'a, 'tcx> {
4864
{
4965
renumber_regions(self.infcx, value)
5066
}
67+
68+
fn renumber_regions_in_mir_constant(
69+
&mut self,
70+
value: ConstantKind<'tcx>,
71+
) -> ConstantKind<'tcx> {
72+
renumber_regions_in_mir_constant(self.infcx, value)
73+
}
5174
}
5275

5376
impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
@@ -77,7 +100,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
77100
debug!(?region);
78101
}
79102

80-
fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
81-
*constant = self.renumber_regions(*constant);
103+
#[instrument(skip(self), level = "debug")]
104+
fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) {
105+
let literal = constant.literal;
106+
constant.literal = self.renumber_regions_in_mir_constant(literal);
107+
debug!("constant: {:#?}", constant);
82108
}
83109
}

compiler/rustc_borrowck/src/type_check/mod.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,15 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
355355
let tcx = self.tcx();
356356
let maybe_uneval = match constant.literal {
357357
ConstantKind::Ty(ct) => match ct.kind() {
358-
ty::ConstKind::Unevaluated(uv) => Some(uv),
358+
ty::ConstKind::Unevaluated(_) => {
359+
bug!("should not encounter unevaluated ConstantKind::Ty here, got {:?}", ct)
360+
}
359361
_ => None,
360362
},
363+
ConstantKind::Unevaluated(uv, _) => Some(uv),
361364
_ => None,
362365
};
366+
363367
if let Some(uv) = maybe_uneval {
364368
if let Some(promoted) = uv.promoted {
365369
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
@@ -1813,12 +1817,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18131817
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
18141818
if let Operand::Constant(constant) = op {
18151819
let maybe_uneval = match constant.literal {
1816-
ConstantKind::Ty(ct) => match ct.kind() {
1817-
ty::ConstKind::Unevaluated(uv) => Some(uv),
1818-
_ => None,
1819-
},
1820-
_ => None,
1820+
ConstantKind::Val(..) | ConstantKind::Ty(_) => None,
1821+
ConstantKind::Unevaluated(uv, _) => Some(uv),
18211822
};
1823+
18221824
if let Some(uv) = maybe_uneval {
18231825
if uv.promoted.is_none() {
18241826
let tcx = self.tcx();

compiler/rustc_codegen_cranelift/src/constant.rs

+31-42
Original file line numberDiff line numberDiff line change
@@ -41,36 +41,30 @@ impl ConstantCx {
4141
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
4242
let mut all_constants_ok = true;
4343
for constant in &fx.mir.required_consts {
44-
let const_ = match fx.monomorphize(constant.literal) {
45-
ConstantKind::Ty(ct) => ct,
44+
let unevaluated = match fx.monomorphize(constant.literal) {
45+
ConstantKind::Ty(ct) => match ct.kind() {
46+
ConstKind::Unevaluated(uv) => uv.expand(),
47+
ConstKind::Value(_) => continue,
48+
ConstKind::Param(_)
49+
| ConstKind::Infer(_)
50+
| ConstKind::Bound(_, _)
51+
| ConstKind::Placeholder(_)
52+
| ConstKind::Error(_) => unreachable!("{:?}", ct),
53+
},
54+
ConstantKind::Unevaluated(uv, _) => uv,
4655
ConstantKind::Val(..) => continue,
4756
};
48-
match const_.kind() {
49-
ConstKind::Value(_) => {}
50-
ConstKind::Unevaluated(unevaluated) => {
51-
if let Err(err) =
52-
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
53-
{
54-
all_constants_ok = false;
55-
match err {
56-
ErrorHandled::Reported(_) | ErrorHandled::Linted => {
57-
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
58-
}
59-
ErrorHandled::TooGeneric => {
60-
span_bug!(
61-
constant.span,
62-
"codegen encountered polymorphic constant: {:?}",
63-
err
64-
);
65-
}
66-
}
57+
58+
if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
59+
all_constants_ok = false;
60+
match err {
61+
ErrorHandled::Reported(_) | ErrorHandled::Linted => {
62+
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
63+
}
64+
ErrorHandled::TooGeneric => {
65+
span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
6766
}
6867
}
69-
ConstKind::Param(_)
70-
| ConstKind::Infer(_)
71-
| ConstKind::Bound(_, _)
72-
| ConstKind::Placeholder(_)
73-
| ConstKind::Error(_) => unreachable!("{:?}", const_),
7468
}
7569
}
7670
all_constants_ok
@@ -122,36 +116,28 @@ pub(crate) fn codegen_constant<'tcx>(
122116
fx: &mut FunctionCx<'_, '_, 'tcx>,
123117
constant: &Constant<'tcx>,
124118
) -> CValue<'tcx> {
125-
let const_ = match fx.monomorphize(constant.literal) {
126-
ConstantKind::Ty(ct) => ct,
127-
ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
128-
};
129-
let const_val = match const_.kind() {
130-
ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)),
131-
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
119+
let (const_val, ty) = match fx.monomorphize(constant.literal) {
120+
ConstantKind::Ty(const_) => unreachable!("{:?}", const_),
121+
ConstantKind::Unevaluated(ty::Unevaluated { def, substs, promoted }, ty)
132122
if fx.tcx.is_static(def.did) =>
133123
{
134124
assert!(substs.is_empty());
135125
assert!(promoted.is_none());
136126

137-
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx);
127+
return codegen_static_ref(fx, def.did, fx.layout_of(ty)).to_cvalue(fx);
138128
}
139-
ConstKind::Unevaluated(unevaluated) => {
129+
ConstantKind::Unevaluated(unevaluated, ty) => {
140130
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
141-
Ok(const_val) => const_val,
131+
Ok(const_val) => (const_val, ty),
142132
Err(_) => {
143133
span_bug!(constant.span, "erroneous constant not captured by required_consts");
144134
}
145135
}
146136
}
147-
ConstKind::Param(_)
148-
| ConstKind::Infer(_)
149-
| ConstKind::Bound(_, _)
150-
| ConstKind::Placeholder(_)
151-
| ConstKind::Error(_) => unreachable!("{:?}", const_),
137+
ConstantKind::Val(val, ty) => (val, ty),
152138
};
153139

154-
codegen_const_value(fx, const_val, const_.ty())
140+
codegen_const_value(fx, const_val, ty)
155141
}
156142

157143
pub(crate) fn codegen_const_value<'tcx>(
@@ -496,6 +482,9 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
496482
.eval_for_mir(fx.tcx, ParamEnv::reveal_all())
497483
.try_to_value(fx.tcx),
498484
ConstantKind::Val(val, _) => Some(val),
485+
ConstantKind::Unevaluated(uv, _) => {
486+
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).ok()
487+
}
499488
},
500489
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
501490
// inside a temporary before being passed to the intrinsic requiring the const argument.

compiler/rustc_codegen_ssa/src/mir/constant.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2525
constant: &mir::Constant<'tcx>,
2626
) -> Result<ConstValue<'tcx>, ErrorHandled> {
2727
let ct = self.monomorphize(constant.literal);
28-
let ct = match ct {
29-
mir::ConstantKind::Ty(ct) => ct,
28+
let uv = match ct {
29+
mir::ConstantKind::Ty(ct) => match ct.kind() {
30+
ty::ConstKind::Unevaluated(uv) => uv.expand(),
31+
ty::ConstKind::Value(val) => {
32+
return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val)));
33+
}
34+
err => span_bug!(
35+
constant.span,
36+
"encountered bad ConstKind after monomorphizing: {:?}",
37+
err
38+
),
39+
},
40+
mir::ConstantKind::Unevaluated(uv, _) => uv,
3041
mir::ConstantKind::Val(val, _) => return Ok(val),
3142
};
32-
match ct.kind() {
33-
ty::ConstKind::Unevaluated(ct) => self
34-
.cx
35-
.tcx()
36-
.const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
37-
.map_err(|err| {
38-
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
39-
err
40-
}),
41-
ty::ConstKind::Value(val) => Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))),
42-
err => span_bug!(
43-
constant.span,
44-
"encountered bad ConstKind after monomorphizing: {:?}",
45-
err
46-
),
47-
}
43+
44+
self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
45+
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
46+
err
47+
})
4848
}
4949

5050
/// process constant containing SIMD shuffle indices

compiler/rustc_const_eval/src/interpret/operand.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
564564
throw_inval!(AlreadyReported(reported))
565565
}
566566
ty::ConstKind::Unevaluated(uv) => {
567+
// NOTE: We evaluate to a `ValTree` here as a check to ensure
568+
// we're working with valid constants, even though we never need it.
567569
let instance = self.resolve(uv.def, uv.substs)?;
568-
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
570+
let cid = GlobalId { instance, promoted: None };
571+
let _valtree = self
572+
.tcx
573+
.eval_to_valtree(self.param_env.and(cid))?
574+
.unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv));
575+
576+
Ok(self.eval_to_allocation(cid)?.into())
569577
}
570578
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
571579
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
@@ -586,6 +594,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
586594
match val {
587595
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
588596
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
597+
mir::ConstantKind::Unevaluated(uv, _) => {
598+
let instance = self.resolve(uv.def, uv.substs)?;
599+
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
600+
}
589601
}
590602
}
591603

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+33-21
Original file line numberDiff line numberDiff line change
@@ -346,31 +346,43 @@ where
346346
};
347347

348348
// Check the qualifs of the value of `const` items.
349-
if let Some(ct) = constant.literal.const_for_ty() {
350-
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.kind()
351-
{
352-
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
353-
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
354-
// check performed after the promotion. Verify that with an assertion.
355-
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
356-
// Don't peek inside trait associated constants.
357-
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
358-
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
359-
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
360-
} else {
361-
cx.tcx.at(constant.span).mir_const_qualif(def.did)
362-
};
363-
364-
if !Q::in_qualifs(&qualifs) {
365-
return false;
366-
}
349+
// FIXME(valtrees): check whether const qualifs should behave the same
350+
// way for type and mir constants.
351+
let uneval = match constant.literal {
352+
ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => {
353+
let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() };
367354

368-
// Just in case the type is more specific than
369-
// the definition, e.g., impl associated const
370-
// with type parameters, take it into account.
355+
Some(uv.expand())
356+
}
357+
ConstantKind::Ty(_) => None,
358+
ConstantKind::Unevaluated(uv, _) => Some(uv),
359+
ConstantKind::Val(..) => None,
360+
};
361+
362+
if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval {
363+
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
364+
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
365+
// check performed after the promotion. Verify that with an assertion.
366+
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
367+
368+
// Don't peek inside trait associated constants.
369+
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
370+
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
371+
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
372+
} else {
373+
cx.tcx.at(constant.span).mir_const_qualif(def.did)
374+
};
375+
376+
if !Q::in_qualifs(&qualifs) {
377+
return false;
371378
}
379+
380+
// Just in case the type is more specific than
381+
// the definition, e.g., impl associated const
382+
// with type parameters, take it into account.
372383
}
373384
}
385+
374386
// Otherwise use the qualifs of the type.
375387
Q::in_any_value_of_ty(cx, constant.literal.ty())
376388
}

compiler/rustc_const_eval/src/transform/promote_consts.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -840,21 +840,15 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
840840
promoted.span = span;
841841
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
842842
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
843-
let _const = tcx.mk_const(ty::ConstS {
844-
ty,
845-
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
846-
def,
847-
substs,
848-
promoted: Some(promoted_id),
849-
}),
850-
});
843+
let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) };
851844

852845
Operand::Constant(Box::new(Constant {
853846
span,
854847
user_ty: None,
855-
literal: ConstantKind::from_const(_const, tcx),
848+
literal: ConstantKind::Unevaluated(uneval, ty),
856849
}))
857850
};
851+
858852
let blocks = self.source.basic_blocks.as_mut();
859853
let local_decls = &mut self.source.local_decls;
860854
let loc = candidate.location;

compiler/rustc_infer/src/infer/combine.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
743743
}
744744
}
745745
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
746-
assert_eq!(promoted, None);
746+
assert_eq!(promoted, ());
747+
747748
let substs = self.relate_with_variance(
748749
ty::Variance::Invariant,
749750
ty::VarianceDiagInfo::default(),
@@ -964,13 +965,15 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
964965
}
965966
}
966967
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
967-
assert_eq!(promoted, None);
968+
assert_eq!(promoted, ());
969+
968970
let substs = self.relate_with_variance(
969971
ty::Variance::Invariant,
970972
ty::VarianceDiagInfo::default(),
971973
substs,
972974
substs,
973975
)?;
976+
974977
Ok(self.tcx().mk_const(ty::ConstS {
975978
ty: c.ty(),
976979
kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),

0 commit comments

Comments
 (0)