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 kind: MemberAccessKind<'db>,
344 #[dont_rewrite]
345 stable_ptr: ast::ExprPtr<'db>,
346 ty: TypeId<'db>,
348 },
349}
350impl<'db> ExprVarMemberPath<'db> {
351 pub fn base_var(&self) -> VarId<'db> {
352 match self {
353 ExprVarMemberPath::Var(expr) => expr.var,
354 ExprVarMemberPath::Member { parent, .. } => parent.base_var(),
355 }
356 }
357 pub fn ty(&self) -> TypeId<'db> {
358 match self {
359 ExprVarMemberPath::Var(expr) => expr.ty,
360 ExprVarMemberPath::Member { ty, .. } => *ty,
361 }
362 }
363 pub fn stable_ptr(&self) -> ast::ExprPtr<'db> {
364 match self {
365 ExprVarMemberPath::Var(var) => var.stable_ptr,
366 ExprVarMemberPath::Member { stable_ptr, .. } => *stable_ptr,
367 }
368 }
369}
370impl<'db> DebugWithDb<'db> for ExprVarMemberPath<'db> {
371 type Db = dyn Database;
372
373 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
374 match self {
375 ExprVarMemberPath::Var(var) => var.fmt(f, db),
376 ExprVarMemberPath::Member { parent, kind, .. } => match kind {
377 MemberAccessKind::Struct { member_id, .. } => {
378 write!(f, "{:?}::{}", parent.debug(db), member_id.name(db).long(db))
379 }
380 MemberAccessKind::Index { index, .. } => {
381 write!(f, "{:?}::{}", parent.debug(db), index)
382 }
383 },
384 }
385 }
386}
387#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
388#[debug_db(ExprFormatter<'db>)]
389pub struct ExprClosure<'db> {
390 pub body: ExprId,
391 pub params: Vec<semantic::Parameter<'db>>,
392 #[hide_field_debug_with_db]
393 #[dont_rewrite]
394 pub stable_ptr: ast::ExprPtr<'db>,
395 pub ty: TypeId<'db>,
396}
397
398#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
399#[debug_db(ExprFormatter<'db>)]
400pub enum ExprFunctionCallArg<'db> {
401 Reference(ExprVarMemberPath<'db>),
402 Value(ExprId),
403 TempReference(ExprId),
406}
407
408#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
409#[debug_db(ExprFormatter<'db>)]
410pub struct ExprFunctionCall<'db> {
411 pub function: FunctionId<'db>,
412 pub args: Vec<ExprFunctionCallArg<'db>>,
413 pub coupon_arg: Option<ExprId>,
417 pub ty: semantic::TypeId<'db>,
418 #[hide_field_debug_with_db]
419 #[dont_rewrite]
420 pub stable_ptr: ast::ExprPtr<'db>,
421}
422
423#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
424#[debug_db(ExprFormatter<'db>)]
425pub struct ExprMatch<'db> {
426 pub matched_expr: ExprId,
427 pub arms: Vec<MatchArm>,
428 pub ty: semantic::TypeId<'db>,
429 #[hide_field_debug_with_db]
430 #[dont_rewrite]
431 pub stable_ptr: ast::ExprPtr<'db>,
432}
433
434#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
435#[debug_db(ExprFormatter<'db>)]
436pub struct ExprIf<'db> {
437 pub conditions: Vec<Condition>,
438 pub if_block: ExprId,
439 pub else_block: Option<ExprId>,
440 pub ty: semantic::TypeId<'db>,
441 #[hide_field_debug_with_db]
442 #[dont_rewrite]
443 pub stable_ptr: ast::ExprPtr<'db>,
444}
445
446#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
447#[debug_db(ExprFormatter<'db>)]
448pub enum Condition {
449 BoolExpr(ExprId),
450 Let(ExprId, Vec<PatternId>),
451}
452
453#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
454#[debug_db(ExprFormatter<'db>)]
455pub struct MatchArm {
456 pub patterns: Vec<PatternId>,
457 pub expression: ExprId,
458}
459
460#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
461#[debug_db(ExprFormatter<'db>)]
462pub struct ExprAssignment<'db> {
463 pub ref_arg: ExprVarMemberPath<'db>,
464 pub rhs: semantic::ExprId,
465 pub ty: semantic::TypeId<'db>,
467 #[hide_field_debug_with_db]
468 #[dont_rewrite]
469 pub stable_ptr: ast::ExprPtr<'db>,
470}
471
472#[derive(Clone, Debug, Eq, Hash, PartialEq)]
473pub enum LogicalOperator {
474 AndAnd,
475 OrOr,
476}
477
478#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
479#[debug_db(ExprFormatter<'db>)]
480pub struct ExprLogicalOperator<'db> {
481 pub lhs: semantic::ExprId,
482 #[dont_rewrite]
483 pub op: LogicalOperator,
484 pub rhs: semantic::ExprId,
485 pub ty: semantic::TypeId<'db>,
487 #[hide_field_debug_with_db]
488 #[dont_rewrite]
489 pub stable_ptr: ast::ExprPtr<'db>,
490}
491
492#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject, salsa::Update)]
493pub struct ExprVar<'db> {
494 pub var: VarId<'db>,
495 pub ty: semantic::TypeId<'db>,
496 #[dont_rewrite]
497 pub stable_ptr: ast::ExprPtr<'db>,
498}
499impl<'db> DebugWithDb<'db> for ExprVar<'db> {
500 type Db = dyn Database;
501
502 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
503 self.var.fmt(f, db)
504 }
505}
506
507#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
508#[debug_db(ExprFormatter<'db>)]
509pub struct ExprNumericLiteral<'db> {
510 #[dont_rewrite]
511 pub value: BigInt,
512 pub ty: semantic::TypeId<'db>,
513 #[hide_field_debug_with_db]
514 #[dont_rewrite]
515 pub stable_ptr: ast::ExprPtr<'db>,
516}
517
518#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
519#[debug_db(ExprFormatter<'db>)]
520pub struct ExprStringLiteral<'db> {
521 #[dont_rewrite]
522 pub value: String,
523 pub ty: semantic::TypeId<'db>,
524 #[hide_field_debug_with_db]
525 #[dont_rewrite]
526 pub stable_ptr: ast::ExprPtr<'db>,
527}
528
529#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
532#[debug_db(dyn Database)]
533pub enum MemberAccessKind<'db> {
534 Struct { concrete_struct_id: ConcreteStructId<'db>, member_id: MemberId<'db> },
536 Index {
538 tuple_ty: TypeId<'db>,
540 #[dont_rewrite]
541 index: usize,
542 },
543}
544
545#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
546#[debug_db(ExprFormatter<'db>)]
547pub struct ExprMemberAccess<'db> {
548 pub expr: semantic::ExprId,
549 pub kind: MemberAccessKind<'db>,
550 pub ty: semantic::TypeId<'db>,
551 #[hide_field_debug_with_db]
552 pub member_path: Option<ExprVarMemberPath<'db>>,
553 #[hide_field_debug_with_db]
554 #[dont_rewrite]
555 pub n_snapshots: usize,
556 #[hide_field_debug_with_db]
557 #[dont_rewrite]
558 pub stable_ptr: ast::ExprPtr<'db>,
559}
560
561#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
562#[debug_db(ExprFormatter<'db>)]
563pub struct ExprStructCtor<'db> {
564 pub concrete_struct_id: ConcreteStructId<'db>,
565 pub members: Vec<(ExprId, MemberId<'db>)>,
566 pub base_struct: Option<ExprId>,
569 pub ty: semantic::TypeId<'db>,
570 #[hide_field_debug_with_db]
571 #[dont_rewrite]
572 pub stable_ptr: ast::ExprPtr<'db>,
573}
574
575#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
576#[debug_db(ExprFormatter<'db>)]
577pub struct ExprEnumVariantCtor<'db> {
578 pub variant: semantic::ConcreteVariant<'db>,
579 pub value_expr: ExprId,
580 pub ty: semantic::TypeId<'db>,
581 #[hide_field_debug_with_db]
582 #[dont_rewrite]
583 pub stable_ptr: ast::ExprPtr<'db>,
584}
585
586#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
587#[debug_db(ExprFormatter<'db>)]
588pub struct ExprPropagateError<'db> {
589 pub inner: ExprId,
590 pub ok_variant: semantic::ConcreteVariant<'db>,
591 pub err_variant: semantic::ConcreteVariant<'db>,
592 pub func_err_variant: semantic::ConcreteVariant<'db>,
593 #[hide_field_debug_with_db]
594 #[dont_rewrite]
595 pub stable_ptr: ast::ExprPtr<'db>,
596}
597
598#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
599#[debug_db(ExprFormatter<'db>)]
600pub struct ExprConstant<'db> {
601 pub const_value_id: ConstValueId<'db>,
602 pub ty: semantic::TypeId<'db>,
603 #[dont_rewrite]
604 #[hide_field_debug_with_db]
605 pub stable_ptr: ast::ExprPtr<'db>,
606}
607
608#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
609#[debug_db(ExprFormatter<'db>)]
610pub struct ExprUse<'db> {
611 pub const_value_id: StatementUseId<'db>,
612 pub ty: semantic::TypeId<'db>,
613 #[dont_rewrite]
614 #[hide_field_debug_with_db]
615 pub stable_ptr: ast::ExprPtr<'db>,
616}
617
618#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
619#[debug_db(ExprFormatter<'db>)]
620pub struct ExprMissing<'db> {
621 pub ty: semantic::TypeId<'db>,
622 #[hide_field_debug_with_db]
623 #[dont_rewrite]
624 pub stable_ptr: ast::ExprPtr<'db>,
625 #[hide_field_debug_with_db]
626 #[dont_rewrite]
627 pub diag_added: DiagnosticAdded,
628}
629
630#[derive(Clone, Debug, Default, PartialEq, Eq, DebugWithDb)]
632#[debug_db(dyn Database)]
633pub struct Arenas<'db> {
634 pub exprs: ExprArena<'db>,
635 pub patterns: PatternArena<'db>,
636 pub statements: StatementArena<'db>,
637}
638
639unsafe impl<'db> salsa::Update for Arenas<'db> {
640 unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
641 let old_arenas: &mut Arenas<'db> = unsafe { &mut *old_pointer };
642
643 if old_arenas.exprs.next_id() != new_value.exprs.next_id()
645 || old_arenas.patterns.next_id() != new_value.patterns.next_id()
646 || old_arenas.statements.next_id() != new_value.statements.next_id()
647 {
648 *old_arenas = new_value;
649 return true;
650 }
651 false
652 }
653}