diff options
| author | Boxy <rust@boxyuwu.dev> | 2024-11-12 02:54:03 +0000 |
|---|---|---|
| committer | Boxy <rust@boxyuwu.dev> | 2024-11-12 02:54:03 +0000 |
| commit | bea0148ac62758a99dcc2ac2cc2efedacb8881bf (patch) | |
| tree | 1e3cf15272da0fb53f45fc9521b626509467af14 /compiler/rustc_middle/src/ty | |
| parent | 81eef2d362a6f03db6f8928f82d94298d31eb81b (diff) | |
| download | rust-bea0148ac62758a99dcc2ac2cc2efedacb8881bf.tar.gz rust-bea0148ac62758a99dcc2ac2cc2efedacb8881bf.zip | |
Consolidate type system const evaluation under `traits::evaluate_const`
mew
Diffstat (limited to 'compiler/rustc_middle/src/ty')
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/kind.rs | 36 |
2 files changed, 3 insertions, 92 deletions
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 5ab85a69ce6..5689f3d4265 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,4 +1,3 @@ -use either::Either; use rustc_data_structures::intern::Interned; use rustc_error_messages::MultiSpan; use rustc_hir::def::{DefKind, Res}; @@ -9,7 +8,7 @@ use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; use tracing::{debug, instrument}; use crate::middle::resolve_bound_vars as rbv; -use crate::mir::interpret::{ErrorHandled, LitToConstInput, Scalar}; +use crate::mir::interpret::{LitToConstInput, Scalar}; use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; mod int; @@ -18,7 +17,7 @@ mod valtree; pub use int::*; pub use kind::*; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed}; pub use valtree::*; pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>; @@ -363,60 +362,6 @@ impl<'tcx> Const<'tcx> { Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize)) } - /// Returns the evaluated constant as a valtree; - /// if that fails due to a valtree-incompatible type, indicate which type that is - /// by returning `Err(Left(bad_type))`. - #[inline] - pub fn eval_valtree( - self, - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - span: Span, - ) -> Result<(Ty<'tcx>, ValTree<'tcx>), Either<Ty<'tcx>, ErrorHandled>> { - assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}"); - match self.kind() { - ConstKind::Unevaluated(unevaluated) => { - // FIXME(eddyb) maybe the `const_eval_*` methods should take - // `ty::ParamEnvAnd` instead of having them separate. - let (param_env, unevaluated) = unevaluated.prepare_for_eval(tcx, param_env); - // try to resolve e.g. associated constants to their definition on an impl, and then - // evaluate the const. - match tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span) { - Ok(Ok(c)) => { - Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c)) - } - Ok(Err(bad_ty)) => Err(Either::Left(bad_ty)), - Err(err) => Err(Either::Right(err)), - } - } - ConstKind::Value(ty, val) => Ok((ty, val)), - ConstKind::Error(g) => Err(Either::Right(g.into())), - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(_, _) - | ConstKind::Placeholder(_) - | ConstKind::Expr(_) => Err(Either::Right(ErrorHandled::TooGeneric(span))), - } - } - - /// Normalizes the constant to a value or an error if possible. - #[inline] - pub fn normalize_internal(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { - match self.eval_valtree(tcx, param_env, DUMMY_SP) { - Ok((ty, val)) => Self::new_value(tcx, val, ty), - Err(Either::Left(_bad_ty)) => { - // This can happen when we run on ill-typed code. - Self::new_error( - tcx, - tcx.dcx() - .delayed_bug("`ty::Const::eval` called on a non-valtree-compatible type"), - ) - } - Err(Either::Right(ErrorHandled::Reported(r, _span))) => Self::new_error(tcx, r.into()), - Err(Either::Right(ErrorHandled::TooGeneric(_span))) => self, - } - } - /// Panics if self.kind != ty::ConstKind::Value pub fn to_valtree(self) -> (ty::ValTree<'tcx>, Ty<'tcx>) { match self.kind() { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 91b764ae1d4..b3436550e8e 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,46 +1,12 @@ use std::assert_matches::assert_matches; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use super::Const; use crate::mir; use crate::ty::abstract_const::CastKind; -use crate::ty::visit::TypeVisitableExt as _; use crate::ty::{self, Ty, TyCtxt}; -#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)] -impl<'tcx> ty::UnevaluatedConst<'tcx> { - /// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this - /// hurts performance. - #[inline] - fn prepare_for_eval( - self, - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> (ty::ParamEnv<'tcx>, Self) { - // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` - // also does later, but we want to do it before checking for - // inference variables. - // Note that we erase regions *before* calling `with_reveal_all_normalized`, - // so that we don't try to invoke this query with - // any region variables. - - // HACK(eddyb) when the query key would contain inference variables, - // attempt using identity args and `ParamEnv` instead, that will succeed - // when the expression doesn't depend on any parameters. - // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that - // we can call `infcx.const_eval_resolve` which handles inference variables. - if (param_env, self).has_non_region_infer() { - (tcx.param_env(self.def), ty::UnevaluatedConst { - def: self.def, - args: ty::GenericArgs::identity_for_item(tcx, self.def), - }) - } else { - (tcx.erase_regions(param_env).with_reveal_all_normalized(tcx), tcx.erase_regions(self)) - } - } -} - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum ExprKind { |
