| //! A subset of a mir body used for const evaluability checking. | |
| use rustc_errors::ErrorGuaranteed; | |
| use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeVisitable}; | |
| use crate::ty::{ | |
| self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, | |
| TypeVisitableExt, | |
| }; | |
| #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)] | |
| #[derive(TyDecodable, TyEncodable, StableHash, TypeVisitable, TypeFoldable)] | |
| pub enum CastKind { | |
| /// thir::ExprKind::As | |
| As, | |
| /// thir::ExprKind::Use | |
| Use, | |
| } | |
| #[derive(Debug, Copy, Clone, PartialEq, Eq, StableHash, TyEncodable, TyDecodable)] | |
| pub enum NotConstEvaluatable { | |
| Error(ErrorGuaranteed), | |
| MentionsInfer, | |
| MentionsParam, | |
| } | |
| impl From<ErrorGuaranteed> for NotConstEvaluatable { | |
| fn from(e: ErrorGuaranteed) -> NotConstEvaluatable { | |
| NotConstEvaluatable::Error(e) | |
| } | |
| } | |
| pub type BoundAbstractConst<'tcx> = | |
| Result<Option<EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed>; | |
| impl<'tcx> TyCtxt<'tcx> { | |
| pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T { | |
| struct Expander<'tcx> { | |
| tcx: TyCtxt<'tcx>, | |
| } | |
| impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Expander<'tcx> { | |
| fn cx(&self) -> TyCtxt<'tcx> { | |
| self.tcx | |
| } | |
| fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { | |
| if ty.has_type_flags(ty::TypeFlags::HAS_CONST_ALIAS) { | |
| ty.super_fold_with(self) | |
| } else { | |
| ty | |
| } | |
| } | |
| fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { | |
| let ct = match c.kind() { | |
| ty::ConstKind::Alias(_, alias_const) | |
| if let Some(def_id) = alias_const.kind.opt_def_id() => | |
| { | |
| match self.tcx.thir_abstract_const(def_id) { | |
| Err(e) => ty::Const::new_error(self.tcx, e), | |
| Ok(Some(bac)) => { | |
| let args = self.tcx.erase_and_anonymize_regions(alias_const.args); | |
| let bac = bac.instantiate(self.tcx, args).skip_norm_wip(); | |
| return bac.fold_with(self); | |
| } | |
| Ok(None) => c, | |
| } | |
| } | |
| _ => c, | |
| }; | |
| ct.super_fold_with(self) | |
| } | |
| } | |
| ac.fold_with(&mut Expander { tcx: self }) | |
| } | |
| } |