1use crate::ast::*;
2use derive_generic_visitor::{ControlFlow, Drive, DriveMut, DriveTwo};
3use macros::{EnumAsGetters, EnumIsA, VariantIndexArity, VariantName};
4
5pub mod fun_decl;
6pub mod global_decl;
7pub mod item_ids;
8pub mod layout;
9pub mod trait_decl;
10pub mod trait_impl;
11pub mod type_decl;
12
13pub use fun_decl::*;
14pub use global_decl::*;
15pub use item_ids::*;
16pub use layout::*;
17pub use trait_decl::*;
18pub use trait_impl::*;
19pub use type_decl::*;
20
21#[derive(
23 Debug,
24 PartialEq,
25 Eq,
26 EnumIsA,
27 EnumAsGetters,
28 VariantName,
29 VariantIndexArity,
30 Drive,
31 DriveMut,
32 DriveTwo,
33)]
34pub enum ItemByVal {
35 Type(TypeDecl),
36 Fun(FunDecl),
37 Global(GlobalDecl),
38 TraitDecl(TraitDecl),
39 TraitImpl(TraitImpl),
40}
41
42#[derive(
44 Debug,
45 Clone,
46 Copy,
47 EnumIsA,
48 EnumAsGetters,
49 VariantName,
50 VariantIndexArity,
51 Drive,
52 DriveMut,
53 DriveTwo,
54)]
55pub enum ItemRef<'ctx> {
56 Type(&'ctx TypeDecl),
57 Fun(&'ctx FunDecl),
58 Global(&'ctx GlobalDecl),
59 TraitDecl(&'ctx TraitDecl),
60 TraitImpl(&'ctx TraitImpl),
61}
62
63#[derive(
65 Debug,
66 PartialEq,
67 Eq,
68 EnumIsA,
69 EnumAsGetters,
70 VariantName,
71 VariantIndexArity,
72 Drive,
73 DriveMut,
74 DriveTwo,
75)]
76pub enum ItemRefMut<'ctx> {
77 Type(&'ctx mut TypeDecl),
78 Fun(&'ctx mut FunDecl),
79 Global(&'ctx mut GlobalDecl),
80 TraitDecl(&'ctx mut TraitDecl),
81 TraitImpl(&'ctx mut TraitImpl),
82}
83
84impl ItemByVal {
85 pub fn as_ref(&self) -> ItemRef<'_> {
86 match self {
87 Self::Type(d) => ItemRef::Type(d),
88 Self::Fun(d) => ItemRef::Fun(d),
89 Self::Global(d) => ItemRef::Global(d),
90 Self::TraitDecl(d) => ItemRef::TraitDecl(d),
91 Self::TraitImpl(d) => ItemRef::TraitImpl(d),
92 }
93 }
94 pub fn as_mut(&mut self) -> ItemRefMut<'_> {
95 match self {
96 Self::Type(d) => ItemRefMut::Type(d),
97 Self::Fun(d) => ItemRefMut::Fun(d),
98 Self::Global(d) => ItemRefMut::Global(d),
99 Self::TraitDecl(d) => ItemRefMut::TraitDecl(d),
100 Self::TraitImpl(d) => ItemRefMut::TraitImpl(d),
101 }
102 }
103}
104
105impl<'ctx> ItemRef<'ctx> {
106 pub fn id(&self) -> ItemId {
107 match self {
108 ItemRef::Type(d) => d.def_id.into(),
109 ItemRef::Fun(d) => d.def_id.into(),
110 ItemRef::Global(d) => d.def_id.into(),
111 ItemRef::TraitDecl(d) => d.def_id.into(),
112 ItemRef::TraitImpl(d) => d.def_id.into(),
113 }
114 }
115
116 pub fn to_owned(&self) -> ItemByVal {
117 match *self {
118 Self::Type(d) => ItemByVal::Type(d.clone()),
119 Self::Fun(d) => ItemByVal::Fun(d.clone()),
120 Self::Global(d) => ItemByVal::Global(d.clone()),
121 Self::TraitDecl(d) => ItemByVal::TraitDecl(d.clone()),
122 Self::TraitImpl(d) => ItemByVal::TraitImpl(d.clone()),
123 }
124 }
125
126 pub fn item_meta(&self) -> &'ctx ItemMeta {
127 match self {
128 Self::Type(d) => &d.item_meta,
129 Self::Fun(d) => &d.item_meta,
130 Self::Global(d) => &d.item_meta,
131 Self::TraitDecl(d) => &d.item_meta,
132 Self::TraitImpl(d) => &d.item_meta,
133 }
134 }
135 pub fn generic_params(&self) -> &'ctx GenericParams {
137 match self {
138 ItemRef::Type(d) => &d.generics,
139 ItemRef::Fun(d) => &d.generics,
140 ItemRef::Global(d) => &d.generics,
141 ItemRef::TraitDecl(d) => &d.generics,
142 ItemRef::TraitImpl(d) => &d.generics,
143 }
144 }
145
146 pub fn identity_args(&self) -> GenericArgs {
148 self.generic_params().identity_args()
149 }
150
151 pub fn drive<V: VisitAst>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
154 match *self {
155 ItemRef::Type(d) => visitor.visit(d),
156 ItemRef::Fun(d) => visitor.visit(d),
157 ItemRef::Global(d) => visitor.visit(d),
158 ItemRef::TraitDecl(d) => visitor.visit(d),
159 ItemRef::TraitImpl(d) => visitor.visit(d),
160 }
161 }
162
163 pub fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T)) {
165 match *self {
166 ItemRef::Type(d) => d.dyn_visit(f),
167 ItemRef::Fun(d) => d.dyn_visit(f),
168 ItemRef::Global(d) => d.dyn_visit(f),
169 ItemRef::TraitDecl(d) => d.dyn_visit(f),
170 ItemRef::TraitImpl(d) => d.dyn_visit(f),
171 }
172 }
173}
174
175impl<'ctx> ItemRefMut<'ctx> {
176 pub fn as_ref(&self) -> ItemRef<'_> {
177 match self {
178 ItemRefMut::Type(d) => ItemRef::Type(d),
179 ItemRefMut::Fun(d) => ItemRef::Fun(d),
180 ItemRefMut::Global(d) => ItemRef::Global(d),
181 ItemRefMut::TraitDecl(d) => ItemRef::TraitDecl(d),
182 ItemRefMut::TraitImpl(d) => ItemRef::TraitImpl(d),
183 }
184 }
185 pub fn reborrow(&mut self) -> ItemRefMut<'_> {
186 match self {
187 ItemRefMut::Type(d) => ItemRefMut::Type(d),
188 ItemRefMut::Fun(d) => ItemRefMut::Fun(d),
189 ItemRefMut::Global(d) => ItemRefMut::Global(d),
190 ItemRefMut::TraitDecl(d) => ItemRefMut::TraitDecl(d),
191 ItemRefMut::TraitImpl(d) => ItemRefMut::TraitImpl(d),
192 }
193 }
194
195 pub fn set_id(&mut self, id: ItemId) {
196 match (self, id) {
197 (Self::Type(d), ItemId::Type(id)) => d.def_id = id,
198 (Self::Fun(d), ItemId::Fun(id)) => d.def_id = id,
199 (Self::Global(d), ItemId::Global(id)) => d.def_id = id,
200 (Self::TraitDecl(d), ItemId::TraitDecl(id)) => d.def_id = id,
201 (Self::TraitImpl(d), ItemId::TraitImpl(id)) => d.def_id = id,
202 _ => unreachable!(),
203 }
204 }
205
206 pub fn item_meta(&mut self) -> &mut ItemMeta {
207 match self {
208 Self::Type(d) => &mut d.item_meta,
209 Self::Fun(d) => &mut d.item_meta,
210 Self::Global(d) => &mut d.item_meta,
211 Self::TraitDecl(d) => &mut d.item_meta,
212 Self::TraitImpl(d) => &mut d.item_meta,
213 }
214 }
215 pub fn generic_params(&mut self) -> &mut GenericParams {
217 match self {
218 ItemRefMut::Type(d) => &mut d.generics,
219 ItemRefMut::Fun(d) => &mut d.generics,
220 ItemRefMut::Global(d) => &mut d.generics,
221 ItemRefMut::TraitDecl(d) => &mut d.generics,
222 ItemRefMut::TraitImpl(d) => &mut d.generics,
223 }
224 }
225
226 pub fn drive_mut<V: VisitAstMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
229 match self {
230 ItemRefMut::Type(d) => visitor.visit(*d),
231 ItemRefMut::Fun(d) => visitor.visit(*d),
232 ItemRefMut::Global(d) => visitor.visit(*d),
233 ItemRefMut::TraitDecl(d) => visitor.visit(*d),
234 ItemRefMut::TraitImpl(d) => visitor.visit(*d),
235 }
236 }
237
238 pub fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T)) {
240 match self {
241 ItemRefMut::Type(d) => d.dyn_visit_mut(f),
242 ItemRefMut::Fun(d) => d.dyn_visit_mut(f),
243 ItemRefMut::Global(d) => d.dyn_visit_mut(f),
244 ItemRefMut::TraitDecl(d) => d.dyn_visit_mut(f),
245 ItemRefMut::TraitImpl(d) => d.dyn_visit_mut(f),
246 }
247 }
248}