charon_lib/ast/
gast_utils.rs1use crate::ast::*;
4
5impl FnPtrKind {
6 pub fn mk_builtin(aid: BuiltinFunId) -> Self {
7 Self::Fun(FunId::Builtin(aid))
8 }
9}
10
11impl Body {
12 pub fn has_contents(&self) -> bool {
15 match self {
16 Body::Unstructured(..) | Body::Structured(..) => true,
17 Body::TraitMethodWithoutDefault | Body::Opaque | Body::Missing | Body::Error(..) => {
18 false
19 }
20 }
21 }
22
23 pub fn locals(&self) -> &Locals {
24 match self {
25 Body::Structured(body) => &body.locals,
26 Body::Unstructured(body) => &body.locals,
27 _ => panic!("called `locals` on a missing body"),
28 }
29 }
30}
31
32impl Locals {
33 pub fn new(arg_count: usize) -> Self {
34 Self {
35 arg_count,
36 locals: Default::default(),
37 }
38 }
39
40 pub fn new_var(&mut self, name: Option<String>, ty: Ty) -> Place {
43 let local_id = self.locals.push_with(|index| Local {
44 index,
45 name,
46 ty: ty.clone(),
47 });
48 Place::new(local_id, ty)
49 }
50
51 pub fn place_for_var(&self, local_id: LocalId) -> Place {
53 let ty = self.locals[local_id].ty.clone();
54 Place::new(local_id, ty)
55 }
56
57 pub fn is_return_or_arg(&self, lid: LocalId) -> bool {
59 lid.index() <= self.arg_count
60 }
61
62 pub fn return_place(&self) -> Place {
64 self.place_for_var(LocalId::new(0))
65 }
66
67 pub fn non_argument_locals(&self) -> impl Iterator<Item = (LocalId, &Local)> {
69 self.locals.iter_indexed().skip(1 + self.arg_count)
70 }
71}
72
73impl std::ops::Index<LocalId> for Locals {
74 type Output = Local;
75 fn index(&self, local_id: LocalId) -> &Self::Output {
76 &self.locals[local_id]
77 }
78}
79impl std::ops::IndexMut<LocalId> for Locals {
80 fn index_mut(&mut self, local_id: LocalId) -> &mut Self::Output {
81 &mut self.locals[local_id]
82 }
83}
84
85impl FunDecl {
86 pub fn substitute_params(self, subst: Binder<GenericArgs>) -> Self {
88 let FunDecl {
89 def_id,
90 item_meta,
91 signature,
92 src: kind,
93 is_global_initializer,
94 body,
95 } = self;
96 let signature = FunSig {
97 generics: subst.params,
98 inputs: signature.inputs.substitute(&subst.skip_binder),
99 output: signature.output.substitute(&subst.skip_binder),
100 ..signature
101 };
102 let src = kind.substitute(&subst.skip_binder);
103 let body = body.substitute(&subst.skip_binder);
104 FunDecl {
105 def_id,
106 item_meta,
107 signature,
108 src,
109 is_global_initializer,
110 body,
111 }
112 }
113}
114impl TraitDecl {
115 pub fn methods(&self) -> impl Iterator<Item = &Binder<TraitMethod>> {
116 self.methods.iter()
117 }
118}
119impl TraitImpl {
120 pub fn methods(&self) -> impl Iterator<Item = &(TraitItemName, Binder<FunDeclRef>)> {
121 self.methods.iter()
122 }
123}
124
125impl Binder<TraitAssocTy> {
126 pub fn name(&self) -> &TraitItemName {
127 &self.skip_binder.name
128 }
129}
130impl Binder<TraitMethod> {
131 pub fn name(&self) -> TraitItemName {
132 self.skip_binder.name
133 }
134}