mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Promoteds also need param envs.
This also allows us to use the `const_eval` query again without causing cycles
This commit is contained in:
parent
36b1756711
commit
6e1bbff2c6
@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
|
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
|
||||||
if let Some(instance) = instance {
|
if let Some(instance) = instance {
|
||||||
if let Some(promoted) = promoted {
|
if let Some(promoted) = promoted {
|
||||||
self.const_eval_promoted(instance, promoted)
|
self.const_eval_promoted(param_env, instance, promoted)
|
||||||
} else {
|
} else {
|
||||||
self.const_eval_instance(param_env, instance, span)
|
self.const_eval_instance(param_env, instance, span)
|
||||||
}
|
}
|
||||||
@ -68,11 +68,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
/// Evaluate a promoted constant.
|
/// Evaluate a promoted constant.
|
||||||
pub fn const_eval_promoted(
|
pub fn const_eval_promoted(
|
||||||
self,
|
self,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
promoted: mir::Promoted,
|
promoted: mir::Promoted,
|
||||||
) -> ConstEvalResult<'tcx> {
|
) -> ConstEvalResult<'tcx> {
|
||||||
let cid = GlobalId { instance, promoted: Some(promoted) };
|
let cid = GlobalId { instance, promoted: Some(promoted) };
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
|
||||||
self.const_eval_validated(param_env.and(cid))
|
self.const_eval_validated(param_env.and(cid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -757,13 +757,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
&self,
|
&self,
|
||||||
gid: GlobalId<'tcx>,
|
gid: GlobalId<'tcx>,
|
||||||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||||
let val = if self.tcx.is_static(gid.instance.def_id()) {
|
// For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
|
||||||
self.tcx.const_eval_poly(gid.instance.def_id())?
|
// and thus don't care about the parameter environment. While we could just use
|
||||||
} else if let Some(promoted) = gid.promoted {
|
// `self.param_env`, that would mean we invoke the query to evaluate the static
|
||||||
self.tcx.const_eval_promoted(gid.instance, promoted)?
|
// with different parameter environments, thus causing the static to be evaluated
|
||||||
|
// multiple times.
|
||||||
|
let param_env = if self.tcx.is_static(gid.instance.def_id()) {
|
||||||
|
ty::ParamEnv::reveal_all()
|
||||||
} else {
|
} else {
|
||||||
self.tcx.const_eval_instance(self.param_env, gid.instance, Some(self.tcx.span))?
|
self.param_env
|
||||||
};
|
};
|
||||||
|
let val = if let Some(promoted) = gid.promoted {
|
||||||
|
self.tcx.const_eval_promoted(param_env, gid.instance, promoted)?
|
||||||
|
} else {
|
||||||
|
self.tcx.const_eval_instance(param_env, gid.instance, Some(self.tcx.span))?
|
||||||
|
};
|
||||||
|
|
||||||
// Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a
|
// Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a
|
||||||
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
|
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
|
||||||
// return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call
|
// return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call
|
||||||
|
@ -537,14 +537,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
// potentially requiring the current static to be evaluated again. This is not a
|
// potentially requiring the current static to be evaluated again. This is not a
|
||||||
// problem here, because we are building an operand which means an actual read is
|
// problem here, because we are building an operand which means an actual read is
|
||||||
// happening.
|
// happening.
|
||||||
// FIXME(oli-obk): eliminate all the `const_eval_raw` usages when we get rid of
|
return Ok(OpTy::from(self.const_eval(GlobalId { instance, promoted })?));
|
||||||
// `StaticKind` once and for all.
|
|
||||||
// FIXME the following line should have been:
|
|
||||||
// return self.const_eval(GlobalId { instance, promoted });
|
|
||||||
// but since the addition of Promoteds being Constants is causing const validation
|
|
||||||
// cycles. Promoteds being Constants exercise const validation more often and it
|
|
||||||
// may have made show up a pre-existing bug.
|
|
||||||
return Ok(OpTy::from(self.const_eval_raw(GlobalId { instance, promoted })?));
|
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(..)
|
ty::ConstKind::Infer(..)
|
||||||
| ty::ConstKind::Bound(..)
|
| ty::ConstKind::Bound(..)
|
||||||
|
@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
|
|||||||
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
|
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
|
||||||
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
|
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
|
||||||
LL | | let out_of_bounds_ptr = &ptr[255];
|
LL | | let out_of_bounds_ptr = &ptr[255];
|
||||||
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1
|
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 9 which has size 1
|
||||||
LL | | mem::transmute(out_of_bounds_ptr)
|
LL | | mem::transmute(out_of_bounds_ptr)
|
||||||
LL | | } };
|
LL | | } };
|
||||||
| |____-
|
| |____-
|
||||||
|
Loading…
Reference in New Issue
Block a user