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}
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 }
24 }
25
26 pub(crate) const fn with_lvalue(&self) -> Self {
27 Self {
28 expected_type: self.expected_type,
29 has_lvalue_target: true,
30 }
31 }
32
33 pub(crate) const fn argument(&self, expected_type: &'a TypeRef) -> Self {
34 Self {
35 expected_type: Some(expected_type),
36 has_lvalue_target: self.has_lvalue_target,
37 }
38 }
39
40 pub(crate) const fn with_argument_anything(&self) -> Self {
41 Self {
42 expected_type: None,
43 has_lvalue_target: self.has_lvalue_target,
44 }
45 }
46
47 #[must_use]
48 pub const fn new_argument(required_type: &'a TypeRef, has_lvalue_target: bool) -> Self {
49 Self {
50 expected_type: Some(required_type),
51 has_lvalue_target,
52 }
53 }
54
55 #[must_use]
56 pub const fn new_unsure_argument(
57 expected_type: Option<&'a TypeRef>,
58 has_lvalue_target: bool,
59 ) -> Self {
60 Self {
61 expected_type,
62 has_lvalue_target,
63 }
64 }
65
66 #[must_use]
67 pub const fn new_anything_argument(has_lvalue_target: bool) -> Self {
68 Self {
69 expected_type: None,
70 has_lvalue_target,
71 }
72 }
73
74 #[must_use]
75 pub fn new_function(required_type: &'a TypeRef) -> Self {
76 Self {
77 expected_type: Some(required_type),
78 has_lvalue_target: required_type.collection_view_that_needs_explicit_storage(),
79 }
80 }
81
82 #[must_use]
83 pub const fn with_expected_type(
84 &self,
85 expected_type: Option<&'a TypeRef>,
86 has_lvalue_target: bool,
87 ) -> Self {
88 Self {
89 expected_type,
90 has_lvalue_target,
91 }
92 }
93
94 pub(crate) const fn we_know_expected_type(
95 &self,
96 found_type: &'a TypeRef,
97 has_lvalue_target: bool,
98 ) -> Self {
99 self.with_expected_type(Some(found_type), has_lvalue_target)
100 }
101
102 #[must_use]
105 pub fn expected_type_or_optional_inner(&self) -> Self {
106 #[allow(clippy::bind_instead_of_map)]
107 let new_expected = self
108 .expected_type
109 .and_then(|expected| match expected.kind.as_ref() {
110 TypeKind::Optional(inner) => Some(inner),
111 _ => Some(expected),
112 });
113
114 Self {
115 expected_type: new_expected,
116 has_lvalue_target: self.has_lvalue_target,
117 }
118 }
119}