Skip to content

Commit 6e1bbff

Browse files
committed
Promoteds also need param envs.
This also allows us to use the `const_eval` query again without causing cycles
1 parent 36b1756 commit 6e1bbff

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

src/librustc/mir/interpret/queries.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> {
4242
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
4343
if let Some(instance) = instance {
4444
if let Some(promoted) = promoted {
45-
self.const_eval_promoted(instance, promoted)
45+
self.const_eval_promoted(param_env, instance, promoted)
4646
} else {
4747
self.const_eval_instance(param_env, instance, span)
4848
}
@@ -68,11 +68,11 @@ impl<'tcx> TyCtxt<'tcx> {
6868
/// Evaluate a promoted constant.
6969
pub fn const_eval_promoted(
7070
self,
71+
param_env: ty::ParamEnv<'tcx>,
7172
instance: ty::Instance<'tcx>,
7273
promoted: mir::Promoted,
7374
) -> ConstEvalResult<'tcx> {
7475
let cid = GlobalId { instance, promoted: Some(promoted) };
75-
let param_env = ty::ParamEnv::reveal_all();
7676
self.const_eval_validated(param_env.and(cid))
7777
}
7878
}

src/librustc_mir/interpret/eval_context.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -757,13 +757,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
757757
&self,
758758
gid: GlobalId<'tcx>,
759759
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
760-
let val = if self.tcx.is_static(gid.instance.def_id()) {
761-
self.tcx.const_eval_poly(gid.instance.def_id())?
762-
} else if let Some(promoted) = gid.promoted {
763-
self.tcx.const_eval_promoted(gid.instance, promoted)?
760+
// For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
761+
// and thus don't care about the parameter environment. While we could just use
762+
// `self.param_env`, that would mean we invoke the query to evaluate the static
763+
// with different parameter environments, thus causing the static to be evaluated
764+
// multiple times.
765+
let param_env = if self.tcx.is_static(gid.instance.def_id()) {
766+
ty::ParamEnv::reveal_all()
764767
} else {
765-
self.tcx.const_eval_instance(self.param_env, gid.instance, Some(self.tcx.span))?
768+
self.param_env
766769
};
770+
let val = if let Some(promoted) = gid.promoted {
771+
self.tcx.const_eval_promoted(param_env, gid.instance, promoted)?
772+
} else {
773+
self.tcx.const_eval_instance(param_env, gid.instance, Some(self.tcx.span))?
774+
};
775+
767776
// Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a
768777
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
769778
// return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call

src/librustc_mir/interpret/operand.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -537,14 +537,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
537537
// potentially requiring the current static to be evaluated again. This is not a
538538
// problem here, because we are building an operand which means an actual read is
539539
// happening.
540-
// FIXME(oli-obk): eliminate all the `const_eval_raw` usages when we get rid of
541-
// `StaticKind` once and for all.
542-
// FIXME the following line should have been:
543-
// return self.const_eval(GlobalId { instance, promoted });
544-
// but since the addition of Promoteds being Constants is causing const validation
545-
// cycles. Promoteds being Constants exercise const validation more often and it
546-
// may have made show up a pre-existing bug.
547-
return Ok(OpTy::from(self.const_eval_raw(GlobalId { instance, promoted })?));
540+
return Ok(OpTy::from(self.const_eval(GlobalId { instance, promoted })?));
548541
}
549542
ty::ConstKind::Infer(..)
550543
| ty::ConstKind::Bound(..)

src/test/ui/consts/const-eval/ub-nonnull.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
1313
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
1414
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
1515
LL | | let out_of_bounds_ptr = &ptr[255];
16-
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1
16+
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 9 which has size 1
1717
LL | | mem::transmute(out_of_bounds_ptr)
1818
LL | | } };
1919
| |____-

0 commit comments

Comments
 (0)