sway_core/has_changes.rs
1/// Reports whether an operation that mutates declarations ([`crate::language::ty::TyDecl`]),
2/// type ids ([`crate::TypeId`]), or other entities in place actually changed anything.
3///
4/// It is used to propagate "did anything change" information across various
5/// in-place transformations, e.g., [`crate::SubstTypes`], declaration replacement,
6/// monomorphization, etc.
7#[derive(Default)]
8pub enum HasChanges {
9 Yes,
10 #[default]
11 No,
12}
13
14impl HasChanges {
15 pub fn has_changes(&self) -> bool {
16 matches!(self, HasChanges::Yes)
17 }
18}
19
20impl std::ops::BitOr for HasChanges {
21 type Output = HasChanges;
22
23 fn bitor(self, rhs: Self) -> Self::Output {
24 match (self, rhs) {
25 (HasChanges::No, HasChanges::No) => HasChanges::No,
26 _ => HasChanges::Yes,
27 }
28 }
29}
30
31impl std::ops::BitOrAssign for HasChanges {
32 fn bitor_assign(&mut self, rhs: Self) {
33 if rhs.has_changes() {
34 *self = HasChanges::Yes;
35 }
36 }
37}
38
39impl From<bool> for HasChanges {
40 fn from(value: bool) -> Self {
41 if value {
42 HasChanges::Yes
43 } else {
44 HasChanges::No
45 }
46 }
47}
48
49#[macro_export]
50macro_rules! has_changes {
51 ($($stmt:expr);* ;) => {{
52 let mut has_changes = $crate::HasChanges::No;
53 $(
54 has_changes |= $stmt;
55 )*
56 has_changes
57 }};
58}
59
60/// Like [`has_changes!`], but for use inside a [`sway_error::handler::Handler::scope`].
61///
62/// Each statement must evaluate to a `Result<HasChanges, ErrorEmitted>`. Errors are
63/// swallowed instead of short-circuiting: they remain captured by the enclosing scope,
64/// which will still report them, so every statement runs and independent sub-operations
65/// each get to emit their diagnostics.
66///
67/// Use this only inside a `Handler::scope` (or with a scope up the call stack). Outside a
68/// scope, a swallowed error would be lost from the returned `Result` even though it was
69/// emitted.
70#[macro_export]
71macro_rules! has_changes_scoped {
72 ($($stmt:expr);* ;) => {{
73 let mut has_changes = $crate::HasChanges::No;
74 $(
75 if let Ok(r) = $stmt {
76 has_changes |= r;
77 }
78 )*
79 has_changes
80 }};
81}