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(ExprNumericLiteral<'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 TempReference(ExprId),
402}
403
404#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
405#[debug_db(ExprFormatter<'db>)]
406pub struct ExprFunctionCall<'db> {
407 pub function: FunctionId<'db>,
408 pub args: Vec<ExprFunctionCallArg<'db>>,
409 pub coupon_arg: Option<ExprId>,
413 pub ty: semantic::TypeId<'db>,
414 #[hide_field_debug_with_db]
415 #[dont_rewrite]
416 pub stable_ptr: ast::ExprPtr<'db>,
417}
418
419#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
420#[debug_db(ExprFormatter<'db>)]
421pub struct ExprMatch<'db> {
422 pub matched_expr: ExprId,
423 pub arms: Vec<MatchArm>,
424 pub ty: semantic::TypeId<'db>,
425 #[hide_field_debug_with_db]
426 #[dont_rewrite]
427 pub stable_ptr: ast::ExprPtr<'db>,
428}
429
430#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
431#[debug_db(ExprFormatter<'db>)]
432pub struct ExprIf<'db> {
433 pub conditions: Vec<Condition>,
434 pub if_block: ExprId,
435 pub else_block: Option<ExprId>,
436 pub ty: semantic::TypeId<'db>,
437 #[hide_field_debug_with_db]
438 #[dont_rewrite]
439 pub stable_ptr: ast::ExprPtr<'db>,
440}
441
442#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
443#[debug_db(ExprFormatter<'db>)]
444pub enum Condition {
445 BoolExpr(ExprId),
446 Let(ExprId, Vec<PatternId>),
447}
448
449#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
450#[debug_db(ExprFormatter<'db>)]
451pub struct MatchArm {
452 pub patterns: Vec<PatternId>,
453 pub expression: ExprId,
454}
455
456#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
457#[debug_db(ExprFormatter<'db>)]
458pub struct ExprAssignment<'db> {
459 pub ref_arg: ExprVarMemberPath<'db>,
460 pub rhs: semantic::ExprId,
461 pub ty: semantic::TypeId<'db>,
463 #[hide_field_debug_with_db]
464 #[dont_rewrite]
465 pub stable_ptr: ast::ExprPtr<'db>,
466}
467
468#[derive(Clone, Debug, Eq, Hash, PartialEq)]
469pub enum LogicalOperator {
470 AndAnd,
471 OrOr,
472}
473
474#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
475#[debug_db(ExprFormatter<'db>)]
476pub struct ExprLogicalOperator<'db> {
477 pub lhs: semantic::ExprId,
478 #[dont_rewrite]
479 pub op: LogicalOperator,
480 pub rhs: semantic::ExprId,
481 pub ty: semantic::TypeId<'db>,
483 #[hide_field_debug_with_db]
484 #[dont_rewrite]
485 pub stable_ptr: ast::ExprPtr<'db>,
486}
487
488#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject, salsa::Update)]
489pub struct ExprVar<'db> {
490 pub var: VarId<'db>,
491 pub ty: semantic::TypeId<'db>,
492 #[dont_rewrite]
493 pub stable_ptr: ast::ExprPtr<'db>,
494}
495impl<'db> DebugWithDb<'db> for ExprVar<'db> {
496 type Db = dyn Database;
497
498 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
499 self.var.fmt(f, db)
500 }
501}
502
503#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
504#[debug_db(ExprFormatter<'db>)]
505pub struct ExprNumericLiteral<'db> {
506 #[dont_rewrite]
507 pub value: BigInt,
508 pub ty: semantic::TypeId<'db>,
509 #[hide_field_debug_with_db]
510 #[dont_rewrite]
511 pub stable_ptr: ast::ExprPtr<'db>,
512}
513
514#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
515#[debug_db(ExprFormatter<'db>)]
516pub struct ExprStringLiteral<'db> {
517 #[dont_rewrite]
518 pub value: String,
519 pub ty: semantic::TypeId<'db>,
520 #[hide_field_debug_with_db]
521 #[dont_rewrite]
522 pub stable_ptr: ast::ExprPtr<'db>,
523}
524
525#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
526#[debug_db(ExprFormatter<'db>)]
527pub struct ExprMemberAccess<'db> {
528 pub expr: semantic::ExprId,
529 pub concrete_struct_id: ConcreteStructId<'db>,
530 pub member: MemberId<'db>,
531 pub ty: semantic::TypeId<'db>,
532 #[hide_field_debug_with_db]
533 pub member_path: Option<ExprVarMemberPath<'db>>,
534 #[hide_field_debug_with_db]
535 #[dont_rewrite]
536 pub n_snapshots: usize,
537 #[hide_field_debug_with_db]
538 #[dont_rewrite]
539 pub stable_ptr: ast::ExprPtr<'db>,
540}
541
542#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
543#[debug_db(ExprFormatter<'db>)]
544pub struct ExprStructCtor<'db> {
545 pub concrete_struct_id: ConcreteStructId<'db>,
546 pub members: Vec<(ExprId, MemberId<'db>)>,
547 pub base_struct: Option<ExprId>,
550 pub ty: semantic::TypeId<'db>,
551 #[hide_field_debug_with_db]
552 #[dont_rewrite]
553 pub stable_ptr: ast::ExprPtr<'db>,
554}
555
556#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
557#[debug_db(ExprFormatter<'db>)]
558pub struct ExprEnumVariantCtor<'db> {
559 pub variant: semantic::ConcreteVariant<'db>,
560 pub value_expr: ExprId,
561 pub ty: semantic::TypeId<'db>,
562 #[hide_field_debug_with_db]
563 #[dont_rewrite]
564 pub stable_ptr: ast::ExprPtr<'db>,
565}
566
567#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
568#[debug_db(ExprFormatter<'db>)]
569pub struct ExprPropagateError<'db> {
570 pub inner: ExprId,
571 pub ok_variant: semantic::ConcreteVariant<'db>,
572 pub err_variant: semantic::ConcreteVariant<'db>,
573 pub func_err_variant: semantic::ConcreteVariant<'db>,
574 #[hide_field_debug_with_db]
575 #[dont_rewrite]
576 pub stable_ptr: ast::ExprPtr<'db>,
577}
578
579#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
580#[debug_db(ExprFormatter<'db>)]
581pub struct ExprConstant<'db> {
582 pub const_value_id: ConstValueId<'db>,
583 pub ty: semantic::TypeId<'db>,
584 #[dont_rewrite]
585 #[hide_field_debug_with_db]
586 pub stable_ptr: ast::ExprPtr<'db>,
587}
588
589#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
590#[debug_db(ExprFormatter<'db>)]
591pub struct ExprUse<'db> {
592 pub const_value_id: StatementUseId<'db>,
593 pub ty: semantic::TypeId<'db>,
594 #[dont_rewrite]
595 #[hide_field_debug_with_db]
596 pub stable_ptr: ast::ExprPtr<'db>,
597}
598
599#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
600#[debug_db(ExprFormatter<'db>)]
601pub struct ExprMissing<'db> {
602 pub ty: semantic::TypeId<'db>,
603 #[hide_field_debug_with_db]
604 #[dont_rewrite]
605 pub stable_ptr: ast::ExprPtr<'db>,
606 #[hide_field_debug_with_db]
607 #[dont_rewrite]
608 pub diag_added: DiagnosticAdded,
609}
610
611#[derive(Clone, Debug, Default, PartialEq, Eq, DebugWithDb)]
613#[debug_db(dyn Database)]
614pub struct Arenas<'db> {
615 pub exprs: ExprArena<'db>,
616 pub patterns: PatternArena<'db>,
617 pub statements: StatementArena<'db>,
618}
619
620unsafe impl<'db> salsa::Update for Arenas<'db> {
621 unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
622 let old_arenas: &mut Arenas<'db> = unsafe { &mut *old_pointer };
623
624 if old_arenas.exprs.next_id() != new_value.exprs.next_id()
626 || old_arenas.patterns.next_id() != new_value.patterns.next_id()
627 || old_arenas.statements.next_id() != new_value.statements.next_id()
628 {
629 *old_arenas = new_value;
630 return true;
631 }
632 false
633 }
634}