1use cairo_lang_debug::DebugWithDb;
2use cairo_lang_defs::ids::{MemberId, NamedLanguageElementId, StatementUseId, VarId};
3use cairo_lang_diagnostics::DiagnosticAdded;
4use cairo_lang_proc_macros::{DebugWithDb, SemanticObject};
5use cairo_lang_syntax::node::ast;
6use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
7use id_arena::{Arena, ArenaBehavior};
8use num_bigint::BigInt;
9use salsa::Database;
10
11use super::fmt::ExprFormatter;
12use crate::items::constant::ConstValueId;
13use crate::{ConcreteStructId, FunctionId, TypeId, semantic};
14
15macro_rules! define_arena_id {
17 ($id:ident, $behaviour:ident) => {
18 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
19 pub struct $id(u32, usize);
20
21 impl core::fmt::Debug for $id {
22 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23 f.debug_tuple(stringify!($id)).field(&self.1).finish()
24 }
25 }
26
27 #[derive(Clone, Debug, PartialEq, Eq)]
28 pub struct $behaviour;
29 impl ArenaBehavior for $behaviour {
30 type Id = $id;
31
32 fn new_id(arena_id: u32, index: usize) -> Self::Id {
33 $id(arena_id, index)
34 }
35
36 fn arena_id(id: Self::Id) -> u32 {
37 id.0
38 }
39
40 fn index(id: Self::Id) -> usize {
41 id.1
42 }
43 }
44 };
45}
46
47define_arena_id!(PatternId, PatternArenaBehavior);
48pub type PatternArena<'db> = Arena<semantic::Pattern<'db>, PatternArenaBehavior>;
49define_arena_id!(ExprId, ExprArenaBehavior);
50pub type ExprArena<'db> = Arena<semantic::Expr<'db>, ExprArenaBehavior>;
51define_arena_id!(StatementId, StatementArenaBehavior);
52pub type StatementArena<'db> = Arena<semantic::Statement<'db>, StatementArenaBehavior>;
53
54#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
55#[debug_db(ExprFormatter<'db>)]
56pub enum Statement<'db> {
57 Expr(StatementExpr<'db>),
58 Let(StatementLet<'db>),
59 Continue(StatementContinue<'db>),
60 Return(StatementReturn<'db>),
61 Break(StatementBreak<'db>),
62 Item(StatementItem<'db>),
63}
64impl<'db> Statement<'db> {
65 pub fn stable_ptr(&self) -> ast::StatementPtr<'db> {
66 match self {
67 Statement::Expr(stmt) => stmt.stable_ptr,
68 Statement::Let(stmt) => stmt.stable_ptr,
69 Statement::Continue(stmt) => stmt.stable_ptr,
70 Statement::Return(stmt) => stmt.stable_ptr,
71 Statement::Break(stmt) => stmt.stable_ptr,
72 Statement::Item(stmt) => stmt.stable_ptr,
73 }
74 }
75}
76
77impl<'db> From<&Statement<'db>> for SyntaxStablePtrId<'db> {
78 fn from(statement: &Statement<'db>) -> Self {
79 statement.stable_ptr().into()
80 }
81}
82
83#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
84#[debug_db(ExprFormatter<'db>)]
85pub struct StatementExpr<'db> {
86 pub expr: ExprId,
87 #[hide_field_debug_with_db]
88 #[dont_rewrite]
89 pub stable_ptr: ast::StatementPtr<'db>,
90}
91
92#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
93#[debug_db(ExprFormatter<'db>)]
94pub struct StatementLet<'db> {
95 pub pattern: PatternId,
96 pub expr: ExprId,
97 pub else_clause: Option<ExprId>,
98 #[hide_field_debug_with_db]
99 #[dont_rewrite]
100 pub stable_ptr: ast::StatementPtr<'db>,
101}
102
103#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
104#[debug_db(ExprFormatter<'db>)]
105pub struct StatementContinue<'db> {
106 #[hide_field_debug_with_db]
107 #[dont_rewrite]
108 pub stable_ptr: ast::StatementPtr<'db>,
109}
110
111#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
112#[debug_db(ExprFormatter<'db>)]
113pub struct StatementReturn<'db> {
114 pub expr_option: Option<ExprId>,
115 #[hide_field_debug_with_db]
116 #[dont_rewrite]
117 pub stable_ptr: ast::StatementPtr<'db>,
118}
119
120#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
121#[debug_db(ExprFormatter<'db>)]
122pub struct StatementBreak<'db> {
123 pub expr_option: Option<ExprId>,
124 #[hide_field_debug_with_db]
125 #[dont_rewrite]
126 pub stable_ptr: ast::StatementPtr<'db>,
127}
128
129#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
130#[debug_db(ExprFormatter<'db>)]
131pub struct StatementItem<'db> {
132 #[hide_field_debug_with_db]
133 #[dont_rewrite]
134 pub stable_ptr: ast::StatementPtr<'db>,
135}
136
137#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
139#[debug_db(ExprFormatter<'db>)]
140pub enum Expr<'db> {
141 Tuple(ExprTuple<'db>),
142 Snapshot(ExprSnapshot<'db>),
143 Desnap(ExprDesnap<'db>),
144 Assignment(ExprAssignment<'db>),
145 LogicalOperator(ExprLogicalOperator<'db>),
146 Block(ExprBlock<'db>),
147 Loop(ExprLoop<'db>),
148 While(ExprWhile<'db>),
149 For(ExprFor<'db>),
150 FunctionCall(ExprFunctionCall<'db>),
151 Match(ExprMatch<'db>),
152 If(ExprIf<'db>),
153 Var(ExprVar<'db>),
154 Literal(ExprLiteral<'db>),
155 StringLiteral(ExprStringLiteral<'db>),
156 MemberAccess(ExprMemberAccess<'db>),
157 StructCtor(ExprStructCtor<'db>),
158 EnumVariantCtor(ExprEnumVariantCtor<'db>),
159 PropagateError(ExprPropagateError<'db>),
160 Constant(ExprConstant<'db>),
161 FixedSizeArray(ExprFixedSizeArray<'db>),
162 ExprClosure(ExprClosure<'db>),
163 Missing(ExprMissing<'db>),
164}
165impl<'db> Expr<'db> {
166 pub fn ty(&self) -> semantic::TypeId<'db> {
167 match self {
168 Expr::Assignment(expr) => expr.ty,
169 Expr::Tuple(expr) => expr.ty,
170 Expr::Snapshot(expr) => expr.ty,
171 Expr::Desnap(expr) => expr.ty,
172 Expr::LogicalOperator(expr) => expr.ty,
173 Expr::Block(expr) => expr.ty,
174 Expr::Loop(expr) => expr.ty,
175 Expr::While(expr) => expr.ty,
176 Expr::For(expr) => expr.ty,
177 Expr::FunctionCall(expr) => expr.ty,
178 Expr::Match(expr) => expr.ty,
179 Expr::If(expr) => expr.ty,
180 Expr::Var(expr) => expr.ty,
181 Expr::Literal(expr) => expr.ty,
182 Expr::StringLiteral(expr) => expr.ty,
183 Expr::MemberAccess(expr) => expr.ty,
184 Expr::StructCtor(expr) => expr.ty,
185 Expr::EnumVariantCtor(expr) => expr.ty,
186 Expr::PropagateError(expr) => expr.ok_variant.ty,
187 Expr::Constant(expr) => expr.ty,
188 Expr::Missing(expr) => expr.ty,
189 Expr::FixedSizeArray(expr) => expr.ty,
190 Expr::ExprClosure(expr) => expr.ty,
191 }
192 }
193 pub fn stable_ptr(&self) -> ast::ExprPtr<'db> {
194 match self {
195 Expr::Assignment(expr) => expr.stable_ptr,
196 Expr::Tuple(expr) => expr.stable_ptr,
197 Expr::Snapshot(expr) => expr.stable_ptr,
198 Expr::Desnap(expr) => expr.stable_ptr,
199 Expr::LogicalOperator(expr) => expr.stable_ptr,
200 Expr::Block(expr) => expr.stable_ptr,
201 Expr::Loop(expr) => expr.stable_ptr,
202 Expr::While(expr) => expr.stable_ptr,
203 Expr::For(expr) => expr.stable_ptr,
204 Expr::FunctionCall(expr) => expr.stable_ptr,
205 Expr::Match(expr) => expr.stable_ptr,
206 Expr::If(expr) => expr.stable_ptr,
207 Expr::Var(expr) => expr.stable_ptr,
208 Expr::Literal(expr) => expr.stable_ptr,
209 Expr::StringLiteral(expr) => expr.stable_ptr,
210 Expr::MemberAccess(expr) => expr.stable_ptr,
211 Expr::StructCtor(expr) => expr.stable_ptr,
212 Expr::EnumVariantCtor(expr) => expr.stable_ptr,
213 Expr::PropagateError(expr) => expr.stable_ptr,
214 Expr::Constant(expr) => expr.stable_ptr,
215 Expr::Missing(expr) => expr.stable_ptr,
216 Expr::FixedSizeArray(expr) => expr.stable_ptr,
217 Expr::ExprClosure(expr) => expr.stable_ptr,
218 }
219 }
220
221 pub fn as_member_path(&self) -> Option<ExprVarMemberPath<'db>> {
223 match self {
224 Expr::Var(expr) => Some(ExprVarMemberPath::Var(expr.clone())),
225 Expr::MemberAccess(expr) => expr.member_path.clone(),
226 _ => None,
227 }
228 }
229}
230
231impl<'db> From<&Expr<'db>> for SyntaxStablePtrId<'db> {
232 fn from(expr: &Expr<'db>) -> Self {
233 expr.stable_ptr().into()
234 }
235}
236
237#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
238#[debug_db(ExprFormatter<'db>)]
239pub struct ExprTuple<'db> {
240 pub items: Vec<ExprId>,
241 pub ty: semantic::TypeId<'db>,
242 #[hide_field_debug_with_db]
243 #[dont_rewrite]
244 pub stable_ptr: ast::ExprPtr<'db>,
245}
246
247#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
248#[debug_db(ExprFormatter<'db>)]
249pub struct ExprFixedSizeArray<'db> {
250 pub items: FixedSizeArrayItems<'db>,
251 pub ty: semantic::TypeId<'db>,
252 #[hide_field_debug_with_db]
253 #[dont_rewrite]
254 pub stable_ptr: ast::ExprPtr<'db>,
255}
256
257#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
260#[debug_db(ExprFormatter<'db>)]
261pub enum FixedSizeArrayItems<'db> {
262 Items(Vec<ExprId>),
263 ValueAndSize(ExprId, ConstValueId<'db>),
264}
265
266#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
267#[debug_db(ExprFormatter<'db>)]
268pub struct ExprSnapshot<'db> {
269 pub inner: ExprId,
270 pub ty: semantic::TypeId<'db>,
271 #[hide_field_debug_with_db]
272 #[dont_rewrite]
273 pub stable_ptr: ast::ExprPtr<'db>,
274}
275
276#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
277#[debug_db(ExprFormatter<'db>)]
278pub struct ExprDesnap<'db> {
279 pub inner: ExprId,
280 pub ty: semantic::TypeId<'db>,
281 #[hide_field_debug_with_db]
282 #[dont_rewrite]
283 pub stable_ptr: ast::ExprPtr<'db>,
284}
285
286#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
287#[debug_db(ExprFormatter<'db>)]
288pub struct ExprBlock<'db> {
289 pub statements: Vec<StatementId>,
290 pub tail: Option<ExprId>,
295 pub ty: semantic::TypeId<'db>,
296 #[hide_field_debug_with_db]
297 #[dont_rewrite]
298 pub stable_ptr: ast::ExprPtr<'db>,
299}
300
301#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
302#[debug_db(ExprFormatter<'db>)]
303pub struct ExprLoop<'db> {
304 pub body: ExprId,
305 pub ty: semantic::TypeId<'db>,
306 #[hide_field_debug_with_db]
307 #[dont_rewrite]
308 pub stable_ptr: ast::ExprPtr<'db>,
309}
310
311#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
312#[debug_db(ExprFormatter<'db>)]
313pub struct ExprWhile<'db> {
314 pub condition: Condition,
315 pub body: ExprId,
316 pub ty: semantic::TypeId<'db>,
317 #[hide_field_debug_with_db]
318 #[dont_rewrite]
319 pub stable_ptr: ast::ExprPtr<'db>,
320}
321
322#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
323#[debug_db(ExprFormatter<'db>)]
324pub struct ExprFor<'db> {
325 pub into_iter: FunctionId<'db>,
326 pub into_iter_member_path: ExprVarMemberPath<'db>,
327 pub next_function_id: FunctionId<'db>,
328 pub expr_id: ExprId,
329 pub pattern: PatternId,
330 pub body: ExprId,
331 pub ty: semantic::TypeId<'db>,
332 #[hide_field_debug_with_db]
333 #[dont_rewrite]
334 pub stable_ptr: ast::ExprPtr<'db>,
335}
336
337#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject, salsa::Update)]
339pub enum ExprVarMemberPath<'db> {
340 Var(ExprVar<'db>),
341 Member {
342 parent: Box<ExprVarMemberPath<'db>>,
343 member_id: MemberId<'db>,
344 #[dont_rewrite]
345 stable_ptr: ast::ExprPtr<'db>,
346 concrete_struct_id: ConcreteStructId<'db>,
347 ty: TypeId<'db>,
349 },
350}
351impl<'db> ExprVarMemberPath<'db> {
352 pub fn base_var(&self) -> VarId<'db> {
353 match self {
354 ExprVarMemberPath::Var(expr) => expr.var,
355 ExprVarMemberPath::Member { parent, .. } => parent.base_var(),
356 }
357 }
358 pub fn ty(&self) -> TypeId<'db> {
359 match self {
360 ExprVarMemberPath::Var(expr) => expr.ty,
361 ExprVarMemberPath::Member { ty, .. } => *ty,
362 }
363 }
364 pub fn stable_ptr(&self) -> ast::ExprPtr<'db> {
365 match self {
366 ExprVarMemberPath::Var(var) => var.stable_ptr,
367 ExprVarMemberPath::Member { stable_ptr, .. } => *stable_ptr,
368 }
369 }
370}
371impl<'db> DebugWithDb<'db> for ExprVarMemberPath<'db> {
372 type Db = dyn Database;
373
374 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
375 match self {
376 ExprVarMemberPath::Var(var) => var.fmt(f, db),
377 ExprVarMemberPath::Member { parent, member_id, .. } => {
378 write!(f, "{:?}::{}", parent.debug(db), member_id.name(db).long(db))
379 }
380 }
381 }
382}
383#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
384#[debug_db(ExprFormatter<'db>)]
385pub struct ExprClosure<'db> {
386 pub body: ExprId,
387 pub params: Vec<semantic::Parameter<'db>>,
388 #[hide_field_debug_with_db]
389 #[dont_rewrite]
390 pub stable_ptr: ast::ExprPtr<'db>,
391 pub ty: TypeId<'db>,
392}
393
394#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
395#[debug_db(ExprFormatter<'db>)]
396pub enum ExprFunctionCallArg<'db> {
397 Reference(ExprVarMemberPath<'db>),
398 Value(ExprId),
399}
400
401#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
402#[debug_db(ExprFormatter<'db>)]
403pub struct ExprFunctionCall<'db> {
404 pub function: FunctionId<'db>,
405 pub args: Vec<ExprFunctionCallArg<'db>>,
406 pub coupon_arg: Option<ExprId>,
410 pub ty: semantic::TypeId<'db>,
411 #[hide_field_debug_with_db]
412 #[dont_rewrite]
413 pub stable_ptr: ast::ExprPtr<'db>,
414}
415
416#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
417#[debug_db(ExprFormatter<'db>)]
418pub struct ExprMatch<'db> {
419 pub matched_expr: ExprId,
420 pub arms: Vec<MatchArm>,
421 pub ty: semantic::TypeId<'db>,
422 #[hide_field_debug_with_db]
423 #[dont_rewrite]
424 pub stable_ptr: ast::ExprPtr<'db>,
425}
426
427#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
428#[debug_db(ExprFormatter<'db>)]
429pub struct ExprIf<'db> {
430 pub conditions: Vec<Condition>,
431 pub if_block: ExprId,
432 pub else_block: Option<ExprId>,
433 pub ty: semantic::TypeId<'db>,
434 #[hide_field_debug_with_db]
435 #[dont_rewrite]
436 pub stable_ptr: ast::ExprPtr<'db>,
437}
438
439#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
440#[debug_db(ExprFormatter<'db>)]
441pub enum Condition {
442 BoolExpr(ExprId),
443 Let(ExprId, Vec<PatternId>),
444}
445
446#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
447#[debug_db(ExprFormatter<'db>)]
448pub struct MatchArm {
449 pub patterns: Vec<PatternId>,
450 pub expression: ExprId,
451}
452
453#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
454#[debug_db(ExprFormatter<'db>)]
455pub struct ExprAssignment<'db> {
456 pub ref_arg: ExprVarMemberPath<'db>,
457 pub rhs: semantic::ExprId,
458 pub ty: semantic::TypeId<'db>,
460 #[hide_field_debug_with_db]
461 #[dont_rewrite]
462 pub stable_ptr: ast::ExprPtr<'db>,
463}
464
465#[derive(Clone, Debug, Eq, Hash, PartialEq)]
466pub enum LogicalOperator {
467 AndAnd,
468 OrOr,
469}
470
471#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
472#[debug_db(ExprFormatter<'db>)]
473pub struct ExprLogicalOperator<'db> {
474 pub lhs: semantic::ExprId,
475 #[dont_rewrite]
476 pub op: LogicalOperator,
477 pub rhs: semantic::ExprId,
478 pub ty: semantic::TypeId<'db>,
480 #[hide_field_debug_with_db]
481 #[dont_rewrite]
482 pub stable_ptr: ast::ExprPtr<'db>,
483}
484
485#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject, salsa::Update)]
486pub struct ExprVar<'db> {
487 pub var: VarId<'db>,
488 pub ty: semantic::TypeId<'db>,
489 #[dont_rewrite]
490 pub stable_ptr: ast::ExprPtr<'db>,
491}
492impl<'db> DebugWithDb<'db> for ExprVar<'db> {
493 type Db = dyn Database;
494
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
496 self.var.fmt(f, db)
497 }
498}
499
500#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
502#[debug_db(ExprFormatter<'db>)]
503pub struct ExprLiteral<'db> {
504 #[dont_rewrite]
505 pub value: BigInt,
506 pub ty: semantic::TypeId<'db>,
507 #[hide_field_debug_with_db]
508 #[dont_rewrite]
509 pub stable_ptr: ast::ExprPtr<'db>,
510}
511
512#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
513#[debug_db(ExprFormatter<'db>)]
514pub struct ExprStringLiteral<'db> {
515 #[dont_rewrite]
516 pub value: String,
517 pub ty: semantic::TypeId<'db>,
518 #[hide_field_debug_with_db]
519 #[dont_rewrite]
520 pub stable_ptr: ast::ExprPtr<'db>,
521}
522
523#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
524#[debug_db(ExprFormatter<'db>)]
525pub struct ExprMemberAccess<'db> {
526 pub expr: semantic::ExprId,
527 pub concrete_struct_id: ConcreteStructId<'db>,
528 pub member: MemberId<'db>,
529 pub ty: semantic::TypeId<'db>,
530 #[hide_field_debug_with_db]
531 pub member_path: Option<ExprVarMemberPath<'db>>,
532 #[hide_field_debug_with_db]
533 #[dont_rewrite]
534 pub n_snapshots: usize,
535 #[hide_field_debug_with_db]
536 #[dont_rewrite]
537 pub stable_ptr: ast::ExprPtr<'db>,
538}
539
540#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
541#[debug_db(ExprFormatter<'db>)]
542pub struct ExprStructCtor<'db> {
543 pub concrete_struct_id: ConcreteStructId<'db>,
544 pub members: Vec<(ExprId, MemberId<'db>)>,
545 pub base_struct: Option<ExprId>,
548 pub ty: semantic::TypeId<'db>,
549 #[hide_field_debug_with_db]
550 #[dont_rewrite]
551 pub stable_ptr: ast::ExprPtr<'db>,
552}
553
554#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
555#[debug_db(ExprFormatter<'db>)]
556pub struct ExprEnumVariantCtor<'db> {
557 pub variant: semantic::ConcreteVariant<'db>,
558 pub value_expr: ExprId,
559 pub ty: semantic::TypeId<'db>,
560 #[hide_field_debug_with_db]
561 #[dont_rewrite]
562 pub stable_ptr: ast::ExprPtr<'db>,
563}
564
565#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
566#[debug_db(ExprFormatter<'db>)]
567pub struct ExprPropagateError<'db> {
568 pub inner: ExprId,
569 pub ok_variant: semantic::ConcreteVariant<'db>,
570 pub err_variant: semantic::ConcreteVariant<'db>,
571 pub func_err_variant: semantic::ConcreteVariant<'db>,
572 #[hide_field_debug_with_db]
573 #[dont_rewrite]
574 pub stable_ptr: ast::ExprPtr<'db>,
575}
576
577#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
578#[debug_db(ExprFormatter<'db>)]
579pub struct ExprConstant<'db> {
580 pub const_value_id: ConstValueId<'db>,
581 pub ty: semantic::TypeId<'db>,
582 #[dont_rewrite]
583 #[hide_field_debug_with_db]
584 pub stable_ptr: ast::ExprPtr<'db>,
585}
586
587#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
588#[debug_db(ExprFormatter<'db>)]
589pub struct ExprUse<'db> {
590 pub const_value_id: StatementUseId<'db>,
591 pub ty: semantic::TypeId<'db>,
592 #[dont_rewrite]
593 #[hide_field_debug_with_db]
594 pub stable_ptr: ast::ExprPtr<'db>,
595}
596
597#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
598#[debug_db(ExprFormatter<'db>)]
599pub struct ExprMissing<'db> {
600 pub ty: semantic::TypeId<'db>,
601 #[hide_field_debug_with_db]
602 #[dont_rewrite]
603 pub stable_ptr: ast::ExprPtr<'db>,
604 #[hide_field_debug_with_db]
605 #[dont_rewrite]
606 pub diag_added: DiagnosticAdded,
607}
608
609#[derive(Clone, Debug, Default, PartialEq, Eq, DebugWithDb)]
611#[debug_db(dyn Database)]
612pub struct Arenas<'db> {
613 pub exprs: ExprArena<'db>,
614 pub patterns: PatternArena<'db>,
615 pub statements: StatementArena<'db>,
616}
617
618unsafe impl<'db> salsa::Update for Arenas<'db> {
619 unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
620 let old_arenas: &mut Arenas<'db> = unsafe { &mut *old_pointer };
621
622 if old_arenas.exprs.next_id() != new_value.exprs.next_id()
624 || old_arenas.patterns.next_id() != new_value.patterns.next_id()
625 || old_arenas.statements.next_id() != new_value.statements.next_id()
626 {
627 *old_arenas = new_value;
628 return true;
629 }
630 false
631 }
632}