flux_rustc_bridge/ty/
subst.rs

1use flux_arc_interner::{Internable, List};
2
3use super::{
4    Binder, Const, ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef,
5    FnSig, GenericArg, Region, Ty, TyKind,
6};
7use crate::ty::TraitRef;
8
9pub(super) trait Subst {
10    fn subst(&self, args: &[GenericArg]) -> Self;
11}
12
13impl<T> Subst for Binder<T>
14where
15    T: Subst,
16{
17    fn subst(&self, args: &[GenericArg]) -> Self {
18        Binder(self.0.subst(args), self.1.clone())
19    }
20}
21
22impl Subst for FnSig {
23    fn subst(&self, args: &[GenericArg]) -> Self {
24        FnSig {
25            safety: self.safety,
26            abi: self.abi,
27            inputs_and_output: self.inputs_and_output.subst(args),
28        }
29    }
30}
31
32impl Subst for Ty {
33    fn subst(&self, args: &[GenericArg]) -> Ty {
34        match self.kind() {
35            TyKind::Adt(adt_def, args2) => Ty::mk_adt(adt_def.clone(), args2.subst(args)),
36            TyKind::FnDef(def_id, args2) => Ty::mk_fn_def(*def_id, args2.subst(args)),
37            TyKind::Array(ty, len) => Ty::mk_array(ty.subst(args), len.clone()),
38            TyKind::Ref(re, ty, mutbl) => Ty::mk_ref(*re, ty.subst(args), *mutbl),
39            TyKind::Tuple(tys) => Ty::mk_tuple(tys.subst(args)),
40            TyKind::Slice(ty) => Ty::mk_slice(ty.subst(args)),
41            TyKind::Closure(def_id, args2) => Ty::mk_closure(*def_id, args2.subst(args)),
42            TyKind::Coroutine(def_id, args2) => Ty::mk_coroutine(*def_id, args2.subst(args)),
43            TyKind::CoroutineWitness(def_id, args2) => {
44                Ty::mk_generator_witness(*def_id, args2.subst(args))
45            }
46            TyKind::Alias(kind, alias_ty) => {
47                let def_id = alias_ty.def_id;
48                Ty::mk_alias(*kind, def_id, alias_ty.args.subst(args))
49            }
50            TyKind::RawPtr(ty, mutbl) => Ty::mk_raw_ptr(ty.subst(args), *mutbl),
51            TyKind::Param(param_ty) => args[param_ty.index as usize].expect_type().clone(),
52            TyKind::FnPtr(fn_sig) => Ty::mk_fn_ptr(fn_sig.subst(args)),
53            TyKind::Dynamic(exi_preds, re) => Ty::mk_dynamic(exi_preds.subst(args), *re),
54            TyKind::Foreign(def_id) => Ty::mk_foreign(*def_id),
55            TyKind::Pat => todo!(),
56            TyKind::Bool
57            | TyKind::Uint(_)
58            | TyKind::Str
59            | TyKind::Char
60            | TyKind::Float(_)
61            | TyKind::Int(_)
62            | TyKind::Never => self.clone(),
63        }
64    }
65}
66
67impl Subst for TraitRef {
68    fn subst(&self, args: &[GenericArg]) -> Self {
69        let def_id = self.def_id;
70        TraitRef { def_id, args: self.args.subst(args) }
71    }
72}
73
74impl Subst for ExistentialTraitRef {
75    fn subst(&self, args: &[GenericArg]) -> Self {
76        ExistentialTraitRef { def_id: self.def_id, args: self.args.subst(args) }
77    }
78}
79
80impl Subst for ExistentialProjection {
81    fn subst(&self, args: &[GenericArg]) -> Self {
82        ExistentialProjection {
83            def_id: self.def_id,
84            args: self.args.subst(args),
85            term: self.term.subst(args),
86        }
87    }
88}
89
90impl Subst for ExistentialPredicate {
91    fn subst(&self, args: &[GenericArg]) -> Self {
92        match self {
93            ExistentialPredicate::Trait(exi_trait_ref) => {
94                ExistentialPredicate::Trait(exi_trait_ref.subst(args))
95            }
96            ExistentialPredicate::Projection(exi_proj_pred) => {
97                ExistentialPredicate::Projection(exi_proj_pred.subst(args))
98            }
99            ExistentialPredicate::AutoTrait(def_id) => ExistentialPredicate::AutoTrait(*def_id),
100        }
101    }
102}
103
104impl Subst for GenericArg {
105    fn subst(&self, args: &[GenericArg]) -> Self {
106        match self {
107            GenericArg::Ty(ty) => GenericArg::Ty(ty.subst(args)),
108            GenericArg::Lifetime(re) => GenericArg::Lifetime(re.subst(args)),
109            GenericArg::Const(c) => GenericArg::Const(c.subst(args)),
110        }
111    }
112}
113
114impl Subst for Const {
115    fn subst(&self, args: &[GenericArg]) -> Self {
116        if let ConstKind::Param(param_const) = &self.kind {
117            args[param_const.index as usize].expect_const().clone()
118        } else {
119            self.clone()
120        }
121    }
122}
123
124impl Subst for Region {
125    fn subst(&self, args: &[GenericArg]) -> Self {
126        match self {
127            Region::ReEarlyParam(ebr) => args[ebr.index as usize].expect_lifetime(),
128            Region::ReLateParam(..)
129            | Region::ReBound(_, _)
130            | Region::ReStatic
131            | Region::ReErased
132            | Region::ReVar(_) => *self,
133        }
134    }
135}
136
137impl<T> Subst for List<T>
138where
139    T: Subst,
140    [T]: Internable,
141{
142    fn subst(&self, args: &[GenericArg]) -> Self {
143        self.iter().map(|t| t.subst(args)).collect()
144    }
145}