flux_rustc_bridge/ty/
subst.rs1use 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::Bool
56 | TyKind::Uint(_)
57 | TyKind::Str
58 | TyKind::Char
59 | TyKind::Float(_)
60 | TyKind::Int(_)
61 | TyKind::Never => self.clone(),
62 }
63 }
64}
65
66impl Subst for TraitRef {
67 fn subst(&self, args: &[GenericArg]) -> Self {
68 let def_id = self.def_id;
69 TraitRef { def_id, args: self.args.subst(args) }
70 }
71}
72
73impl Subst for ExistentialTraitRef {
74 fn subst(&self, args: &[GenericArg]) -> Self {
75 ExistentialTraitRef { def_id: self.def_id, args: self.args.subst(args) }
76 }
77}
78
79impl Subst for ExistentialProjection {
80 fn subst(&self, args: &[GenericArg]) -> Self {
81 ExistentialProjection {
82 def_id: self.def_id,
83 args: self.args.subst(args),
84 term: self.term.subst(args),
85 }
86 }
87}
88
89impl Subst for ExistentialPredicate {
90 fn subst(&self, args: &[GenericArg]) -> Self {
91 match self {
92 ExistentialPredicate::Trait(exi_trait_ref) => {
93 ExistentialPredicate::Trait(exi_trait_ref.subst(args))
94 }
95 ExistentialPredicate::Projection(exi_proj_pred) => {
96 ExistentialPredicate::Projection(exi_proj_pred.subst(args))
97 }
98 ExistentialPredicate::AutoTrait(def_id) => ExistentialPredicate::AutoTrait(*def_id),
99 }
100 }
101}
102
103impl Subst for GenericArg {
104 fn subst(&self, args: &[GenericArg]) -> Self {
105 match self {
106 GenericArg::Ty(ty) => GenericArg::Ty(ty.subst(args)),
107 GenericArg::Lifetime(re) => GenericArg::Lifetime(re.subst(args)),
108 GenericArg::Const(c) => GenericArg::Const(c.subst(args)),
109 }
110 }
111}
112
113impl Subst for Const {
114 fn subst(&self, args: &[GenericArg]) -> Self {
115 if let ConstKind::Param(param_const) = &self.kind {
116 args[param_const.index as usize].expect_const().clone()
117 } else {
118 self.clone()
119 }
120 }
121}
122
123impl Subst for Region {
124 fn subst(&self, args: &[GenericArg]) -> Self {
125 match self {
126 Region::ReEarlyParam(ebr) => args[ebr.index as usize].expect_lifetime(),
127 Region::ReLateParam(..)
128 | Region::ReBound(_, _)
129 | Region::ReStatic
130 | Region::ReErased
131 | Region::ReVar(_) => *self,
132 }
133 }
134}
135
136impl<T> Subst for List<T>
137where
138 T: Subst,
139 [T]: Internable,
140{
141 fn subst(&self, args: &[GenericArg]) -> Self {
142 self.iter().map(|t| t.subst(args)).collect()
143 }
144}