update const_eval_resolve
This commit is contained in:
parent
43ebac119b
commit
7c9b5b4ce0
13 changed files with 45 additions and 55 deletions
|
@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
|
||||||
};
|
};
|
||||||
match const_.val {
|
match const_.val {
|
||||||
ConstKind::Value(_) => {}
|
ConstKind::Value(_) => {}
|
||||||
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
ConstKind::Unevaluated(unevaluated) => {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
|
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
|
||||||
{
|
{
|
||||||
all_constants_ok = false;
|
all_constants_ok = false;
|
||||||
match err {
|
match err {
|
||||||
|
@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>(
|
||||||
};
|
};
|
||||||
let const_val = match const_.val {
|
let const_val = match const_.val {
|
||||||
ConstKind::Value(const_val) => const_val,
|
ConstKind::Value(const_val) => const_val,
|
||||||
ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => {
|
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => {
|
||||||
assert!(substs.is_empty());
|
assert!(substs.is_empty());
|
||||||
assert!(promoted.is_none());
|
assert!(promoted.is_none());
|
||||||
|
|
||||||
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
|
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
|
||||||
}
|
}
|
||||||
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
ConstKind::Unevaluated(unevaluated) => {
|
||||||
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
|
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
|
||||||
Ok(const_val) => const_val,
|
Ok(const_val) => const_val,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
span_bug!(constant.span, "erroneous constant not captured by required_consts");
|
span_bug!(constant.span, "erroneous constant not captured by required_consts");
|
||||||
|
|
|
@ -30,10 +30,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
mir::ConstantKind::Val(val, _) => return Ok(val),
|
mir::ConstantKind::Val(val, _) => return Ok(val),
|
||||||
};
|
};
|
||||||
match ct.val {
|
match ct.val {
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => self
|
ty::ConstKind::Unevaluated(ct) => self
|
||||||
.cx
|
.cx
|
||||||
.tcx()
|
.tcx()
|
||||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
|
.const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
|
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
|
||||||
err
|
err
|
||||||
|
|
|
@ -18,7 +18,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
||||||
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
||||||
use rustc_middle::mir;
|
|
||||||
use rustc_middle::mir::interpret::EvalToConstValueResult;
|
use rustc_middle::mir::interpret::EvalToConstValueResult;
|
||||||
use rustc_middle::traits::select;
|
use rustc_middle::traits::select;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||||
|
@ -1499,9 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
pub fn const_eval_resolve(
|
pub fn const_eval_resolve(
|
||||||
&self,
|
&self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
def: ty::WithOptConstParam<DefId>,
|
ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
|
||||||
promoted: Option<mir::Promoted>,
|
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToConstValueResult<'tcx> {
|
) -> EvalToConstValueResult<'tcx> {
|
||||||
let mut original_values = OriginalQueryValues::default();
|
let mut original_values = OriginalQueryValues::default();
|
||||||
|
@ -1510,7 +1507,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let (param_env, substs) = canonical.value;
|
let (param_env, substs) = canonical.value;
|
||||||
// The return value is the evaluated value which doesn't contain any reference to inference
|
// The return value is the evaluated value which doesn't contain any reference to inference
|
||||||
// variables, thus we don't need to substitute back the original values.
|
// variables, thus we don't need to substitute back the original values.
|
||||||
self.tcx.const_eval_resolve(param_env, def, substs, promoted, span)
|
self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `typ` is a type variable of some kind, resolve it one level
|
/// If `typ` is a type variable of some kind, resolve it one level
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{ErrorHandled, EvalToConstValueResult, GlobalId};
|
use super::{ErrorHandled, EvalToConstValueResult, GlobalId};
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::ty::subst::{InternalSubsts, SubstsRef};
|
use crate::ty::subst::InternalSubsts;
|
||||||
use crate::ty::{self, TyCtxt};
|
use crate::ty::{self, TyCtxt};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -35,14 +35,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn const_eval_resolve(
|
pub fn const_eval_resolve(
|
||||||
self,
|
self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
def: ty::WithOptConstParam<DefId>,
|
ct: ty::Unevaluated<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
|
||||||
promoted: Option<mir::Promoted>,
|
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToConstValueResult<'tcx> {
|
) -> EvalToConstValueResult<'tcx> {
|
||||||
match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
|
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
||||||
Ok(Some(instance)) => {
|
Ok(Some(instance)) => {
|
||||||
let cid = GlobalId { instance, promoted };
|
let cid = GlobalId { instance, promoted: ct.promoted };
|
||||||
self.const_eval_global_id(param_env, cid, span)
|
self.const_eval_global_id(param_env, cid, span)
|
||||||
}
|
}
|
||||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||||
|
|
|
@ -140,7 +140,8 @@ impl<'tcx> ConstKind<'tcx> {
|
||||||
let (param_env, substs) = param_env_and_substs.into_parts();
|
let (param_env, substs) = param_env_and_substs.into_parts();
|
||||||
// try to resolve e.g. associated constants to their definition on an impl, and then
|
// try to resolve e.g. associated constants to their definition on an impl, and then
|
||||||
// evaluate the const.
|
// evaluate the const.
|
||||||
match tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
|
match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None)
|
||||||
|
{
|
||||||
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
||||||
// and we use the original type, so nothing from `substs`
|
// and we use the original type, so nothing from `substs`
|
||||||
// (which may be identity substs, see above),
|
// (which may be identity substs, see above),
|
||||||
|
|
|
@ -646,8 +646,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||||
|
|
||||||
match substituted_constant.val {
|
match substituted_constant.val {
|
||||||
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
|
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
|
||||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
ty::ConstKind::Unevaluated(unevaluated) => {
|
||||||
match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
|
match self.tcx.const_eval_resolve(param_env, unevaluated, None) {
|
||||||
Ok(val) => collect_const_value(self.tcx, val, self.output),
|
Ok(val) => collect_const_value(self.tcx, val, self.output),
|
||||||
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
|
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
|
||||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||||
|
|
|
@ -803,17 +803,10 @@ impl AutoTraitFinder<'tcx> {
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||||
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
||||||
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
|
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
|
||||||
def,
|
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
}) = c.val
|
|
||||||
{
|
|
||||||
match select.infcx().const_eval_resolve(
|
match select.infcx().const_eval_resolve(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
def,
|
unevaluated,
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
Some(obligation.cause.span),
|
Some(obligation.cause.span),
|
||||||
) {
|
) {
|
||||||
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
|
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
|
||||||
|
|
|
@ -163,7 +163,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
// and hopefully soon change this to an error.
|
// and hopefully soon change this to an error.
|
||||||
//
|
//
|
||||||
// See #74595 for more details about this.
|
// See #74595 for more details about this.
|
||||||
let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
|
let concrete = infcx.const_eval_resolve(
|
||||||
|
param_env,
|
||||||
|
ty::Unevaluated { def, substs, promoted: None },
|
||||||
|
Some(span),
|
||||||
|
);
|
||||||
|
|
||||||
if concrete.is_ok() && substs.has_param_types_or_consts() {
|
if concrete.is_ok() && substs.has_param_types_or_consts() {
|
||||||
match infcx.tcx.def_kind(def.did) {
|
match infcx.tcx.def_kind(def.did) {
|
||||||
|
|
|
@ -532,23 +532,17 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
let stalled_on = &mut pending_obligation.stalled_on;
|
let stalled_on = &mut pending_obligation.stalled_on;
|
||||||
|
|
||||||
let mut evaluate = |c: &'tcx Const<'tcx>| {
|
let mut evaluate = |c: &'tcx Const<'tcx>| {
|
||||||
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
|
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
|
||||||
def,
|
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
}) = c.val
|
|
||||||
{
|
|
||||||
match self.selcx.infcx().const_eval_resolve(
|
match self.selcx.infcx().const_eval_resolve(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
def,
|
unevaluated,
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
Some(obligation.cause.span),
|
Some(obligation.cause.span),
|
||||||
) {
|
) {
|
||||||
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
|
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
|
||||||
Err(ErrorHandled::TooGeneric) => {
|
Err(ErrorHandled::TooGeneric) => {
|
||||||
stalled_on.extend(
|
stalled_on.extend(
|
||||||
substs
|
unevaluated
|
||||||
|
.substs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
||||||
);
|
);
|
||||||
|
|
|
@ -556,18 +556,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
|
debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
|
||||||
|
|
||||||
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
||||||
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
|
if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
|
||||||
def,
|
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
}) = c.val
|
|
||||||
{
|
|
||||||
self.infcx
|
self.infcx
|
||||||
.const_eval_resolve(
|
.const_eval_resolve(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
def,
|
unevaluated,
|
||||||
substs,
|
|
||||||
promoted,
|
|
||||||
Some(obligation.cause.span),
|
Some(obligation.cause.span),
|
||||||
)
|
)
|
||||||
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty))
|
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty))
|
||||||
|
|
|
@ -296,7 +296,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
|
||||||
|
|
||||||
crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
|
crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
|
||||||
match n.val {
|
match n.val {
|
||||||
ty::ConstKind::Unevaluated(def, _, promoted) => {
|
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
|
||||||
let mut s = if let Some(def) = def.as_local() {
|
let mut s = if let Some(def) = def.as_local() {
|
||||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did);
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did);
|
||||||
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id))
|
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id))
|
||||||
|
|
|
@ -181,7 +181,15 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D
|
||||||
|
|
||||||
let result = cx
|
let result = cx
|
||||||
.tcx
|
.tcx
|
||||||
.const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None);
|
.const_eval_resolve(
|
||||||
|
cx.param_env,
|
||||||
|
ty::Unevaluated {
|
||||||
|
def: ty::WithOptConstParam::unknown(def_id),
|
||||||
|
substs,
|
||||||
|
promoted: None
|
||||||
|
},
|
||||||
|
None
|
||||||
|
);
|
||||||
is_value_unfrozen_raw(cx, result, ty)
|
is_value_unfrozen_raw(cx, result, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -341,9 +341,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
||||||
.tcx
|
.tcx
|
||||||
.const_eval_resolve(
|
.const_eval_resolve(
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::WithOptConstParam::unknown(def_id),
|
ty::Unevaluated {
|
||||||
|
def: ty::WithOptConstParam::unknown(def_id),
|
||||||
substs,
|
substs,
|
||||||
None,
|
promoted: None,
|
||||||
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue