|  | //! A subset of a mir body used for const evaluability checking. | 
|  |  | 
|  | use rustc_errors::ErrorGuaranteed; | 
|  | use rustc_macros::{HashStable, 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, HashStable, TypeVisitable, TypeFoldable)] | 
|  | pub enum CastKind { | 
|  | /// thir::ExprKind::As | 
|  | As, | 
|  | /// thir::ExprKind::Use | 
|  | Use, | 
|  | } | 
|  |  | 
|  | #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, 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_CT_PROJECTION) { | 
|  | ty.super_fold_with(self) | 
|  | } else { | 
|  | ty | 
|  | } | 
|  | } | 
|  | fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { | 
|  | let ct = match c.kind() { | 
|  | ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) { | 
|  | Err(e) => ty::Const::new_error(self.tcx, e), | 
|  | Ok(Some(bac)) => { | 
|  | let args = self.tcx.erase_and_anonymize_regions(uv.args); | 
|  | let bac = bac.instantiate(self.tcx, args); | 
|  | return bac.fold_with(self); | 
|  | } | 
|  | Ok(None) => c, | 
|  | }, | 
|  | _ => c, | 
|  | }; | 
|  | ct.super_fold_with(self) | 
|  | } | 
|  | } | 
|  | ac.fold_with(&mut Expander { tcx: self }) | 
|  | } | 
|  | } |