dada_ir_sym/ir/
variables.rs1use dada_ir_ast::{
2 ast::{AstFunctionInput, AstSelfArg, Identifier, VariableDecl},
3 span::{Span, Spanned},
4};
5use dada_util::SalsaSerialize;
6
7use crate::{
8 check::scope::Scope,
9 ir::types::{SymGenericKind, SymGenericTerm},
10 prelude::Symbol,
11};
12
13use super::types::HasKind;
14
15#[derive(SalsaSerialize)]
17#[salsa::tracked(debug)]
18pub struct SymVariable<'db> {
19 pub kind: SymGenericKind,
20 pub name: Option<Identifier<'db>>,
21 pub span: Span<'db>,
22}
23
24impl<'db> SymVariable<'db> {
25 pub fn new_local(db: &'db dyn crate::Db, id: Identifier<'db>, span: Span<'db>) -> Self {
27 Self::new(db, SymGenericKind::Place, Some(id), span)
28 }
29
30 pub fn into_generic_term(
31 self,
32 db: &'db dyn crate::Db,
33 scope: &Scope<'_, 'db>,
34 ) -> SymGenericTerm<'db> {
35 assert!(
36 scope.generic_sym_in_scope(db, self),
37 "generic symbol for `{self:?}` not in scope"
38 );
39 SymGenericTerm::var(db, self)
40 }
41}
42
43impl<'db> HasKind<'db> for SymVariable<'db> {
44 fn has_kind(&self, db: &'db dyn crate::Db, kind: SymGenericKind) -> bool {
45 self.kind(db) == kind
46 }
47}
48
49impl<'db> Spanned<'db> for SymVariable<'db> {
50 fn span(&self, db: &'db dyn dada_ir_ast::Db) -> Span<'db> {
51 SymVariable::span(*self, db)
52 }
53}
54
55impl std::fmt::Display for SymVariable<'_> {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 salsa::with_attached_database(|db| match self.name(db) {
58 Some(name) => write!(f, "{name}"),
59 None => write!(f, "{kind}", kind = self.kind(db)),
60 })
61 .unwrap_or_else(|| std::fmt::Debug::fmt(self, f))
62 }
63}
64
65pub trait FromVar<'db> {
67 fn var(db: &'db dyn crate::Db, var: SymVariable<'db>) -> Self;
68}
69
70impl<'db> Symbol<'db> for AstFunctionInput<'db> {
71 type Output = SymVariable<'db>;
72
73 fn symbol(self, db: &'db dyn crate::Db) -> SymVariable<'db> {
74 match self {
75 AstFunctionInput::SelfArg(ast_self_arg) => ast_self_arg.symbol(db),
76 AstFunctionInput::Variable(variable_decl) => variable_decl.symbol(db),
77 }
78 }
79}
80
81#[salsa::tracked]
82impl<'db> Symbol<'db> for VariableDecl<'db> {
83 type Output = SymVariable<'db>;
84
85 #[salsa::tracked]
86 fn symbol(self, db: &'db dyn crate::Db) -> SymVariable<'db> {
87 SymVariable::new(
88 db,
89 SymGenericKind::Place,
90 Some(self.name(db).id),
91 self.name(db).span,
92 )
93 }
94}
95
96#[salsa::tracked]
97impl<'db> Symbol<'db> for AstSelfArg<'db> {
98 type Output = SymVariable<'db>;
99
100 #[salsa::tracked]
101 fn symbol(self, db: &'db dyn crate::Db) -> SymVariable<'db> {
102 SymVariable::new(
103 db,
104 SymGenericKind::Place,
105 Some(Identifier::self_ident(db)),
106 self.self_span(db),
107 )
108 }
109}