1use std::mem::size_of_val;
4
5use crate::ast::*;
6use cl_structures::{intern::interned::Interned, span::Span};
7
8pub trait WeightOf {
10 fn weight_of(&self) -> usize;
12}
13
14impl WeightOf for File {
15 fn weight_of(&self) -> usize {
16 let Self { name, items } = self;
17 name.weight_of() + items.weight_of()
18 }
19}
20
21impl WeightOf for Attrs {
22 fn weight_of(&self) -> usize {
23 let Self { meta } = self;
24 meta.weight_of()
25 }
26}
27
28impl WeightOf for Meta {
29 fn weight_of(&self) -> usize {
30 let Self { name, kind } = self;
31 name.weight_of() + kind.weight_of()
32 }
33}
34
35impl WeightOf for MetaKind {
36 fn weight_of(&self) -> usize {
37 match self {
38 MetaKind::Plain => size_of_val(self),
39 MetaKind::Equals(v) => v.weight_of(),
40 MetaKind::Func(v) => v.weight_of(),
41 }
42 }
43}
44
45impl WeightOf for Item {
46 fn weight_of(&self) -> usize {
47 let Self { span, attrs, vis, kind } = self;
48 span.weight_of() + attrs.weight_of() + vis.weight_of() + kind.weight_of()
49 }
50}
51
52impl WeightOf for ItemKind {
53 fn weight_of(&self) -> usize {
54 match self {
55 ItemKind::Module(v) => v.weight_of(),
56 ItemKind::Alias(v) => v.weight_of(),
57 ItemKind::Enum(v) => v.weight_of(),
58 ItemKind::Struct(v) => v.weight_of(),
59 ItemKind::Const(v) => v.weight_of(),
60 ItemKind::Static(v) => v.weight_of(),
61 ItemKind::Function(v) => v.weight_of(),
62 ItemKind::Impl(v) => v.weight_of(),
63 ItemKind::Use(v) => v.weight_of(),
64 }
65 }
66}
67
68impl WeightOf for Generics {
69 fn weight_of(&self) -> usize {
70 let Self { vars } = self;
71 vars.iter().map(|v| v.weight_of()).sum()
72 }
73}
74
75impl WeightOf for Module {
76 fn weight_of(&self) -> usize {
77 let Self { name, file } = self;
78 name.weight_of() + file.weight_of()
79 }
80}
81
82impl WeightOf for Alias {
83 fn weight_of(&self) -> usize {
84 let Self { name, from } = self;
85 name.weight_of() + from.weight_of()
86 }
87}
88
89impl WeightOf for Const {
90 fn weight_of(&self) -> usize {
91 let Self { name, ty, init } = self;
92 name.weight_of() + ty.weight_of() + init.weight_of()
93 }
94}
95
96impl WeightOf for Static {
97 fn weight_of(&self) -> usize {
98 let Self { mutable, name, ty, init } = self;
99 mutable.weight_of() + name.weight_of() + ty.weight_of() + init.weight_of()
100 }
101}
102
103impl WeightOf for Function {
104 fn weight_of(&self) -> usize {
105 let Self { name, gens, sign, bind, body } = self;
106 name.weight_of() + gens.weight_of() + sign.weight_of() + bind.weight_of() + body.weight_of()
107 }
108}
109
110impl WeightOf for Struct {
111 fn weight_of(&self) -> usize {
112 let Self { name, gens, kind } = self;
113 name.weight_of() + gens.weight_of() + kind.weight_of()
114 }
115}
116
117impl WeightOf for StructKind {
118 fn weight_of(&self) -> usize {
119 match self {
120 StructKind::Empty => size_of_val(self),
121 StructKind::Tuple(items) => items.weight_of(),
122 StructKind::Struct(sm) => sm.weight_of(),
123 }
124 }
125}
126
127impl WeightOf for StructMember {
128 fn weight_of(&self) -> usize {
129 let Self { vis, name, ty } = self;
130 vis.weight_of() + name.weight_of() + ty.weight_of()
131 }
132}
133
134impl WeightOf for Enum {
135 fn weight_of(&self) -> usize {
136 let Self { name, gens, variants } = self;
137 name.weight_of() + gens.weight_of() + variants.weight_of()
138 }
139}
140
141impl WeightOf for Variant {
142 fn weight_of(&self) -> usize {
143 let Self { name, kind, body } = self;
144 name.weight_of() + kind.weight_of() + body.weight_of()
145 }
146}
147
148impl WeightOf for Impl {
149 fn weight_of(&self) -> usize {
150 let Self { target, body } = self;
151 target.weight_of() + body.weight_of()
152 }
153}
154
155impl WeightOf for ImplKind {
156 fn weight_of(&self) -> usize {
157 match self {
158 ImplKind::Type(ty) => ty.weight_of(),
159 ImplKind::Trait { impl_trait, for_type } => {
160 impl_trait.weight_of() + for_type.weight_of()
161 }
162 }
163 }
164}
165
166impl WeightOf for Use {
167 fn weight_of(&self) -> usize {
168 let Self { absolute, tree } = self;
169 absolute.weight_of() + tree.weight_of()
170 }
171}
172
173impl WeightOf for UseTree {
174 fn weight_of(&self) -> usize {
175 match self {
176 UseTree::Tree(tr) => tr.weight_of(),
177 UseTree::Path(pa, tr) => pa.weight_of() + tr.weight_of(),
178 UseTree::Alias(src, dst) => src.weight_of() + dst.weight_of(),
179 UseTree::Name(src) => src.weight_of(),
180 UseTree::Glob => size_of_val(self),
181 }
182 }
183}
184
185impl WeightOf for Ty {
186 fn weight_of(&self) -> usize {
187 let Self { span, kind } = self;
188 span.weight_of() + kind.weight_of()
189 }
190}
191
192impl WeightOf for TyKind {
193 fn weight_of(&self) -> usize {
194 match self {
195 TyKind::Never | TyKind::Empty | TyKind::Infer => size_of_val(self),
196 TyKind::Path(v) => v.weight_of(),
197 TyKind::Array(v) => v.weight_of(),
198 TyKind::Slice(v) => v.weight_of(),
199 TyKind::Tuple(v) => v.weight_of(),
200 TyKind::Ref(v) => v.weight_of(),
201 TyKind::Fn(v) => v.weight_of(),
202 }
203 }
204}
205
206impl WeightOf for TyArray {
207 fn weight_of(&self) -> usize {
208 let Self { ty, count } = self;
209 ty.weight_of() + count.weight_of()
210 }
211}
212
213impl WeightOf for TySlice {
214 fn weight_of(&self) -> usize {
215 let Self { ty } = self;
216 ty.weight_of()
217 }
218}
219
220impl WeightOf for TyTuple {
221 fn weight_of(&self) -> usize {
222 let Self { types } = self;
223 types.weight_of()
224 }
225}
226
227impl WeightOf for TyRef {
228 fn weight_of(&self) -> usize {
229 let Self { mutable, count, to } = self;
230 mutable.weight_of() + count.weight_of() + to.weight_of()
231 }
232}
233
234impl WeightOf for TyFn {
235 fn weight_of(&self) -> usize {
236 let Self { args, rety } = self;
237 args.weight_of() + rety.weight_of()
238 }
239}
240
241impl WeightOf for Path {
242 fn weight_of(&self) -> usize {
243 let Self { absolute, parts } = self;
244 absolute.weight_of() + parts.weight_of()
245 }
246}
247
248impl WeightOf for PathPart {
249 fn weight_of(&self) -> usize {
250 match self {
251 PathPart::SuperKw => size_of_val(self),
252 PathPart::SelfTy => size_of_val(self),
253 PathPart::Ident(interned) => interned.weight_of(),
254 }
255 }
256}
257
258impl WeightOf for Stmt {
259 fn weight_of(&self) -> usize {
260 let Self { span, kind, semi } = self;
261 span.weight_of() + kind.weight_of() + semi.weight_of()
262 }
263}
264
265impl WeightOf for StmtKind {
266 fn weight_of(&self) -> usize {
267 match self {
268 StmtKind::Empty => size_of_val(self),
269 StmtKind::Item(item) => item.weight_of(),
270 StmtKind::Expr(expr) => expr.weight_of(),
271 }
272 }
273}
274
275impl WeightOf for Expr {
276 fn weight_of(&self) -> usize {
277 let Self { span, kind } = self;
278 span.weight_of() + kind.weight_of()
279 }
280}
281
282impl WeightOf for ExprKind {
283 fn weight_of(&self) -> usize {
284 match self {
285 ExprKind::Empty => size_of_val(self),
286 ExprKind::Closure(v) => v.weight_of(),
287 ExprKind::Quote(v) => v.weight_of(),
288 ExprKind::Let(v) => v.weight_of(),
289 ExprKind::Match(v) => v.weight_of(),
290 ExprKind::Assign(v) => v.weight_of(),
291 ExprKind::Modify(v) => v.weight_of(),
292 ExprKind::Binary(v) => v.weight_of(),
293 ExprKind::Unary(v) => v.weight_of(),
294 ExprKind::Cast(v) => v.weight_of(),
295 ExprKind::Member(v) => v.weight_of(),
296 ExprKind::Index(v) => v.weight_of(),
297 ExprKind::Structor(v) => v.weight_of(),
298 ExprKind::Path(v) => v.weight_of(),
299 ExprKind::Literal(v) => v.weight_of(),
300 ExprKind::Array(v) => v.weight_of(),
301 ExprKind::ArrayRep(v) => v.weight_of(),
302 ExprKind::AddrOf(v) => v.weight_of(),
303 ExprKind::Block(v) => v.weight_of(),
304 ExprKind::Group(v) => v.weight_of(),
305 ExprKind::Tuple(v) => v.weight_of(),
306 ExprKind::While(v) => v.weight_of(),
307 ExprKind::If(v) => v.weight_of(),
308 ExprKind::For(v) => v.weight_of(),
309 ExprKind::Break(v) => v.weight_of(),
310 ExprKind::Return(v) => v.weight_of(),
311 ExprKind::Continue => size_of_val(self),
312 }
313 }
314}
315
316impl WeightOf for Closure {
317 fn weight_of(&self) -> usize {
318 let Self { arg, body } = self;
319 arg.weight_of() + body.weight_of()
320 }
321}
322
323impl WeightOf for Quote {
324 fn weight_of(&self) -> usize {
325 let Self { quote } = self;
326 quote.weight_of()
327 }
328}
329
330impl WeightOf for Let {
331 fn weight_of(&self) -> usize {
332 let Self { mutable, name, ty, init } = self;
333 mutable.weight_of() + name.weight_of() + ty.weight_of() + init.weight_of()
334 }
335}
336
337impl WeightOf for Pattern {
338 fn weight_of(&self) -> usize {
339 match self {
340 Pattern::Name(s) => size_of_val(s),
341 Pattern::Path(p) => p.weight_of(),
342 Pattern::Literal(literal) => literal.weight_of(),
343 Pattern::Rest(Some(pattern)) => pattern.weight_of(),
344 Pattern::Rest(None) => 0,
345 Pattern::Ref(mutability, pattern) => mutability.weight_of() + pattern.weight_of(),
346 Pattern::RangeExc(head, tail) => head.weight_of() + tail.weight_of(),
347 Pattern::RangeInc(head, tail) => head.weight_of() + tail.weight_of(),
348 Pattern::Tuple(patterns) | Pattern::Array(patterns) => patterns.weight_of(),
349 Pattern::Struct(path, items) => {
350 let sitems: usize = items
351 .iter()
352 .map(|(name, opt)| name.weight_of() + opt.weight_of())
353 .sum();
354 path.weight_of() + sitems
355 }
356 Pattern::TupleStruct(path, patterns) => path.weight_of() + patterns.weight_of(),
357 }
358 }
359}
360
361impl WeightOf for Match {
362 fn weight_of(&self) -> usize {
363 let Self { scrutinee, arms } = self;
364 scrutinee.weight_of() + arms.weight_of()
365 }
366}
367
368impl WeightOf for MatchArm {
369 fn weight_of(&self) -> usize {
370 let Self(pattern, expr) = self;
371 pattern.weight_of() + expr.weight_of()
372 }
373}
374
375impl WeightOf for Assign {
376 fn weight_of(&self) -> usize {
377 let Self { parts } = self;
378
379 parts.0.weight_of() + parts.1.weight_of()
380 }
381}
382
383impl WeightOf for Modify {
384 #[rustfmt::skip]
385 fn weight_of(&self) -> usize {
386 let Self { kind, parts } = self;
387 kind.weight_of()
388 + parts.0.weight_of()
389 + parts.1.weight_of()
390 }
391}
392
393impl WeightOf for Binary {
394 fn weight_of(&self) -> usize {
395 let Self { kind, parts } = self;
396
397 kind.weight_of() + parts.0.weight_of() + parts.1.weight_of()
398 }
399}
400
401impl WeightOf for Unary {
402 #[rustfmt::skip]
403 fn weight_of(&self) -> usize {
404 let Self { kind, tail } = self;
405 kind.weight_of() + tail.weight_of()
406 }
407}
408
409impl WeightOf for Cast {
410 fn weight_of(&self) -> usize {
411 let Self { head, ty } = self;
412 head.weight_of() + ty.weight_of()
413 }
414}
415
416impl WeightOf for Member {
417 fn weight_of(&self) -> usize {
418 let Self { head, kind } = self;
419
420 head.weight_of() + kind.weight_of() }
422}
423
424impl WeightOf for MemberKind {
425 fn weight_of(&self) -> usize {
426 match self {
427 MemberKind::Call(_, tuple) => tuple.weight_of(),
428 MemberKind::Struct(_) => 0,
429 MemberKind::Tuple(literal) => literal.weight_of(),
430 }
431 }
432}
433
434impl WeightOf for Index {
435 fn weight_of(&self) -> usize {
436 let Self { head, indices } = self;
437 head.weight_of() + indices.weight_of()
438 }
439}
440
441impl WeightOf for Literal {
442 fn weight_of(&self) -> usize {
443 match self {
444 Literal::Bool(v) => v.weight_of(),
445 Literal::Char(v) => v.weight_of(),
446 Literal::Int(v) => v.weight_of(),
447 Literal::Float(v) => v.weight_of(),
448 Literal::String(v) => v.weight_of(),
449 }
450 }
451}
452
453impl WeightOf for Structor {
454 fn weight_of(&self) -> usize {
455 let Self { to, init } = self;
456 to.weight_of() + init.weight_of()
457 }
458}
459
460impl WeightOf for Fielder {
461 fn weight_of(&self) -> usize {
462 let Self { name, init } = self;
463 name.weight_of() + init.weight_of()
464 }
465}
466
467impl WeightOf for Array {
468 fn weight_of(&self) -> usize {
469 let Self { values } = self;
470 values.weight_of()
471 }
472}
473
474impl WeightOf for ArrayRep {
475 fn weight_of(&self) -> usize {
476 let Self { value, repeat } = self;
477 value.weight_of() + repeat.weight_of()
478 }
479}
480
481impl WeightOf for AddrOf {
482 fn weight_of(&self) -> usize {
483 let Self { mutable, expr } = self;
484 mutable.weight_of() + expr.weight_of()
485 }
486}
487
488impl WeightOf for Block {
489 fn weight_of(&self) -> usize {
490 let Self { stmts } = self;
491 stmts.weight_of()
492 }
493}
494
495impl WeightOf for Group {
496 fn weight_of(&self) -> usize {
497 let Self { expr } = self;
498 expr.weight_of()
499 }
500}
501
502impl WeightOf for Tuple {
503 fn weight_of(&self) -> usize {
504 let Self { exprs } = self;
505 exprs.weight_of()
506 }
507}
508
509impl WeightOf for While {
510 fn weight_of(&self) -> usize {
511 let Self { cond, pass, fail } = self;
512 cond.weight_of() + pass.weight_of() + fail.weight_of()
513 }
514}
515
516impl WeightOf for If {
517 fn weight_of(&self) -> usize {
518 let Self { cond, pass, fail } = self;
519 cond.weight_of() + pass.weight_of() + fail.weight_of()
520 }
521}
522
523impl WeightOf for For {
524 fn weight_of(&self) -> usize {
525 let Self { bind, cond, pass, fail } = self;
526 bind.weight_of() + cond.weight_of() + pass.weight_of() + fail.weight_of()
527 }
528}
529
530impl WeightOf for Else {
531 fn weight_of(&self) -> usize {
532 let Self { body } = self;
533 body.weight_of()
534 }
535}
536
537impl WeightOf for Break {
538 fn weight_of(&self) -> usize {
539 let Self { body } = self;
540 body.weight_of()
541 }
542}
543
544impl WeightOf for Return {
545 fn weight_of(&self) -> usize {
546 let Self { body } = self;
547 body.weight_of()
548 }
549}
550
551impl<T: WeightOf> WeightOf for Option<T> {
554 fn weight_of(&self) -> usize {
555 match self {
556 Some(t) => t.weight_of().max(size_of_val(t)),
557 None => size_of_val(self),
558 }
559 }
560}
561
562impl<T: WeightOf> WeightOf for [T] {
563 fn weight_of(&self) -> usize {
564 self.iter().map(WeightOf::weight_of).sum()
565 }
566}
567
568impl<T: WeightOf> WeightOf for Vec<T> {
569 fn weight_of(&self) -> usize {
570 size_of::<Self>() + self.iter().map(WeightOf::weight_of).sum::<usize>()
571 }
572}
573
574impl<T: WeightOf> WeightOf for Box<T> {
575 fn weight_of(&self) -> usize {
576 (**self).weight_of() + size_of::<Self>()
577 }
578}
579
580impl WeightOf for str {
581 fn weight_of(&self) -> usize {
582 self.len()
583 }
584}
585
586impl_size_of! {
587 u8, u16, u32, u64, u128, usize,
589 i8, i16, i32, i64, i128, isize,
590 f32, f64, bool, char,
591 Span,
593 Visibility, Mutability, Semi, ModifyKind, BinaryKind, UnaryKind
595}
596
597impl<T> WeightOf for Interned<'_, T> {
598 fn weight_of(&self) -> usize {
599 size_of_val(self) }
601}
602
603macro impl_size_of($($T:ty),*$(,)?) {
604 $(impl WeightOf for $T {
605 fn weight_of(&self) -> usize {
606 ::std::mem::size_of_val(self)
607 }
608 })*
609}