1use crate::type_inference::kind::{GetTypeKind, TypeKind};
16use crate::{Expr, InferredType, Path, PathElem};
17use golem_wasm_ast::analysis::AnalysedType;
18use std::fmt;
19use std::fmt::Display;
20
21#[derive(Debug, Clone)]
22pub struct AmbiguousTypeError {
23 pub expr: Expr,
24 pub ambiguous_types: Vec<TypeKind>, pub additional_error_details: Vec<String>,
26}
27
28impl AmbiguousTypeError {
29 pub fn new(
30 inferred_expr: &InferredType,
31 expr: &Expr,
32 expected: &TypeKind,
33 ) -> AmbiguousTypeError {
34 let actual_kind = inferred_expr.get_type_kind();
35 match actual_kind {
36 TypeKind::Ambiguous { possibilities } => {
37 let possibilities = possibilities.into_iter().collect::<Vec<_>>();
38
39 AmbiguousTypeError {
40 expr: expr.clone(),
41 ambiguous_types: possibilities,
42 additional_error_details: vec![],
43 }
44 }
45 actual_kind => AmbiguousTypeError {
46 expr: expr.clone(),
47 ambiguous_types: vec![expected.clone(), actual_kind],
48 additional_error_details: vec![],
49 },
50 }
51 }
52
53 pub fn with_additional_error_detail(&self, detail: &str) -> AmbiguousTypeError {
54 let mut error = self.clone();
55 error.additional_error_details.push(detail.to_string());
56 error
57 }
58}
59
60pub enum InvalidPatternMatchError {
61 ConstructorMismatch {
62 predicate_expr: Expr,
63 match_expr: Expr,
64 constructor_name: String,
65 },
66 ArgSizeMismatch {
67 predicate_expr: Expr,
68 match_expr: Expr,
69 constructor_name: String,
70 expected_arg_size: usize,
71 actual_arg_size: usize,
72 },
73}
74
75impl InvalidPatternMatchError {
76 pub fn constructor_type_mismatch(
77 predicate_expr: &Expr,
78 match_expr: &Expr,
79 constructor_name: &str,
80 ) -> InvalidPatternMatchError {
81 InvalidPatternMatchError::ConstructorMismatch {
82 predicate_expr: predicate_expr.clone(),
83 match_expr: match_expr.clone(),
84 constructor_name: constructor_name.to_string(),
85 }
86 }
87
88 pub fn arg_size_mismatch(
89 predicate_expr: &Expr,
90 match_expr: &Expr,
91 constructor_name: &str,
92 expected_arg_size: usize,
93 actual_arg_size: usize,
94 ) -> InvalidPatternMatchError {
95 InvalidPatternMatchError::ArgSizeMismatch {
96 predicate_expr: predicate_expr.clone(),
97 match_expr: match_expr.clone(),
98 expected_arg_size,
99 actual_arg_size,
100 constructor_name: constructor_name.to_string(),
101 }
102 }
103}
104
105#[derive(Clone, Debug)]
106pub struct TypeMismatchError {
107 pub expr_with_wrong_type: Expr,
108 pub parent_expr: Option<Expr>,
109 pub expected_type: ExpectedType,
110 pub actual_type: ActualType,
111 pub field_path: Path,
112 pub additional_error_detail: Vec<String>,
113}
114
115#[derive(Clone, Debug)]
116pub enum ExpectedType {
117 AnalysedType(AnalysedType),
118 Kind(TypeKind),
119}
120
121#[derive(Clone, Debug)]
123pub enum ActualType {
124 Inferred(InferredType),
125 Kind(TypeKind),
126}
127
128impl TypeMismatchError {
129 pub fn updated_expected_type(&self, expected_type: &AnalysedType) -> TypeMismatchError {
130 let mut mismatch_error: TypeMismatchError = self.clone();
131 mismatch_error.expected_type = ExpectedType::AnalysedType(expected_type.clone());
132 mismatch_error
133 }
134
135 pub fn at_field(&self, field_name: String) -> TypeMismatchError {
136 let mut mismatch_error: TypeMismatchError = self.clone();
137 mismatch_error
138 .field_path
139 .push_front(PathElem::Field(field_name));
140 mismatch_error
141 }
142
143 pub fn with_actual_inferred_type(
144 expr: &Expr,
145 parent_expr: Option<&Expr>,
146 expected_type: AnalysedType,
147 actual_type: InferredType,
148 ) -> Self {
149 TypeMismatchError {
150 expr_with_wrong_type: expr.clone(),
151 parent_expr: parent_expr.cloned(),
152 expected_type: ExpectedType::AnalysedType(expected_type),
153 actual_type: ActualType::Inferred(actual_type),
154 field_path: Path::default(),
155 additional_error_detail: Vec::new(),
156 }
157 }
158
159 pub fn with_actual_type_kind(
160 expr: &Expr,
161 parent_expr: Option<&Expr>,
162 expected_type: AnalysedType,
163 actual_type: &TypeKind,
164 ) -> Self {
165 TypeMismatchError {
166 expr_with_wrong_type: expr.clone(),
167 parent_expr: parent_expr.cloned(),
168 expected_type: ExpectedType::AnalysedType(expected_type),
169 actual_type: ActualType::Kind(actual_type.clone()),
170 field_path: Path::default(),
171 additional_error_detail: Vec::new(),
172 }
173 }
174}
175
176pub struct MultipleUnResolvedTypesError(pub Vec<UnResolvedTypesError>);
177
178#[derive(Clone)]
179pub struct UnResolvedTypesError {
180 pub unresolved_expr: Expr,
181 pub parent_expr: Option<Expr>,
182 pub additional_messages: Vec<String>,
183 pub help_messages: Vec<String>,
184 pub path: Path,
185}
186
187impl UnResolvedTypesError {
188 pub fn from(expr: &Expr, parent_expr: Option<Expr>) -> Self {
189 let unresolved_types = UnResolvedTypesError {
190 unresolved_expr: expr.clone(),
191 additional_messages: Vec::new(),
192 parent_expr: parent_expr.clone(),
193 help_messages: Vec::new(),
194 path: Path::default(),
195 };
196
197 unresolved_types.with_default_help_messages()
198 }
199
200 pub fn with_default_help_messages(&self) -> Self {
201 self.with_help_message(
202 "consider specifying the type explicitly. Examples: `1: u64`, `person.age: u8`",
203 )
204 .with_help_message(
205 "or specify the type in let binding. Example: let numbers: list<u8> = [1, 2, 3]",
206 )
207 }
208
209 pub fn with_parent_expr(&self, expr: &Expr) -> UnResolvedTypesError {
210 let mut unresolved_error: UnResolvedTypesError = self.clone();
211 unresolved_error.parent_expr = Some(expr.clone());
212 unresolved_error
213 }
214
215 pub fn with_additional_error_detail(&self, message: impl AsRef<str>) -> UnResolvedTypesError {
216 let mut unresolved_error: UnResolvedTypesError = self.clone();
217 unresolved_error
218 .additional_messages
219 .push(message.as_ref().to_string());
220 unresolved_error
221 }
222
223 pub fn with_help_message(&self, message: impl AsRef<str>) -> UnResolvedTypesError {
224 let mut unresolved_error: UnResolvedTypesError = self.clone();
225 unresolved_error
226 .help_messages
227 .push(message.as_ref().to_string());
228
229 unresolved_error
230 }
231
232 pub fn at_field(&self, field_name: String) -> UnResolvedTypesError {
233 let mut unresolved_error: UnResolvedTypesError = self.clone();
234 unresolved_error
235 .path
236 .push_front(PathElem::Field(field_name));
237 unresolved_error
238 }
239
240 pub fn at_index(&self, index: usize) -> UnResolvedTypesError {
241 let mut unresolved_error: UnResolvedTypesError = self.clone();
242 unresolved_error.path.push_front(PathElem::Index(index));
243 unresolved_error
244 }
245}
246
247impl Display for UnResolvedTypesError {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 let span = self.unresolved_expr.source_span();
250
251 writeln!(
252 f,
253 "cannot determine the type of the following rib expression found at line {}, column {}",
254 span.start_line(),
255 span.start_column()
256 )?;
257
258 writeln!(f, "`{}`", self.unresolved_expr)?;
259
260 if let Some(parent) = &self.parent_expr {
261 writeln!(f, "found within:")?;
262 writeln!(f, "`{}`", parent)?;
263 }
264
265 if !self.additional_messages.is_empty() {
266 for message in &self.additional_messages {
267 writeln!(f, "{}", message)?;
268 }
269 }
270
271 Ok(())
272 }
273}
274
275pub enum FunctionCallError {
276 InvalidFunctionCall {
277 function_name: String,
278 expr: Expr,
279 message: String,
280 },
281 TypeMisMatch {
282 function_name: String,
283 argument: Expr,
284 error: TypeMismatchError,
285 },
286 MissingRecordFields {
287 function_name: String,
288 argument: Expr,
289 missing_fields: Vec<Path>,
290 },
291 UnResolvedTypes {
292 function_name: String,
293 argument: Expr,
294 unresolved_error: UnResolvedTypesError,
295 expected_type: AnalysedType,
296 },
297
298 InvalidResourceMethodCall {
299 resource_method_name: String,
300 invalid_lhs: Expr,
301 },
302
303 InvalidGenericTypeParameter {
304 generic_type_parameter: String,
305 expr: Expr,
306 message: String,
307 },
308
309 ArgumentSizeMisMatch {
310 function_name: String,
311 expr: Expr,
312 expected: usize,
313 provided: usize,
314 },
315}
316
317pub struct InvalidWorkerName {
318 pub worker_name_expr: Expr,
319 pub message: String,
320}
321
322#[derive(Clone)]
323pub struct CustomError {
324 pub expr: Expr,
325 pub message: String,
326 pub help_message: Vec<String>,
327}
328
329impl CustomError {
330 pub fn new(expr: &Expr, message: impl AsRef<str>) -> CustomError {
331 CustomError {
332 expr: expr.clone(),
333 message: message.as_ref().to_string(),
334 help_message: Vec::new(),
335 }
336 }
337
338 pub fn with_help_message(&self, message: impl AsRef<str>) -> CustomError {
339 let mut custom_error: CustomError = self.clone();
340 custom_error.help_message.push(message.as_ref().to_string());
341 custom_error
342 }
343}