chomsky_uir/
constraint.rs1use crate::egraph::HasDebugInfo;
2use chomsky_types::Loc;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
6pub enum Effect {
7 Pure,
8 ReadOnly,
9 WriteOnly,
10 ReadWrite,
11 Panic,
12 Diverge,
13}
14
15impl Effect {
16 pub fn join(&self, other: &Self) -> Self {
17 match (self, other) {
18 (Effect::Diverge, _) | (_, Effect::Diverge) => Effect::Diverge,
19 (Effect::Panic, _) | (_, Effect::Panic) => Effect::Panic,
20 (Effect::ReadWrite, _) | (_, Effect::ReadWrite) => Effect::ReadWrite,
21 (Effect::WriteOnly, Effect::ReadOnly) | (Effect::ReadOnly, Effect::WriteOnly) => {
22 Effect::ReadWrite
23 }
24 (Effect::WriteOnly, _) | (_, Effect::WriteOnly) => Effect::WriteOnly,
25 (Effect::ReadOnly, _) | (_, Effect::ReadOnly) => Effect::ReadOnly,
26 (Effect::Pure, other) => *other,
27 }
28 }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
32pub enum Ownership {
33 Borrowed,
34 Owned,
35 Shared,
36 Linear,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
40pub enum Constraint {
41 Effect(Effect),
42 Ownership(Ownership),
43 Atomic,
44 Type(String),
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
48pub struct ConstraintSet {
49 pub effect: Effect,
50 pub ownership: Option<Ownership>,
51 pub is_atomic: bool,
52 pub r#type: Option<String>,
53}
54
55impl Default for ConstraintSet {
56 fn default() -> Self {
57 Self {
58 effect: Effect::Pure,
59 ownership: None,
60 is_atomic: false,
61 r#type: None,
62 }
63 }
64}
65
66impl ConstraintSet {
67 pub fn merge(&mut self, other: &Self) -> bool {
68 let mut changed = false;
69
70 let new_effect = self.effect.join(&other.effect);
71 if new_effect != self.effect {
72 self.effect = new_effect;
73 changed = true;
74 }
75
76 if let Some(o) = &other.ownership {
77 if self.ownership.as_ref() != Some(o) {
78 if self.ownership.is_none() {
79 self.ownership = Some(*o);
80 changed = true;
81 }
82 }
83 }
84
85 if other.is_atomic && !self.is_atomic {
86 self.is_atomic = true;
87 changed = true;
88 }
89
90 if let Some(t) = &other.r#type {
91 if self.r#type.as_ref() != Some(t) {
92 if self.r#type.is_none() {
93 self.r#type = Some(t.clone());
94 changed = true;
95 }
96 }
97 }
98
99 changed
100 }
101}
102
103impl HasDebugInfo for ConstraintSet {
104 fn get_locs(&self) -> &[Loc] {
105 &[]
106 }
107}
108
109impl ConstraintSet {
110 pub fn check_conflict(&self, other: &Self) -> Option<String> {
111 if let (Some(o1), Some(o2)) = (&self.ownership, &other.ownership) {
113 if o1 != o2 {
114 return Some(format!("Ownership conflict: {:?} vs {:?}", o1, o2));
115 }
116 }
117
118 if let (Some(t1), Some(t2)) = (&self.r#type, &other.r#type) {
120 if t1 != t2 {
121 return Some(format!("Type conflict: {} vs {}", t1, t2));
122 }
123 }
124
125 None
126 }
127
128 pub fn can_merge(&self, other: &Self) -> bool {
129 self.check_conflict(other).is_none()
130 }
131}