swamp_analyzer/
context.rs1use swamp_types::{TypeKind, TypeRef};
7
8#[derive(Debug, Clone)]
10pub struct TypeContext<'a> {
11 pub expected_type: Option<&'a TypeRef>,
13 pub has_lvalue_target: bool,
14 pub ephemeral_is_allowed: bool,
15}
16
17impl<'a> TypeContext<'a> {
18 #[must_use]
19 pub const fn new(expected_type: Option<&'a TypeRef>, has_lvalue_target: bool) -> Self {
20 Self {
21 expected_type,
22 has_lvalue_target,
23 ephemeral_is_allowed: false,
24 }
25 }
26
27 pub(crate) const fn with_lvalue(&self) -> Self {
28 Self {
29 expected_type: self.expected_type,
30 has_lvalue_target: true,
31 ephemeral_is_allowed: false,
32 }
33 }
34
35 pub(crate) const fn with_ephemeral(&self) -> TypeContext {
36 Self {
37 expected_type: self.expected_type,
38 has_lvalue_target: self.has_lvalue_target,
39 ephemeral_is_allowed: true,
40 }
41 }
42
43 pub(crate) const fn argument(&self, expected_type: &'a TypeRef) -> Self {
44 Self {
45 expected_type: Some(expected_type),
46 has_lvalue_target: self.has_lvalue_target,
47 ephemeral_is_allowed: false,
48 }
49 }
50
51 pub(crate) const fn with_argument_anything(&self) -> Self {
52 Self {
53 expected_type: None,
54 has_lvalue_target: self.has_lvalue_target,
55 ephemeral_is_allowed: false,
56 }
57 }
58
59 #[must_use]
60 pub const fn new_argument(required_type: &'a TypeRef, has_lvalue_target: bool) -> Self {
61 Self {
62 expected_type: Some(required_type),
63 has_lvalue_target,
64 ephemeral_is_allowed: false,
65 }
66 }
67
68 pub(crate) const fn new_argument_ephemeral(
69 required_type: &'a TypeRef,
70 has_lvalue_target: bool,
71 ) -> Self {
72 Self {
73 expected_type: Some(required_type),
74 has_lvalue_target,
75 ephemeral_is_allowed: true,
76 }
77 }
78
79 #[must_use]
80 pub const fn new_unsure_argument(
81 expected_type: Option<&'a TypeRef>,
82 has_lvalue_target: bool,
83 ) -> Self {
84 Self {
85 expected_type,
86 has_lvalue_target,
87 ephemeral_is_allowed: false,
88 }
89 }
90
91 #[must_use]
92 pub const fn new_anything_argument(has_lvalue_target: bool) -> Self {
93 Self {
94 expected_type: None,
95 has_lvalue_target,
96 ephemeral_is_allowed: false,
97 }
98 }
99
100 #[must_use]
101 pub fn new_function(required_type: &'a TypeRef) -> Self {
102 Self {
103 expected_type: Some(required_type),
104 has_lvalue_target: required_type.collection_view_that_needs_explicit_storage(),
105 ephemeral_is_allowed: false,
106 }
107 }
108
109 #[must_use]
110 pub const fn with_expected_type(
111 &self,
112 expected_type: Option<&'a TypeRef>,
113 has_lvalue_target: bool,
114 ) -> Self {
115 Self {
116 expected_type,
117 has_lvalue_target,
118 ephemeral_is_allowed: false,
119 }
120 }
121
122 pub(crate) const fn we_know_expected_type(
123 &self,
124 found_type: &'a TypeRef,
125 has_lvalue_target: bool,
126 ) -> Self {
127 self.with_expected_type(Some(found_type), has_lvalue_target)
128 }
129
130 #[must_use]
133 pub fn expected_type_or_optional_inner(&self) -> Self {
134 #[allow(clippy::bind_instead_of_map)]
135 let new_expected = self
136 .expected_type
137 .and_then(|expected| match expected.kind.as_ref() {
138 TypeKind::Optional(inner) => Some(inner),
139 _ => Some(expected),
140 });
141
142 Self {
143 expected_type: new_expected,
144 has_lvalue_target: self.has_lvalue_target,
145 ephemeral_is_allowed: false,
146 }
147 }
148}