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 { gens, target, body } = self;
151 gens.weight_of() + 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, gens } = self;
188 span.weight_of() + kind.weight_of() + gens.weight_of()
189 }
190}
191
192impl WeightOf for TyKind {
193 fn weight_of(&self) -> usize {
194 match self {
195 TyKind::Never | 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::Ptr(v) => v.weight_of(),
202 TyKind::Fn(v) => v.weight_of(),
203 }
204 }
205}
206
207impl WeightOf for TyArray {
208 fn weight_of(&self) -> usize {
209 let Self { ty, count } = self;
210 ty.weight_of() + count.weight_of()
211 }
212}
213
214impl WeightOf for TySlice {
215 fn weight_of(&self) -> usize {
216 let Self { ty } = self;
217 ty.weight_of()
218 }
219}
220
221impl WeightOf for TyTuple {
222 fn weight_of(&self) -> usize {
223 let Self { types } = self;
224 types.weight_of()
225 }
226}
227
228impl WeightOf for TyRef {
229 fn weight_of(&self) -> usize {
230 let Self { mutable, count, to } = self;
231 mutable.weight_of() + count.weight_of() + to.weight_of()
232 }
233}
234
235impl WeightOf for TyPtr {
236 fn weight_of(&self) -> usize {
237 let Self { to } = self;
238 to.weight_of()
239 }
240}
241
242impl WeightOf for TyFn {
243 fn weight_of(&self) -> usize {
244 let Self { args, rety } = self;
245 args.weight_of() + rety.weight_of()
246 }
247}
248
249impl WeightOf for Path {
250 fn weight_of(&self) -> usize {
251 let Self { absolute, parts } = self;
252 absolute.weight_of() + parts.weight_of()
253 }
254}
255
256impl WeightOf for PathPart {
257 fn weight_of(&self) -> usize {
258 match self {
259 PathPart::SuperKw => size_of_val(self),
260 PathPart::SelfTy => size_of_val(self),
261 PathPart::Ident(interned) => interned.weight_of(),
262 }
263 }
264}
265
266impl WeightOf for Stmt {
267 fn weight_of(&self) -> usize {
268 let Self { span, kind, semi } = self;
269 span.weight_of() + kind.weight_of() + semi.weight_of()
270 }
271}
272
273impl WeightOf for StmtKind {
274 fn weight_of(&self) -> usize {
275 match self {
276 StmtKind::Empty => size_of_val(self),
277 StmtKind::Item(item) => item.weight_of(),
278 StmtKind::Expr(expr) => expr.weight_of(),
279 }
280 }
281}
282
283impl WeightOf for Expr {
284 fn weight_of(&self) -> usize {
285 let Self { span, kind } = self;
286 span.weight_of() + kind.weight_of()
287 }
288}
289
290impl WeightOf for ExprKind {
291 fn weight_of(&self) -> usize {
292 match self {
293 ExprKind::Empty => size_of_val(self),
294 ExprKind::Closure(v) => v.weight_of(),
295 ExprKind::Quote(v) => v.weight_of(),
296 ExprKind::Let(v) => v.weight_of(),
297 ExprKind::Match(v) => v.weight_of(),
298 ExprKind::Assign(v) => v.weight_of(),
299 ExprKind::Modify(v) => v.weight_of(),
300 ExprKind::Binary(v) => v.weight_of(),
301 ExprKind::Unary(v) => v.weight_of(),
302 ExprKind::Cast(v) => v.weight_of(),
303 ExprKind::Member(v) => v.weight_of(),
304 ExprKind::Index(v) => v.weight_of(),
305 ExprKind::Structor(v) => v.weight_of(),
306 ExprKind::Path(v) => v.weight_of(),
307 ExprKind::Literal(v) => v.weight_of(),
308 ExprKind::Array(v) => v.weight_of(),
309 ExprKind::ArrayRep(v) => v.weight_of(),
310 ExprKind::AddrOf(v) => v.weight_of(),
311 ExprKind::Block(v) => v.weight_of(),
312 ExprKind::Group(v) => v.weight_of(),
313 ExprKind::Tuple(v) => v.weight_of(),
314 ExprKind::While(v) => v.weight_of(),
315 ExprKind::If(v) => v.weight_of(),
316 ExprKind::For(v) => v.weight_of(),
317 ExprKind::Break(v) => v.weight_of(),
318 ExprKind::Return(v) => v.weight_of(),
319 ExprKind::Continue => size_of_val(self),
320 }
321 }
322}
323
324impl WeightOf for Closure {
325 fn weight_of(&self) -> usize {
326 let Self { arg, body } = self;
327 arg.weight_of() + body.weight_of()
328 }
329}
330
331impl WeightOf for Quote {
332 fn weight_of(&self) -> usize {
333 let Self { quote } = self;
334 quote.weight_of()
335 }
336}
337
338impl WeightOf for Let {
339 fn weight_of(&self) -> usize {
340 let Self { mutable, name, ty, init } = self;
341 mutable.weight_of() + name.weight_of() + ty.weight_of() + init.weight_of()
342 }
343}
344
345impl WeightOf for Pattern {
346 fn weight_of(&self) -> usize {
347 match self {
348 Pattern::Name(s) => size_of_val(s),
349 Pattern::Path(p) => p.weight_of(),
350 Pattern::Literal(literal) => literal.weight_of(),
351 Pattern::Rest(Some(pattern)) => pattern.weight_of(),
352 Pattern::Rest(None) => 0,
353 Pattern::Ref(mutability, pattern) => mutability.weight_of() + pattern.weight_of(),
354 Pattern::RangeExc(head, tail) => head.weight_of() + tail.weight_of(),
355 Pattern::RangeInc(head, tail) => head.weight_of() + tail.weight_of(),
356 Pattern::Tuple(patterns) | Pattern::Array(patterns) => patterns.weight_of(),
357 Pattern::Struct(path, items) => {
358 let sitems: usize = items
359 .iter()
360 .map(|(name, opt)| name.weight_of() + opt.weight_of())
361 .sum();
362 path.weight_of() + sitems
363 }
364 Pattern::TupleStruct(path, patterns) => path.weight_of() + patterns.weight_of(),
365 }
366 }
367}
368
369impl WeightOf for Match {
370 fn weight_of(&self) -> usize {
371 let Self { scrutinee, arms } = self;
372 scrutinee.weight_of() + arms.weight_of()
373 }
374}
375
376impl WeightOf for MatchArm {
377 fn weight_of(&self) -> usize {
378 let Self(pattern, expr) = self;
379 pattern.weight_of() + expr.weight_of()
380 }
381}
382
383impl WeightOf for Assign {
384 fn weight_of(&self) -> usize {
385 let Self { parts } = self;
386
387 parts.0.weight_of() + parts.1.weight_of()
388 }
389}
390
391impl WeightOf for Modify {
392 #[rustfmt::skip]
393 fn weight_of(&self) -> usize {
394 let Self { kind, parts } = self;
395 kind.weight_of()
396 + parts.0.weight_of()
397 + parts.1.weight_of()
398 }
399}
400
401impl WeightOf for Binary {
402 fn weight_of(&self) -> usize {
403 let Self { kind, parts } = self;
404
405 kind.weight_of() + parts.0.weight_of() + parts.1.weight_of()
406 }
407}
408
409impl WeightOf for Unary {
410 #[rustfmt::skip]
411 fn weight_of(&self) -> usize {
412 let Self { kind, tail } = self;
413 kind.weight_of() + tail.weight_of()
414 }
415}
416
417impl WeightOf for Cast {
418 fn weight_of(&self) -> usize {
419 let Self { head, ty } = self;
420 head.weight_of() + ty.weight_of()
421 }
422}
423
424impl WeightOf for Member {
425 fn weight_of(&self) -> usize {
426 let Self { head, kind } = self;
427
428 head.weight_of() + kind.weight_of() }
430}
431
432impl WeightOf for MemberKind {
433 fn weight_of(&self) -> usize {
434 match self {
435 MemberKind::Call(_, tuple) => tuple.weight_of(),
436 MemberKind::Struct(_) => 0,
437 MemberKind::Tuple(literal) => literal.weight_of(),
438 }
439 }
440}
441
442impl WeightOf for Index {
443 fn weight_of(&self) -> usize {
444 let Self { head, indices } = self;
445 head.weight_of() + indices.weight_of()
446 }
447}
448
449impl WeightOf for Literal {
450 fn weight_of(&self) -> usize {
451 match self {
452 Literal::Bool(v) => v.weight_of(),
453 Literal::Char(v) => v.weight_of(),
454 Literal::Int(v) => v.weight_of(),
455 Literal::Float(v) => v.weight_of(),
456 Literal::String(v) => v.weight_of(),
457 }
458 }
459}
460
461impl WeightOf for Structor {
462 fn weight_of(&self) -> usize {
463 let Self { to, init } = self;
464 to.weight_of() + init.weight_of()
465 }
466}
467
468impl WeightOf for Fielder {
469 fn weight_of(&self) -> usize {
470 let Self { name, init } = self;
471 name.weight_of() + init.weight_of()
472 }
473}
474
475impl WeightOf for Array {
476 fn weight_of(&self) -> usize {
477 let Self { values } = self;
478 values.weight_of()
479 }
480}
481
482impl WeightOf for ArrayRep {
483 fn weight_of(&self) -> usize {
484 let Self { value, repeat } = self;
485 value.weight_of() + repeat.weight_of()
486 }
487}
488
489impl WeightOf for AddrOf {
490 fn weight_of(&self) -> usize {
491 let Self { mutable, expr } = self;
492 mutable.weight_of() + expr.weight_of()
493 }
494}
495
496impl WeightOf for Block {
497 fn weight_of(&self) -> usize {
498 let Self { stmts } = self;
499 stmts.weight_of()
500 }
501}
502
503impl WeightOf for Group {
504 fn weight_of(&self) -> usize {
505 let Self { expr } = self;
506 expr.weight_of()
507 }
508}
509
510impl WeightOf for Tuple {
511 fn weight_of(&self) -> usize {
512 let Self { exprs } = self;
513 exprs.weight_of()
514 }
515}
516
517impl WeightOf for While {
518 fn weight_of(&self) -> usize {
519 let Self { cond, pass, fail } = self;
520 cond.weight_of() + pass.weight_of() + fail.weight_of()
521 }
522}
523
524impl WeightOf for If {
525 fn weight_of(&self) -> usize {
526 let Self { cond, pass, fail } = self;
527 cond.weight_of() + pass.weight_of() + fail.weight_of()
528 }
529}
530
531impl WeightOf for For {
532 fn weight_of(&self) -> usize {
533 let Self { bind, cond, pass, fail } = self;
534 bind.weight_of() + cond.weight_of() + pass.weight_of() + fail.weight_of()
535 }
536}
537
538impl WeightOf for Else {
539 fn weight_of(&self) -> usize {
540 let Self { body } = self;
541 body.weight_of()
542 }
543}
544
545impl WeightOf for Break {
546 fn weight_of(&self) -> usize {
547 let Self { body } = self;
548 body.weight_of()
549 }
550}
551
552impl WeightOf for Return {
553 fn weight_of(&self) -> usize {
554 let Self { body } = self;
555 body.weight_of()
556 }
557}
558
559impl<T: WeightOf> WeightOf for Option<T> {
562 fn weight_of(&self) -> usize {
563 match self {
564 Some(t) => t.weight_of().max(size_of_val(t)),
565 None => size_of_val(self),
566 }
567 }
568}
569
570impl<T: WeightOf> WeightOf for [T] {
571 fn weight_of(&self) -> usize {
572 self.iter().map(WeightOf::weight_of).sum()
573 }
574}
575
576impl<T: WeightOf> WeightOf for Vec<T> {
577 fn weight_of(&self) -> usize {
578 size_of::<Self>() + self.iter().map(WeightOf::weight_of).sum::<usize>()
579 }
580}
581
582impl<T: WeightOf> WeightOf for Box<T> {
583 fn weight_of(&self) -> usize {
584 (**self).weight_of() + size_of::<Self>()
585 }
586}
587
588impl WeightOf for str {
589 fn weight_of(&self) -> usize {
590 self.len()
591 }
592}
593
594impl_size_of! {
595 u8, u16, u32, u64, u128, usize,
597 i8, i16, i32, i64, i128, isize,
598 f32, f64, bool, char,
599 Span,
601 Visibility, Mutability, Semi, ModifyKind, BinaryKind, UnaryKind
603}
604
605impl<T> WeightOf for Interned<'_, T> {
606 fn weight_of(&self) -> usize {
607 size_of_val(self) }
609}
610
611macro impl_size_of($($T:ty),*$(,)?) {
612 $(impl WeightOf for $T {
613 fn weight_of(&self) -> usize {
614 ::std::mem::size_of_val(self)
615 }
616 })*
617}