1use dada_util::{FromImpls, SalsaSerialize};
2use salsa::Update;
3use serde::Serialize;
4
5use crate::span::{Span, Spanned};
6
7use super::{AstPath, SpanVec, SpannedIdentifier};
8
9#[derive(SalsaSerialize)]
10#[salsa::tracked(debug)]
11pub struct AstTy<'db> {
12 pub span: Span<'db>,
13 pub kind: AstTyKind<'db>,
14}
15
16impl<'db> Spanned<'db> for AstTy<'db> {
17 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
18 AstTy::span(*self, db)
19 }
20}
21
22#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
23pub enum AstTyKind<'db> {
24 Perm(AstPerm<'db>, AstTy<'db>),
26
27 Named(AstPath<'db>, Option<SpanVec<'db, AstGenericTerm<'db>>>),
29
30 GenericDecl(AstGenericDecl<'db>),
32}
33
34#[derive(SalsaSerialize)]
35#[salsa::tracked(debug)]
36pub struct AstPerm<'db> {
37 pub span: Span<'db>,
38
39 #[return_ref]
40 pub kind: AstPermKind<'db>,
41}
42
43impl<'db> Spanned<'db> for AstPerm<'db> {
44 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
45 AstPerm::span(*self, db)
46 }
47}
48
49#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
50pub enum AstPermKind<'db> {
51 Referenced(Option<SpanVec<'db, AstPath<'db>>>),
53
54 Mutable(Option<SpanVec<'db, AstPath<'db>>>),
56
57 Given(Option<SpanVec<'db, AstPath<'db>>>),
59
60 My,
62
63 Our,
65
66 Variable(SpannedIdentifier<'db>),
68
69 GenericDecl(AstGenericDecl<'db>),
71}
72
73#[derive(
74 Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, FromImpls, Serialize,
75)]
76pub enum AstGenericTerm<'db> {
77 Ty(AstTy<'db>),
79
80 Perm(AstPerm<'db>),
82
83 Id(SpannedIdentifier<'db>),
85}
86
87impl<'db> Spanned<'db> for AstGenericTerm<'db> {
88 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
89 match self {
90 AstGenericTerm::Ty(ty) => ty.span(db),
91 AstGenericTerm::Perm(perm) => perm.span(db),
92 AstGenericTerm::Id(id) => id.span(db),
93 }
94 }
95}
96
97#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
98pub enum AstGenericKind<'db> {
99 Type(Span<'db>),
100 Perm(Span<'db>),
101}
102
103impl<'db> Spanned<'db> for AstGenericKind<'db> {
104 fn span(&self, _db: &'db dyn crate::Db) -> Span<'db> {
105 match self {
106 AstGenericKind::Type(span) => *span,
107 AstGenericKind::Perm(span) => *span,
108 }
109 }
110}
111
112#[derive(SalsaSerialize)]
115#[salsa::tracked(debug)]
116pub struct AstGenericDecl<'db> {
117 pub kind: AstGenericKind<'db>,
118 pub name: Option<SpannedIdentifier<'db>>,
119}
120
121impl<'db> Spanned<'db> for AstGenericDecl<'db> {
122 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
123 if let Some(name) = self.name(db) {
124 self.kind(db).span(db).to(db, name.span(db))
125 } else {
126 self.kind(db).span(db)
127 }
128 }
129}
130
131#[derive(SalsaSerialize)]
133#[salsa::tracked(debug)]
134pub struct AstWhereClauses<'db> {
135 pub where_span: Span<'db>,
137
138 #[return_ref]
140 pub clauses: SpanVec<'db, AstWhereClause<'db>>,
141}
142
143#[derive(SalsaSerialize)]
145#[salsa::tracked(debug)]
146pub struct AstWhereClause<'db> {
147 pub subject: AstGenericTerm<'db>,
148
149 #[return_ref]
150 pub kinds: SpanVec<'db, AstWhereClauseKind<'db>>,
151}
152
153#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
154pub enum AstWhereClauseKind<'db> {
155 Reference(Span<'db>),
157
158 Mutable(Span<'db>),
160
161 Shared(Span<'db>),
163
164 Unique(Span<'db>),
166
167 Owned(Span<'db>),
169
170 Lent(Span<'db>),
172}