1 //! A subset of a mir body used for const evaluatability checking.
3 self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
6 use rustc_errors::ErrorGuaranteed;
7 use rustc_hir::def_id::DefId;
9 #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)]
10 #[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)]
12 /// thir::ExprKind::As
14 /// thir::ExprKind::Use
18 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
19 pub enum NotConstEvaluatable {
20 Error(ErrorGuaranteed),
25 impl From<ErrorGuaranteed> for NotConstEvaluatable {
26 fn from(e: ErrorGuaranteed) -> NotConstEvaluatable {
27 NotConstEvaluatable::Error(e)
31 TrivialTypeTraversalAndLiftImpls! {
35 pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;
37 impl<'tcx> TyCtxt<'tcx> {
38 /// Returns a const without substs applied
39 pub fn bound_abstract_const(
41 uv: ty::WithOptConstParam<DefId>,
42 ) -> BoundAbstractConst<'tcx> {
43 let ac = if let Some((did, param_did)) = uv.as_const_arg() {
44 self.thir_abstract_const_of_const_arg((did, param_did))
46 self.thir_abstract_const(uv.did)
48 Ok(ac?.map(|ac| EarlyBinder(ac)))
51 pub fn expand_abstract_consts<T: TypeFoldable<'tcx>>(self, ac: T) -> T {
52 struct Expander<'tcx> {
56 impl<'tcx> TypeFolder<'tcx> for Expander<'tcx> {
57 fn tcx(&self) -> TyCtxt<'tcx> {
60 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
61 if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
62 ty.super_fold_with(self)
67 fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
68 let ct = match c.kind() {
69 ty::ConstKind::Unevaluated(uv) => match self.tcx.bound_abstract_const(uv.def) {
70 Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e),
72 let substs = self.tcx.erase_regions(uv.substs);
73 bac.subst(self.tcx, substs)
79 ct.super_fold_with(self)
82 ac.fold_with(&mut Expander { tcx: self })