Skip to main content

dada_ir_ast/ast/
types.rs

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 $Ty`, e.g., `shared String`
25    Perm(AstPerm<'db>, AstTy<'db>),
26
27    /// `path[arg1, arg2]`, e.g., `Vec[String]`
28    Named(AstPath<'db>, Option<SpanVec<'db, AstGenericTerm<'db>>>),
29
30    /// `type T`
31    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    /// User wrote `ref` or `ref[place1, place2]`
52    Referenced(Option<SpanVec<'db, AstPath<'db>>>),
53
54    /// User wrote `mutable` or `mutable[place1, place2]`
55    Mutable(Option<SpanVec<'db, AstPath<'db>>>),
56
57    /// User wrote `given` or `given[place1, place2]`
58    Given(Option<SpanVec<'db, AstPath<'db>>>),
59
60    /// User wrote `my`
61    My,
62
63    /// User wrote `our`
64    Our,
65
66    /// User wrote `P`
67    Variable(SpannedIdentifier<'db>),
68
69    /// User wrote `perm P`
70    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    /// Something clearly a type
78    Ty(AstTy<'db>),
79
80    /// Something clearly a permission
81    Perm(AstPerm<'db>),
82
83    /// A single identifier is ambiguous and must be disambiguated by the type checker
84    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/// `type T? (: bounds)?`
113/// `perm T? (: bounds)?`
114#[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/// Looks like `where WC1, ... WC2,`
132#[derive(SalsaSerialize)]
133#[salsa::tracked(debug)]
134pub struct AstWhereClauses<'db> {
135    /// Span of the where-clause keyword.
136    pub where_span: Span<'db>,
137
138    /// List of clauses that came after the keyword.
139    #[return_ref]
140    pub clauses: SpanVec<'db, AstWhereClause<'db>>,
141}
142
143/// A where-clause looks like `A is shared`, `A is lent`, `A is shared + lent`, etc.
144#[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    /// `ref`
156    Reference(Span<'db>),
157
158    /// `mut`
159    Mutable(Span<'db>),
160
161    /// `shared`
162    Shared(Span<'db>),
163
164    /// `unique`
165    Unique(Span<'db>),
166
167    /// `owned`
168    Owned(Span<'db>),
169
170    /// `lent`
171    Lent(Span<'db>),
172}