rustc_middle/ty/
abstract_const.rs1use rustc_errors::ErrorGuaranteed;
4use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
5
6use crate::ty::{
7 self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
8 TypeVisitableExt,
9};
10
11#[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)]
12#[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)]
13pub enum CastKind {
14 As,
16 Use,
18}
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
21pub enum NotConstEvaluatable {
22 Error(ErrorGuaranteed),
23 MentionsInfer,
24 MentionsParam,
25}
26
27impl From<ErrorGuaranteed> for NotConstEvaluatable {
28 fn from(e: ErrorGuaranteed) -> NotConstEvaluatable {
29 NotConstEvaluatable::Error(e)
30 }
31}
32
33pub type BoundAbstractConst<'tcx> =
34 Result<Option<EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed>;
35
36impl<'tcx> TyCtxt<'tcx> {
37 pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
38 struct Expander<'tcx> {
39 tcx: TyCtxt<'tcx>,
40 }
41
42 impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Expander<'tcx> {
43 fn cx(&self) -> TyCtxt<'tcx> {
44 self.tcx
45 }
46 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
47 if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
48 ty.super_fold_with(self)
49 } else {
50 ty
51 }
52 }
53 fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
54 let ct = match c.kind() {
55 ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
56 Err(e) => ty::Const::new_error(self.tcx, e),
57 Ok(Some(bac)) => {
58 let args = self.tcx.erase_regions(uv.args);
59 let bac = bac.instantiate(self.tcx, args);
60 return bac.fold_with(self);
61 }
62 Ok(None) => c,
63 },
64 _ => c,
65 };
66 ct.super_fold_with(self)
67 }
68 }
69 ac.fold_with(&mut Expander { tcx: self })
70 }
71}