ryna/
checks.rs

1use std::collections::{HashSet, HashMap};
2
3use colored::Colorize;
4use rustc_hash::FxHashSet;
5
6use crate::annotations::Annotation;
7use crate::compilation::RynaError;
8use crate::context::RynaContext;
9use crate::formats::{check_class_name, check_fn_name, check_interface_name, check_template_name};
10use crate::{located_ryna_warning, ryna_error};
11use crate::parser::{RynaExpr, Location};
12use crate::operations::Operator;
13use crate::types::{Type, BOOL};
14use crate::patterns::Pattern;
15
16/*
17                                                  ╒══════════════════╕
18    ============================================= │  IMPLEMENTATION  │ =============================================
19                                                  ╘══════════════════╛
20*/
21
22impl RynaContext {
23    pub fn check_forbidden_fn_names(name: &String) {
24        let forbidden_names = ["move", "fwd", "cfwd", "demut", "deref", "ref", "mut", "as", "is", "swap"];
25
26        for i in forbidden_names {
27            if i == name {
28                ryna_error!("Defining function overloads for {} is forbidden", i.green());
29            }
30        } 
31    }
32
33    pub fn ensured_return_check(expr: &RynaExpr) -> Result<(), RynaError> {
34        match expr {
35            RynaExpr::PrefixOperationDefinition(l, _, _, _, _, _, _, body) |
36            RynaExpr::PostfixOperationDefinition(l, _, _, _, _, _, _, body) |
37            RynaExpr::BinaryOperationDefinition(l, _, _, _, _, _, _, body) |
38            RynaExpr::NaryOperationDefinition(l, _, _, _, _, _, _, body)  => RynaContext::ensured_return_check_body(body, l, "Operation"),
39
40            RynaExpr::CompiledLambda(l, _, _, _, _, body) |
41            RynaExpr::FunctionDefinition(l, _, _, _, _, _, body) => RynaContext::ensured_return_check_body(body, l, "Function"),
42
43            RynaExpr::DoBlock(l, body, _) => RynaContext::ensured_return_check_body(body, l, "Do block"),
44
45            _ => Ok(())
46        }
47    }
48
49    pub fn ensured_return_check_body(lines: &Vec<RynaExpr>, l: &Location, instance: &str) -> Result<(), RynaError> {
50        for line in lines {
51            match line {
52                RynaExpr::Return(_, _) => return Ok(()),
53
54                RynaExpr::If(_, _, ib, ei, Some(eb_inner)) => {
55                    let mut returns = RynaContext::ensured_return_check_body(ib, l, instance).is_ok() && 
56                                      RynaContext::ensured_return_check_body(eb_inner, l, instance).is_ok();
57
58                    if returns { // Check every branch
59                        for (_, ei_b) in ei {
60                            if RynaContext::ensured_return_check_body(ei_b, l, instance).is_err() {
61                                returns = false;
62                                break;
63                            }
64                        }
65                    }
66
67                    if returns {
68                        return Ok(());
69                    }
70                }
71
72                _ => {}
73            }
74        }
75        
76        Err(RynaError::compiler_error(format!("{instance} may not always return a value"), l, vec!()))
77    }
78
79    pub fn return_check(&self, expr: &RynaExpr, ret_type: &Option<Type>) -> Result<(), RynaError> {
80        match (expr, ret_type) {
81            (RynaExpr::Break(..), _) |
82            (RynaExpr::Continue(..), _) |
83            (RynaExpr::Literal(..), _) |
84            (RynaExpr::Tuple(..), _) |
85            (RynaExpr::Variable(..), _) |
86            (RynaExpr::UnaryOperation(..), _) |
87            (RynaExpr::BinaryOperation(..), _) |
88            (RynaExpr::NaryOperation(..), _) |
89            (RynaExpr::FunctionCall(..), _) |
90            (RynaExpr::AttributeAccess(..), _) |
91            (RynaExpr::AttributeAssignment(..), _) |
92            (RynaExpr::PrefixOperatorDefinition(..), _) |
93            (RynaExpr::PostfixOperatorDefinition(..), _) |
94            (RynaExpr::BinaryOperatorDefinition(..), _) |
95            (RynaExpr::NaryOperatorDefinition(..), _) |
96            (RynaExpr::InterfaceDefinition(..), _) |
97            (RynaExpr::InterfaceImplementation(..), _) |
98            (RynaExpr::ClassDefinition(..), _) => Ok(()),
99
100            (RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _), _) |
101            (RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _), _) => self.return_check(e, &None),
102
103            (RynaExpr::Return(l, _), None) => {
104                Err(RynaError::compiler_error(
105                    "Return statements are only allowed inside function and operation definition bodies".into(), 
106                    l, vec!()
107                ))
108            },
109
110            (RynaExpr::Return(l, e), Some(expected_t)) => {
111                self.return_check(e, ret_type)?;
112                let t = self.infer_type(e)?;
113
114                if t.bindable_to(expected_t, self) {
115                    Ok(())
116
117                } else {
118                    Err(RynaError::compiler_error(
119                        format!("Value of type {} is not bindable to expected return value of type {}", t.get_name(self), expected_t.get_name(self)), 
120                        l, vec!()
121                    ))
122                }
123            },
124
125            (RynaExpr::FunctionDefinition(_, _, _, t, _, ret, body), None) |
126            (RynaExpr::PrefixOperationDefinition(_, _, _, t, _, _, ret, body), None) |
127            (RynaExpr::PostfixOperationDefinition(_, _, _, t, _, _, ret, body), None) |
128            (RynaExpr::BinaryOperationDefinition(_, _, _, t, _, _, ret, body), None) |
129            (RynaExpr::NaryOperationDefinition(_, _, _, t, _, _, ret, body), None) => {
130                if t.is_empty() {
131                    let expected_ret = Some(ret.clone());
132
133                    for line in body {
134                        self.return_check(line, &expected_ret)?;
135                    }
136                }
137
138                RynaContext::ensured_return_check(expr)
139            }
140
141            (RynaExpr::CompiledLambda(_, _, _, _, ret, body), _) => {
142                let expected_ret = Some(ret.clone());
143
144                for line in body {
145                    self.return_check(line, &expected_ret)?;
146                }
147
148                self.repeated_arguments_check(expr)?;
149                self.lambda_check(expr)?;
150                RynaContext::ensured_return_check(expr)
151            }
152
153            (RynaExpr::DoBlock(_, body, ret), _) => {
154                let expected_ret = Some(ret.clone());
155
156                for line in body {
157                    self.return_check(line, &expected_ret)?;
158                }
159
160                RynaContext::ensured_return_check(expr)
161            }
162
163            (RynaExpr::While(_, cond, body), ret) |
164            (RynaExpr::CompiledFor(_, _, _, _, cond, body), ret) => {
165                self.return_check(cond, ret)?;
166
167                for line in body {
168                    self.return_check(line, ret)?;
169                }
170
171                Ok(())
172            },
173
174            (RynaExpr::If(_, ih, ib, ei, eb), ret) => {
175                self.return_check(ih, ret)?;
176
177                for line in ib {
178                    self.return_check(line, ret)?;
179                }
180
181                for (ei_h, ei_b) in ei {
182                    self.return_check(ei_h, ret)?;
183
184                    for line in ei_b {
185                        self.return_check(line, ret)?;
186                    }
187                }
188
189                if let Some(eb_inner) = eb {
190                    for line in eb_inner {
191                        self.return_check(line, ret)?;
192                    }
193                }
194
195                Ok(())
196            },
197
198            (RynaExpr::Macro(..), _) => { Ok(()) },
199
200            _ => unimplemented!("{:?}", expr)
201        }
202    }
203
204    pub fn ambiguity_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
205        return match expr {
206            RynaExpr::Break(..) |
207            RynaExpr::Continue(..) |
208            RynaExpr::Literal(..) |
209            RynaExpr::Variable(..) |
210            RynaExpr::PrefixOperatorDefinition(..) |
211            RynaExpr::PostfixOperatorDefinition(..) |
212            RynaExpr::BinaryOperatorDefinition(..) |
213            RynaExpr::NaryOperatorDefinition(..) |
214            RynaExpr::InterfaceDefinition(..) |
215            RynaExpr::InterfaceImplementation(..) |
216            RynaExpr::ClassDefinition(..) => Ok(()),
217
218            RynaExpr::DoBlock(_, body, _) |
219            RynaExpr::CompiledLambda(_, _, _, _, _, body) |
220            RynaExpr::Tuple(_, body) => {
221                for line in body {
222                    self.ambiguity_check(line)?;
223                }
224
225                Ok(())
226            }
227
228            RynaExpr::FunctionCall(l, id, _ , args) => {
229                let mut arg_types = Vec::with_capacity(args.len());
230
231                for arg in args.iter() {
232                    self.ambiguity_check(arg)?;
233
234                    let t = self.infer_type(arg)?;
235                    arg_types.push(t);
236                }
237
238                if let Some(ov) = self.is_function_overload_ambiguous(*id, arg_types.clone()) {
239                    let f_name = &self.functions[*id].name;
240                    let possibilities = ov.iter().map(|(a, r)| format!("{}{} -> {}", f_name, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
241                    
242                    Err(RynaError::compiler_error(
243                        format!(
244                            "Function call {}({}) is ambiguous",
245                            f_name.green(),
246                            arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")
247                        ), l,
248                        possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
249                    ))
250
251                } else {
252                    Ok(())
253                }
254            },
255
256            RynaExpr::UnaryOperation(l, id, _, arg) => {
257                self.ambiguity_check(arg)?;
258                let t = self.infer_type(arg)?;
259
260                if let Some(ov) = self.is_unary_op_ambiguous(*id, t.clone()) {
261                    if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*id] {
262                        if *prefix {
263                            let possibilities = ov.iter().map(|(a, r)| format!("{}({}) -> {}", representation, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
264                            
265                            Err(RynaError::compiler_error(
266                                format!(
267                                    "Unary operation {}({}) is ambiguous",
268                                    representation,
269                                    t.get_name(self)
270                                ), l, 
271                                possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
272                            ))
273
274                        } else {
275                            let possibilities = ov.iter().map(|(a, r)| format!("({}){} -> {}", a.get_name(self), representation, r.get_name(self))).collect::<Vec<_>>();
276        
277                            Err(RynaError::compiler_error(
278                                format!(
279                                    "Unary operation ({}){} is ambiguous",
280                                    t.get_name(self),
281                                    representation
282                                ), l, 
283                                possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
284                            ))
285                        }
286                        
287                    } else {
288                        unreachable!();
289                    }
290
291                } else {
292                    Ok(())
293                }
294            },
295
296            RynaExpr::BinaryOperation(l, id, _, arg1, arg2) => {
297                self.ambiguity_check(arg1)?;
298                self.ambiguity_check(arg2)?;
299
300                let t1 = self.infer_type(arg1)?;
301                let t2 = self.infer_type(arg2)?;
302                
303                if let Some(ov) = self.is_binary_op_ambiguous(*id, t1.clone(), t2.clone()) {
304                    if let Operator::Binary{representation, ..} = &self.binary_ops[*id] {
305                        let possibilities = ov.iter()
306                            .map(|(a1, a2, r)| format!("({}){}({}) -> {}", a1.get_name(self), representation, a2.get_name(self), r.get_name(self)))
307                            .collect::<Vec<_>>();                
308                        
309                        Err(RynaError::compiler_error(
310                            format!(
311                                "Binary operation ({}){}({}) is ambiguous",
312                                t1.get_name(self),
313                                representation, 
314                                t2.get_name(self)
315                            ), l, 
316                            possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
317                        ))
318
319                    } else {
320                        unreachable!();
321                    }
322
323                } else {
324                    Ok(())
325                }
326            },
327
328            RynaExpr::NaryOperation(l, id, _, first, args) => {
329                self.ambiguity_check(first)?;
330                let t = self.infer_type(first)?;
331
332                let mut arg_types = Vec::with_capacity(args.len());
333
334                for arg in args.iter() {
335                    self.ambiguity_check(arg)?;
336                    arg_types.push(self.infer_type(arg)?);
337                }
338
339                if let Some(ov) = self.is_nary_op_ambiguous(*id, t.clone(), arg_types.clone()) {
340                    if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*id] {
341                        let possibilities = ov.iter()
342                            .map(|(f, a, r)| 
343                                format!(
344                                    "{}{}{}{} -> {}", 
345                                    f.get_name(self), 
346                                    open_rep,
347                                    a.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
348                                    close_rep,
349                                    r.get_name(self)
350                                )
351                            )
352                            .collect::<Vec<_>>();
353                        
354                        Err(RynaError::compiler_error(
355                            format!(
356                                "N-ary operation {}{}{}{} is ambiguous",
357                                t.get_name(self), 
358                                open_rep,
359                                arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
360                                close_rep
361                            ), l, 
362                            possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
363                        ))
364
365                    } else {
366                        unreachable!()
367                    }
368
369                } else {
370                    Ok(())
371                }
372            },
373
374            RynaExpr::If(_, ih, ib, ei, eb) => {
375                self.ambiguity_check(ih)?;
376
377                for line in ib {
378                    self.ambiguity_check(line)?;
379                }
380
381                for (ei_h, ei_b) in ei {
382                    self.ambiguity_check(ei_h)?;
383
384                    for line in ei_b {
385                        self.ambiguity_check(line)?;
386                    }
387                }
388
389                if let Some(eb_inner) = eb {
390                    for line in eb_inner {
391                        self.ambiguity_check(line)?;
392                    }
393                }
394
395                Ok(())
396            },
397
398            RynaExpr::While(_, cond, body) => {
399                self.ambiguity_check(cond)?;
400
401                for line in body {
402                    self.ambiguity_check(line)?;
403                }
404
405                Ok(())
406            },
407
408            RynaExpr::AttributeAssignment(_, a, b, _) => {
409                self.ambiguity_check(a)?;
410                self.ambiguity_check(b)
411            }
412
413            RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _) |
414            RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _) |
415            RynaExpr::AttributeAccess(_, e, _) |
416            RynaExpr::Return(_, e) => {
417                self.ambiguity_check(e)?;
418                self.infer_type(e)?;
419
420                Ok(())
421            }
422
423            RynaExpr::PrefixOperationDefinition(_, _, _, t, _, _, _, b) |
424            RynaExpr::PostfixOperationDefinition(_, _, _, t, _, _, _, b) |
425            RynaExpr::BinaryOperationDefinition(_, _, _, t, _, _, _, b) |
426            RynaExpr::NaryOperationDefinition(_, _, _, t, _, _, _, b) |
427            RynaExpr::FunctionDefinition(_, _, _, t, _, _, b) => {
428                if t.is_empty() {
429                    for line in b {
430                        self.ambiguity_check(line)?;
431                    }
432                }
433
434                Ok(())
435            },
436
437            RynaExpr::CompiledFor(_, _, _, _, _, b) => {
438                for line in b {
439                    self.ambiguity_check(line)?;
440                }
441
442                Ok(())
443            }
444
445            RynaExpr::Macro(..) => { Ok(()) },
446
447            _ => unimplemented!("{:?}", expr)
448        }
449    }
450
451    pub fn break_continue_check(expr: &RynaExpr, allowed: bool) -> Result<(), RynaError> {
452        return match expr {
453            RynaExpr::ClassDefinition(..) |
454            RynaExpr::InterfaceImplementation(..) |
455            RynaExpr::PrefixOperatorDefinition(..) |
456            RynaExpr::PostfixOperatorDefinition(..) |
457            RynaExpr::BinaryOperatorDefinition(..) |
458            RynaExpr::NaryOperatorDefinition(..) |
459            RynaExpr::InterfaceDefinition(..) |
460            RynaExpr::Macro(..) |
461            RynaExpr::Variable(..) |
462            RynaExpr::Literal(..) => Ok(()),
463
464            RynaExpr::Break(..) if allowed => Ok(()),
465            RynaExpr::Break(l) if !allowed => {
466                Err(RynaError::compiler_error("Break statement is not allowed in this context".into(), l, vec!()))
467            }
468
469            RynaExpr::Continue(..) if allowed => Ok(()),
470            RynaExpr::Continue(l) if !allowed => {
471                Err(RynaError::compiler_error("Continue statement is not allowed in this context".into(), l, vec!()))
472            }
473
474            RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _) |
475            RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _) => {
476                RynaContext::break_continue_check(e, allowed)
477            }
478
479            RynaExpr::Tuple(_, args) => args.iter().try_for_each(|i| RynaContext::break_continue_check(i, allowed)),
480            
481            RynaExpr::If(_, i, ib, ei, eb) => {
482                RynaContext::break_continue_check(i, allowed)?;
483
484                for i in ib {
485                    RynaContext::break_continue_check(i, allowed)?;
486                }
487                
488                for (ei_h, ei_b) in ei {
489                    RynaContext::break_continue_check(ei_h, allowed)?;
490
491                    for i in ei_b {
492                        RynaContext::break_continue_check(i, allowed)?;
493                    }
494                }
495
496                if let Some(eb_inner) = eb {
497                    for i in eb_inner {
498                        RynaContext::break_continue_check(i, allowed)?;
499                    }    
500                }
501
502                Ok(())
503            },
504
505            RynaExpr::DoBlock(_, b, _) => {
506                for i in b {
507                    RynaContext::break_continue_check(i, allowed)?;
508                }
509
510                Ok(())
511            }
512
513            RynaExpr::CompiledFor(_, _, _, _, c, b) |
514            RynaExpr::While(_, c, b) => {
515                RynaContext::break_continue_check(c, true)?;
516
517                for i in b {
518                    RynaContext::break_continue_check(i, true)?;
519                }
520
521                Ok(())
522            },
523
524            RynaExpr::UnaryOperation(_, _, _, e) => {
525                RynaContext::break_continue_check(e, allowed)?;
526
527                Ok(())
528            }
529
530            RynaExpr::AttributeAssignment(_, a, b, _) |
531            RynaExpr::BinaryOperation(_, _, _, a, b) => {
532                RynaContext::break_continue_check(a, allowed)?;
533                RynaContext::break_continue_check(b, allowed)?;
534
535                Ok(())
536            },
537
538            RynaExpr::NaryOperation(_, _, _, a, args) => {
539                RynaContext::break_continue_check(a, allowed)?;
540                
541                for i in args {
542                    RynaContext::break_continue_check(i, allowed)?;
543                }
544
545                Ok(())
546            },
547
548            RynaExpr::FunctionCall(_, _, _, args) => {
549                for i in args {
550                    RynaContext::break_continue_check(i, allowed)?;
551                }
552
553                Ok(())
554            },
555
556            RynaExpr::AttributeAccess(_, e, _) |
557            RynaExpr::Return(_, e) => RynaContext::break_continue_check(e, allowed),
558
559            RynaExpr::CompiledLambda(_, _, _, _, _, b) => {
560                for i in b {
561                    RynaContext::break_continue_check(i, false)?;
562                }
563
564                Ok(())
565            },
566
567            RynaExpr::PrefixOperationDefinition(_, _, _, tm, _, _, _, b) => {
568                if tm.is_empty() {
569                    for i in b {
570                        RynaContext::break_continue_check(i, false)?;
571                    }
572                }
573
574                Ok(())
575            },
576
577            RynaExpr::PostfixOperationDefinition(_, _, _, tm, _, _, _, b) => {
578                if tm.is_empty() {
579                    for i in b {
580                        RynaContext::break_continue_check(i, false)?;    
581                    }
582                }
583                
584                Ok(())
585            },
586
587            RynaExpr::BinaryOperationDefinition(_, _, _, tm, (_, _), (_, _), _, b) => {
588                if tm.is_empty() {
589                    for i in b {
590                        RynaContext::break_continue_check(i, false)?;    
591                    }          
592                }
593                
594                Ok(())
595            },
596
597            RynaExpr::NaryOperationDefinition(_, _, _, tm, (_, _), _, _, b) => {
598                if tm.is_empty() {
599                    for i in b {
600                        RynaContext::break_continue_check(i, false)?;    
601                    }
602                }
603                
604                Ok(())
605            },
606
607
608            RynaExpr::FunctionDefinition(_, _, _, tm, _, _, b) => {
609                if tm.is_empty() {
610                    for i in b {
611                        RynaContext::break_continue_check(i, false)?;    
612                    }
613                }
614                
615                Ok(())
616            },
617
618            e => unreachable!("{:?}", e)
619        };
620    }
621
622    pub fn invalid_type_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
623        return match expr {
624            RynaExpr::PrefixOperatorDefinition(..) |
625            RynaExpr::PostfixOperatorDefinition(..) |
626            RynaExpr::BinaryOperatorDefinition(..) |
627            RynaExpr::NaryOperatorDefinition(..) |
628            RynaExpr::InterfaceDefinition(..) |
629            RynaExpr::Macro(..) |
630            RynaExpr::Break(..) |
631            RynaExpr::Continue(..) |
632            RynaExpr::Variable(..) |
633            RynaExpr::Literal(..) => Ok(()),
634
635            RynaExpr::CompiledVariableAssignment(l, _, _, t, e, _) |
636            RynaExpr::CompiledVariableDefinition(l, _, _, t, e, _) => {
637                if t.has_self() {
638                    return Err(RynaError::compiler_error(
639                        format!("{} type found outside an interface", Type::SelfType.get_name(self)),
640                        l, vec!()
641                    ));
642                }
643
644                self.invalid_type_check(e)
645            }
646
647            RynaExpr::AttributeAssignment(_, a, b, _) => {
648                self.invalid_type_check(a)?;
649                self.invalid_type_check(b)
650            }
651
652            RynaExpr::Tuple(_, args) => args.iter().try_for_each(|i| self.invalid_type_check(i)),
653            
654            RynaExpr::If(_, i, ib, ei, eb) => {
655                self.invalid_type_check(i)?;
656
657                for i in ib {
658                    self.invalid_type_check(i)?;
659                }
660                
661                for (ei_h, ei_b) in ei {
662                    self.invalid_type_check(ei_h)?;
663
664                    for i in ei_b {
665                        self.invalid_type_check(i)?;
666                    }
667                }
668
669                if let Some(eb_inner) = eb {
670                    for i in eb_inner {
671                        self.invalid_type_check(i)?;
672                    }    
673                }
674
675                Ok(())
676            },
677
678            RynaExpr::DoBlock(l, b, t) => {
679                if t.has_self() {
680                    return Err(RynaError::compiler_error(
681                        format!("{} type found outside an interface", Type::SelfType.get_name(self)),
682                        l, vec!()
683                    ));
684                }
685
686                for i in b {
687                    self.invalid_type_check(i)?;
688                }
689
690                Ok(())
691            }
692
693            RynaExpr::CompiledFor(_, _, _, _, c, b) |
694            RynaExpr::While(_, c, b) => {
695                self.invalid_type_check(c)?;
696
697                for i in b {
698                    self.invalid_type_check(i)?;
699                }
700
701                Ok(())
702            },
703
704            RynaExpr::UnaryOperation(l, _, tm, e) => {
705                self.invalid_type_check(e)?;
706
707                for t in tm {
708                    if t.has_self() {
709                        return Err(RynaError::compiler_error(
710                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
711                            l, vec!()
712                        ));    
713                    }
714                }
715
716                Ok(())
717            }
718
719            RynaExpr::BinaryOperation(l, _, tm, a, b) => {
720                self.invalid_type_check(a)?;
721                self.invalid_type_check(b)?;
722
723                for t in tm {
724                    if t.has_self() {
725                        return Err(RynaError::compiler_error(
726                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
727                            l, vec!()
728                        ));    
729                    }
730                }
731
732                Ok(())
733            },
734
735            RynaExpr::NaryOperation(l, _, tm, a, args) => {
736                self.invalid_type_check(a)?;
737                
738                for i in args {
739                    self.invalid_type_check(i)?;
740                }
741
742                for t in tm {
743                    if t.has_self() {
744                        return Err(RynaError::compiler_error(
745                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
746                            l, vec!()
747                        ));    
748                    }
749                }
750
751                Ok(())
752            },
753
754            RynaExpr::FunctionCall(l, _, tm, args) => {
755                for i in args {
756                    self.invalid_type_check(i)?;
757                }
758
759                for t in tm {
760                    if t.has_self() {
761                        return Err(RynaError::compiler_error(
762                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
763                            l, vec!()
764                        ));    
765                    }
766                }
767
768                Ok(())
769            },
770
771            RynaExpr::AttributeAccess(_, e, _) |
772            RynaExpr::Return(_, e) => self.invalid_type_check(e),
773
774            RynaExpr::CompiledLambda(l, _, c, args, ret, b) => {
775                for (_, i) in c {
776                    self.invalid_type_check(i)?;
777                }
778
779                for i in b {
780                    self.invalid_type_check(i)?;
781                }
782
783                for t in args.iter().map(|(_, t)| t).chain([ret]) {
784                    if t.has_self() {
785                        return Err(RynaError::compiler_error(
786                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
787                            l, vec!()
788                        ));    
789                    }
790                }
791
792                Ok(())
793            },
794
795            RynaExpr::PrefixOperationDefinition(l, _, _, tm, _, a, ret, b) => {
796                if tm.is_empty() {
797                    for i in b {
798                        self.invalid_type_check(i)?;
799                    }
800    
801                    for t in [a, ret] {
802                        if t.has_self() {
803                            return Err(RynaError::compiler_error(
804                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
805                                l, vec!()
806                            ));    
807                        }
808                    }
809                }
810
811                Ok(())
812            },
813
814            RynaExpr::PostfixOperationDefinition(l, _, _, tm, _, a, ret, b) => {
815                if tm.is_empty() {
816                    for i in b {
817                        self.invalid_type_check(i)?;    
818                    }
819    
820                    for t in [a, ret] {
821                        if t.has_self() {
822                            return Err(RynaError::compiler_error(
823                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
824                                l, vec!()
825                            ));    
826                        }
827                    }
828                }
829                
830                Ok(())
831            },
832
833            RynaExpr::BinaryOperationDefinition(l, _, _, tm, (_, a_1), (_, a_2), ret, b) => {
834                if tm.is_empty() {
835                    for i in b {
836                        self.invalid_type_check(i)?;    
837                    }
838    
839                    for t in [a_1, a_2, ret] {
840                        if t.has_self() {
841                            return Err(RynaError::compiler_error(
842                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
843                                l, vec!()
844                            ));    
845                        }
846                    }                
847                }
848                
849                Ok(())
850            },
851
852            RynaExpr::NaryOperationDefinition(l, _, _, tm, (_, a), args, ret, b) => {
853                if tm.is_empty() {
854                    for i in b {
855                        self.invalid_type_check(i)?;    
856                    }
857    
858                    for t in args.iter().map(|(_, t)| t).chain([a, ret]) {
859                        if t.has_self() {
860                            return Err(RynaError::compiler_error(
861                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
862                                l, vec!()
863                            ));    
864                        }
865                    }
866                }
867                
868                Ok(())
869            },
870
871
872            RynaExpr::FunctionDefinition(l, _, _, tm, args, ret, b) => {
873                if tm.is_empty() {
874                    for i in b {
875                        self.invalid_type_check(i)?;    
876                    }
877    
878                    for t in args.iter().map(|(_, t)| t).chain([ret]) {
879                        if t.has_self() {
880                            return Err(RynaError::compiler_error(
881                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
882                                l, vec!()
883                            ));    
884                        }
885                    }
886                }
887                
888                Ok(())
889            },
890
891            RynaExpr::ClassDefinition(l, _, _, _, args, alias, _) => {
892                if let Some(t) = alias {
893                    if t.has_self() {
894                        return Err(RynaError::compiler_error(
895                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
896                            l, vec!()
897                        ));    
898                    }
899                
900                } else {
901                    for t in args.iter().map(|(_, t)| t) {
902                        if t.has_self() {
903                            return Err(RynaError::compiler_error(
904                                format!("{} type found outside an interface", Type::SelfType.get_name(self)),
905                                l, vec!()
906                            ));    
907                        }
908                    }
909                }
910
911                Ok(())
912            },
913
914            RynaExpr::InterfaceImplementation(l, _, ret, _, args) => {
915                for t in args.iter().chain([ret]) {
916                    if t.has_self() {
917                        return Err(RynaError::compiler_error(
918                            format!("{} type found outside an interface", Type::SelfType.get_name(self)),
919                            l, vec!()
920                        ));    
921                    }
922                }
923
924                Ok(())
925            },
926
927            e => unreachable!("{:?}", e)
928        };
929    }
930
931    pub fn check_type_well_formed(&self, t: &Type, l: &Location) -> Result<(), RynaError> {
932        return match t {
933            Type::Empty |
934            Type::SelfType |
935            Type::Basic(_) |
936            Type::Wildcard |
937            Type::InferenceMarker => Ok(()),
938
939            Type::Ref(i) |
940            Type::MutRef(i) => self.check_type_well_formed(i, l),
941
942            Type::Or(v) |
943            Type::And(v) => v.iter().try_for_each(|i| self.check_type_well_formed(i, l)),
944
945            Type::TemplateParamStr(n, _) => {
946                Err(RynaError::compiler_error(
947                    format!(
948                        "Template {} is not defined", 
949                        format!("'{}", n).green(),
950                    ), 
951                    l, 
952                    vec!()
953                ))
954            }
955
956            Type::TemplateParam(_, cs) => {
957                for c in cs {
958                    let interface = &self.interfaces[c.id];
959                    let interface_args = interface.params.len();
960
961                    if c.args.len() != interface_args {
962                        return Err(
963                            RynaError::compiler_error(
964                                format!(
965                                    "Interface {}{} expected {} arguments (got {})", 
966                                    interface.name.cyan(), 
967                                    if interface_args == 0 { 
968                                        "".into() 
969                                    } else { 
970                                        format!("<{}>", interface.params.iter().map(|i| i.green().to_string()).collect::<Vec<_>>().join(", ")) 
971                                    },
972                                    interface_args, 
973                                    c.args.len()
974                                ), 
975                                l, 
976                                vec!()
977                            )
978                        );
979                    }
980
981                    for arg in &c.args {
982                        self.check_type_well_formed(arg, l)?;
983                    }
984                }
985
986                Ok(())
987            },
988
989            Type::Template(id, args) => {
990                let t = &self.type_templates[*id];
991                let num_params = t.params.len();
992
993                if num_params != args.len() {
994                    return Err(
995                        RynaError::compiler_error(
996                            format!(
997                                "Type {}{} expected {} arguments (got {})", 
998                                t.name.cyan(), 
999                                if num_params == 0 { "".into() } else { format!("<{}>", t.params.iter().map(|i| i.green().to_string()).collect::<Vec<_>>().join(", ")) },
1000                                num_params, 
1001                                args.len()
1002                            ), 
1003                            l, 
1004                            vec!()
1005                        )
1006                    );
1007                }
1008
1009                args.iter().try_for_each(|i| self.check_type_well_formed(i, l))
1010            },
1011            
1012            Type::Function(a, b) => {
1013                self.check_type_well_formed(a, l)?;
1014                self.check_type_well_formed(b, l)
1015            },
1016        }
1017    }
1018
1019    pub fn type_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1020        match expr {
1021            RynaExpr::Break(..) |
1022            RynaExpr::Continue(..) |
1023            RynaExpr::Literal(..) |
1024            RynaExpr::Variable(..) |
1025            RynaExpr::PrefixOperatorDefinition(..) |
1026            RynaExpr::PostfixOperatorDefinition(..) |
1027            RynaExpr::BinaryOperatorDefinition(..) |
1028            RynaExpr::NaryOperatorDefinition(..) => Ok(()),
1029
1030            RynaExpr::DoBlock(_, args, _) |
1031            RynaExpr::Tuple(_, args) => {
1032                for arg in args {
1033                    self.type_check(arg)?;
1034                }
1035
1036                Ok(())
1037            }
1038
1039            RynaExpr::CompiledVariableDefinition(l, _, n, t, e, _) |
1040            RynaExpr::CompiledVariableAssignment(l, _, n, t, e, _) => {
1041                self.check_type_well_formed(t, l)?;
1042                self.type_check(e)?;
1043
1044                let it = self.infer_type(e)?;
1045
1046                if it.bindable_to(t, self) {
1047                    Ok(())
1048
1049                } else{
1050                    Err(RynaError::compiler_error(format!(
1051                        "Unable to bind value of type {} to variable {}, which is of type {}",
1052                        it.get_name(self),
1053                        n.cyan(),
1054                        t.get_name(self)
1055                    ), l, vec!()))
1056                }
1057            },
1058
1059            RynaExpr::AttributeAssignment(l, a, b, attr_idx) => {
1060                self.type_check(a)?;
1061                self.type_check(b)?;
1062
1063                let lhs_attr = self.infer_type(a)?;
1064
1065                let (attr_name, lhs) = if let Type::Basic(id) | Type::Template(id, _) = lhs_attr.deref_type() {
1066                    self.type_templates[*id].attributes[*attr_idx].clone()
1067                } else {
1068                    unreachable!()
1069                };
1070
1071                if let Type::Ref(_) = lhs_attr {
1072                    return Err(RynaError::compiler_error(format!(
1073                        "Unable assign value to attribute {} because it is accessed from a constant reference",
1074                        attr_name.cyan()
1075                    ), l, vec!()));
1076                }
1077
1078                if !matches!(lhs_attr, Type::MutRef(_)) {
1079                    return Err(RynaError::compiler_error(format!(
1080                        "Unable assign value to attribute {} because it is not accesed from a mutable reference",
1081                        attr_name.cyan()
1082                    ), l, vec!()));
1083                }
1084
1085                let rhs = self.infer_type(b)?;
1086
1087                if rhs.bindable_to(&lhs, self) {
1088                    Ok(())
1089
1090                } else {
1091                    return Err(RynaError::compiler_error(format!(
1092                        "Unable to bind value of type {} to attribute {}, which is of type {}",
1093                        rhs.get_name(self),
1094                        attr_name.cyan(),
1095                        lhs.get_name(self)
1096                    ), l, vec!()));
1097                }
1098            },
1099
1100            RynaExpr::FunctionCall(l, id, templates, args) => {
1101                for t in templates {
1102                    self.check_type_well_formed(t, l)?;
1103                }
1104
1105                let mut arg_types = Vec::with_capacity(args.len());
1106
1107                for arg in args.iter() {
1108                    self.type_check(arg)?;
1109                    arg_types.push(self.infer_type(arg)?);
1110                }
1111
1112                let (ov_id, _, _, _) = self.get_first_function_overload(*id, arg_types.clone(), Some(templates.clone()), false, l)?;
1113
1114                //Invalid number of template arguments
1115                if self.functions[*id].overloads[ov_id].templates != templates.len() {
1116                    Err(RynaError::compiler_error(format!(
1117                        "Function overload for {}{}({}) expected {} type arguments (got {})",
1118                        self.functions[*id].name.green(),
1119                        if templates.is_empty() { "".into() } else { format!("<{}>", templates.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")) },
1120                        arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1121                        self.functions[*id].overloads[ov_id].templates, templates.len()
1122                    ), l, vec!()))
1123                
1124                } else {
1125                    // Update caches
1126                    self.cache.usages.functions.add_new(*id, arg_types.clone(), templates.clone());
1127                    self.cache.overloads.functions.insert((*id, arg_types.clone(), templates.clone()), ov_id);
1128
1129                    // Forbid custom destructors for types that need generated destructors
1130                    if  *id == self.get_function_id("destroy".into()).unwrap() {
1131                        let dtor_arg = arg_types[0].deref_type();
1132
1133                        if dtor_arg.has_invalid_destructor(self) {
1134                            return Err(RynaError::compiler_error(
1135                                format!("Type {} cannot implement Destroyable because it needs a compiler-generated destructor", dtor_arg.get_name(self)),
1136                                l, vec!()
1137                            ));
1138                        }
1139                    }
1140
1141                    Ok(())
1142                }
1143            },
1144
1145            RynaExpr::UnaryOperation(l, id, templates, arg) => {
1146                for t in templates {
1147                    self.check_type_well_formed(t, l)?;
1148                }
1149
1150                self.type_check(arg)?;
1151                let t = self.infer_type(arg)?;
1152
1153                let (ov_id, _, _, _) = self.get_first_unary_op(*id, t.clone(), Some(templates.clone()), false, l)?;
1154
1155                if let Operator::Unary{prefix, representation, operations, ..} = &self.unary_ops[*id] {
1156                    if operations[ov_id].templates != templates.len() {
1157                        if *prefix {
1158                            Err(RynaError::compiler_error(format!(
1159                                "Unary operator overload for {}({}) expected {} type arguments (got {})",
1160                                representation,
1161                                t.get_name(self),
1162                                operations[ov_id].templates, templates.len()
1163                            ), l, vec!()))
1164
1165                        } else {
1166                            Err(RynaError::compiler_error(format!(
1167                                "Unary operator overload for ({}){} expected {} type arguments (got {})",
1168                                t.get_name(self),
1169                                representation,
1170                                operations[ov_id].templates, templates.len()
1171                            ), l, vec!()))
1172                        }
1173
1174                    } else {
1175                        // Update caches
1176                        self.cache.usages.unary.add_new(*id, vec!(t.clone()), templates.clone());
1177                        self.cache.overloads.unary.insert((*id, vec!(t.clone()), templates.clone()), ov_id);
1178
1179                        Ok(())                            
1180                    }
1181                
1182                } else {
1183                    unreachable!()
1184                }
1185            },
1186
1187            RynaExpr::BinaryOperation(l, id, templates, arg1, arg2) => {
1188                for t in templates {
1189                    self.check_type_well_formed(t, l)?;
1190                }
1191                
1192                self.type_check(arg1)?;
1193                self.type_check(arg2)?;
1194
1195                let t1 = self.infer_type(arg1)?;
1196                let t2 = self.infer_type(arg2)?;
1197                
1198                let (ov_id, _, _, _) = self.get_first_binary_op(*id, t1.clone(), t2.clone(), Some(templates.clone()), false, l)?;
1199
1200                if let Operator::Binary{representation, operations, ..} = &self.binary_ops[*id] {
1201                    if operations[ov_id].templates != templates.len() {
1202                        Err(RynaError::compiler_error(format!(
1203                            "Binary operator overload for ({}){}({}) expected {} type arguments (got {})",
1204                            t1.get_name(self),
1205                            representation,
1206                            t2.get_name(self),
1207                            operations[ov_id].templates, templates.len()
1208                        ), l, vec!()))    
1209
1210                    } else {
1211                        // Update caches
1212                        self.cache.usages.binary.add_new(*id, vec!(t1.clone(), t2.clone()), templates.clone());
1213                        self.cache.overloads.binary.insert((*id, vec!(t1.clone(), t2.clone()), templates.clone()), ov_id);
1214
1215                        Ok(())
1216                    }
1217
1218                } else {
1219                    unreachable!()
1220                }
1221            },
1222
1223            RynaExpr::NaryOperation(l, id, templates, first, args) => {
1224                for t in templates {
1225                    self.check_type_well_formed(t, l)?;
1226                }
1227                
1228                self.type_check(first)?;
1229                let t = self.infer_type(first)?;
1230
1231                let mut arg_types = Vec::with_capacity(args.len());
1232
1233                for arg in args.iter() {
1234                    self.type_check(arg)?;
1235                    arg_types.push(self.infer_type(arg)?);
1236                }
1237
1238                let (ov_id, _, _, _) = self.get_first_nary_op(*id, t.clone(), arg_types.clone(), Some(templates.clone()), false, l)?;
1239
1240                if let Operator::Nary{open_rep, close_rep, operations, ..} = &self.nary_ops[*id] {
1241                    if operations[ov_id].templates != templates.len() {
1242                        Err(RynaError::compiler_error(format!(
1243                            "N-ary operator overload for {}{}{}{} expected {} type arguments (got {})",
1244                            t.get_name(self),
1245                            open_rep,
1246                            arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1247                            close_rep,
1248                            operations[ov_id].templates, templates.len()
1249                        ), l, vec!()))
1250
1251                    } else {
1252                        let mut all_args = vec!(t.clone());
1253                        all_args.extend(arg_types);
1254
1255                        // Update caches
1256                        self.cache.usages.nary.add_new(*id, all_args.clone(), templates.clone());
1257                        self.cache.overloads.nary.insert((*id, all_args, templates.clone()), ov_id);
1258                        
1259                        Ok(())    
1260                    }
1261
1262                } else {
1263                    unreachable!()
1264                }
1265            },
1266
1267            RynaExpr::If(l, ih, ib, ei, eb) => {
1268                self.type_check(ih)?;
1269
1270                let t = self.infer_type(ih)?;
1271
1272                if *t.deref_type() != BOOL {
1273                    return Err(RynaError::compiler_error(format!("If condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1274                }
1275
1276                for line in ib {
1277                    self.type_check(line)?;
1278                }
1279
1280                for (ei_h, ei_b) in ei {
1281                    self.type_check(ei_h)?;
1282                    let t = self.infer_type(ei_h)?;
1283
1284                    if *t.deref_type() != BOOL {
1285                        return Err(RynaError::compiler_error(format!("If condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1286                    }
1287
1288                    for line in ei_b {
1289                        self.type_check(line)?;
1290                    }
1291                }
1292
1293                if let Some(eb_inner) = eb {
1294                    for line in eb_inner {
1295                        self.type_check(line)?;
1296                    }
1297                }
1298
1299                Ok(())
1300            },
1301
1302            RynaExpr::CompiledFor(_, _, _, _, iter, body) => {
1303                self.type_check(iter)?;
1304
1305                for line in body {
1306                    self.type_check(line)?;
1307                }
1308
1309                Ok(())
1310            }
1311
1312            RynaExpr::While(l, cond, body) => {
1313                self.type_check(cond)?;
1314                let t = self.infer_type(cond)?;
1315
1316                if *t.deref_type() != BOOL {
1317                    return Err(RynaError::compiler_error(format!("While condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1318                }
1319
1320                for line in body {
1321                    self.type_check(line)?;
1322                }
1323
1324                Ok(())
1325            },
1326
1327            RynaExpr::AttributeAccess(_, e, _) |
1328            RynaExpr::Return(_, e) => {
1329                self.type_check(e)?;
1330                self.infer_type(e)?;
1331                
1332                Ok(())
1333            }
1334
1335            RynaExpr::CompiledLambda(l, _, c, args, _, b) => {
1336                for (_, i) in c {
1337                    self.type_check(i)?;
1338                }     
1339
1340                for (_, t) in args {
1341                    self.check_type_well_formed(t, l)?;
1342                }
1343                
1344                for line in b {
1345                    self.type_check(line)?;
1346                }                
1347
1348                Ok(())
1349            }
1350
1351            RynaExpr::PrefixOperationDefinition(l, _, _, t, _, arg, r, b) |
1352            RynaExpr::PostfixOperationDefinition(l, _, _, t, _, arg, r, b) => {
1353                self.check_type_well_formed(arg, l)?;
1354                self.check_type_well_formed(r, l)?;
1355
1356                if t.is_empty() {
1357                    for line in b {
1358                        self.type_check(line)?;
1359                    }
1360                
1361                } else {
1362                    let mut templates = HashSet::new();
1363                    arg.template_dependencies(&mut templates);
1364                    r.template_dependencies(&mut templates);
1365
1366                    for (i, n) in t.iter().enumerate() {
1367                        if !templates.contains(&i) {
1368                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1369                        }
1370                    }
1371                }
1372
1373                Ok(())
1374            }
1375
1376            RynaExpr::BinaryOperationDefinition(l, _, _, t, (_, ta), (_, tb), r, b) => {
1377                self.check_type_well_formed(ta, l)?;
1378                self.check_type_well_formed(tb, l)?;
1379                self.check_type_well_formed(r, l)?;
1380
1381                if t.is_empty() {
1382                    for line in b {
1383                        self.type_check(line)?;
1384                    }
1385                
1386                } else {
1387                    let mut templates = HashSet::new();
1388                    ta.template_dependencies(&mut templates);
1389                    tb.template_dependencies(&mut templates);
1390                    r.template_dependencies(&mut templates);
1391
1392                    for (i, n) in t.iter().enumerate() {
1393                        if !templates.contains(&i) {
1394                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1395                        }
1396                    }
1397                }
1398
1399                Ok(())
1400            }
1401
1402            RynaExpr::NaryOperationDefinition(l, _, _, t, (_, ta), args, r, b) => {
1403                self.check_type_well_formed(ta, l)?;
1404                self.check_type_well_formed(r, l)?;
1405
1406                for (_, t) in args {
1407                    self.check_type_well_formed(t, l)?;
1408                }
1409                
1410                if t.is_empty() {
1411                    for line in b {
1412                        self.type_check(line)?;
1413                    }
1414                
1415                } else {
1416                    let mut templates = HashSet::new();
1417                    ta.template_dependencies(&mut templates);
1418                    r.template_dependencies(&mut templates);
1419
1420                    for (_, i) in args {
1421                        i.template_dependencies(&mut templates);
1422                    }
1423
1424                    for (i, n) in t.iter().enumerate() {
1425                        if !templates.contains(&i) {
1426                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1427                        }
1428                    }
1429                }
1430
1431                Ok(())
1432            },
1433
1434            RynaExpr::FunctionDefinition(l, _, _, t, args, r, b) => {
1435                self.check_type_well_formed(r, l)?;
1436
1437                for (_, t) in args {
1438                    self.check_type_well_formed(t, l)?;
1439                }
1440
1441                if t.is_empty() {
1442                    for line in b {
1443                        self.type_check(line)?;
1444                    }
1445                
1446                } else {
1447                    let mut templates = HashSet::new();
1448                    r.template_dependencies(&mut templates);
1449
1450                    for (_, i) in args {
1451                        i.template_dependencies(&mut templates);
1452                    }
1453
1454                    for (i, n) in t.iter().enumerate() {
1455                        if !templates.contains(&i) {
1456                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1457                        }
1458                    }
1459                }
1460
1461                Ok(())
1462            }
1463
1464            RynaExpr::InterfaceDefinition(l, _, _, t, fns, uns, bin, nary) => {
1465                let mut templates = HashSet::new();
1466
1467                for (_, _, f_t, args, r) in fns {
1468                    let mut templates_f = HashSet::new();
1469
1470                    self.check_type_well_formed(r, l)?;
1471                    r.template_dependencies(&mut templates);
1472                    r.template_dependencies(&mut templates_f);
1473
1474                    for (_, i) in args {
1475                        self.check_type_well_formed(i, l)?;
1476                        i.template_dependencies(&mut templates);
1477                        i.template_dependencies(&mut templates_f);
1478                    }
1479
1480                    // Function templates
1481                    if let Some(inner) = f_t {
1482                        for (i, n) in inner.iter().enumerate() {
1483                            let offset_id = i + t.len();
1484
1485                            if !templates.contains(&offset_id) {
1486                                return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1487                            }    
1488                        }
1489                    }
1490                }
1491
1492                for (_, _, f_t, _, at, r) in uns {
1493                    self.check_type_well_formed(at, l)?;
1494                    self.check_type_well_formed(r, l)?;
1495
1496                    at.template_dependencies(&mut templates);
1497                    r.template_dependencies(&mut templates);
1498
1499                    for (i, n) in f_t.iter().enumerate() {
1500                        let offset_id = i + t.len();
1501
1502                        if !templates.contains(&offset_id) {
1503                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1504                        }    
1505                    }
1506                }
1507
1508                for (_, _, f_t, (_, a0t), (_, a1t), r) in bin {
1509                    self.check_type_well_formed(a0t, l)?;
1510                    self.check_type_well_formed(a1t, l)?;
1511                    self.check_type_well_formed(r, l)?;
1512
1513                    a0t.template_dependencies(&mut templates);
1514                    a1t.template_dependencies(&mut templates);
1515                    r.template_dependencies(&mut templates);
1516
1517                    for (i, n) in f_t.iter().enumerate() {
1518                        let offset_id = i + t.len();
1519
1520                        if !templates.contains(&offset_id) {
1521                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1522                        }    
1523                    }
1524                }
1525
1526                for (_, _, f_t, (_, a0t), args, r) in nary {
1527                    self.check_type_well_formed(a0t, l)?;
1528                    self.check_type_well_formed(r, l)?;
1529
1530                    a0t.template_dependencies(&mut templates);
1531                    r.template_dependencies(&mut templates);
1532
1533                    for (_, i) in args {
1534                        self.check_type_well_formed(i, l)?;
1535                        i.template_dependencies(&mut templates);
1536                    }
1537
1538                    for (i, n) in f_t.iter().enumerate() {
1539                        let offset_id = i + t.len();
1540
1541                        if !templates.contains(&offset_id) {
1542                            return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1543                        }    
1544                    }
1545                }
1546
1547                for (i, n) in t.iter().enumerate() {
1548                    if !templates.contains(&i) {
1549                        return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1550                    }
1551                }
1552                
1553                Ok(())
1554            }
1555
1556            RynaExpr::InterfaceImplementation(l, t, tp, _, args) => {
1557                let mut templates = HashSet::new();
1558                self.check_type_well_formed(tp, l)?;
1559                tp.template_dependencies(&mut templates);
1560
1561                for i in args {
1562                    self.check_type_well_formed(i, l)?;
1563                    i.template_dependencies(&mut templates);
1564                }
1565
1566                for (i, n) in t.iter().enumerate() {
1567                    if !templates.contains(&i) {
1568                        return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1569                    }
1570                }
1571
1572                Ok(())
1573            }
1574
1575            RynaExpr::ClassDefinition(l, _, _, t, attrs, alias, _) => {
1576                let mut templates = HashSet::new();
1577
1578                if let Some(a) = alias {
1579                    self.check_type_well_formed(a, l)?;
1580                    a.template_dependencies(&mut templates);    
1581                
1582                } else {
1583                    for (_, i) in attrs {
1584                        self.check_type_well_formed(i, l)?;
1585                        i.template_dependencies(&mut templates);
1586                    }
1587                }
1588
1589                for (i, n) in t.iter().enumerate() {
1590                    if !templates.contains(&i) {
1591                        return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1592                    }
1593                }
1594
1595                Ok(())
1596            }
1597
1598            RynaExpr::Macro(..) => { Ok(()) },
1599
1600            _ => unimplemented!("{:?}", expr)
1601        }
1602    }
1603
1604    #[allow(clippy::never_loop)] // This seems like an bug in clippy
1605    pub fn implicit_syntax_check(&self, name: &String, templates: &[String], attributes: &[(String, Type)], syntaxes: &Vec<Pattern>) -> Result<(), String> {
1606        if !syntaxes.is_empty() && !templates.is_empty() {
1607            return Err("Implicit syntaxes are not allowed when classes have type parameters".to_string())
1608        }
1609
1610        let atts = attributes.iter().map(|(n, _)| n.clone()).collect::<HashSet<_>>();
1611
1612        for s in syntaxes {
1613            let args = s.get_markers();
1614
1615            for diff in args.symmetric_difference(&atts) {
1616                if args.contains(diff) {
1617                    return Err(format!("Syntax argument with name \"{}\" is not an attribute of {}", diff, name));
1618                }
1619
1620                return Err(format!("Attribute \"{}\" does not appear in syntax definition for {}", diff, name));
1621            }
1622        }
1623
1624        Ok(())
1625    }
1626
1627    pub fn class_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1628        match expr {
1629            RynaExpr::ClassDefinition(l, _, n, _, attributes, _, _) => {
1630                for (att, _) in attributes {
1631                    if attributes.iter().filter(|(i, _)| i == att).count() > 1 {
1632                        return Err(RynaError::compiler_error(format!("Repeated attribute \"{}\" in class {}", att, n), l, vec!()));
1633                    }
1634                }
1635                
1636                Ok(())
1637            }
1638
1639            _ => Ok(())
1640        }
1641    }
1642
1643    pub fn macro_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1644        match expr {
1645            RynaExpr::Macro(l, _, n, _, p, b) => {
1646                let pattern_args = p.get_markers();
1647                let macro_args = b.get_markers();
1648                
1649                for p in &pattern_args {
1650                    if !macro_args.contains(&(false, p.clone())) {
1651                        return Err(RynaError::compiler_error(
1652                            format!("Argument {} is not used inside {} syntax", p.green(), n.blue()),
1653                            l, vec!()
1654                        ));
1655                    }
1656                }
1657                
1658                for p in macro_args {
1659                    if !p.0 && !pattern_args.contains(&p.1) {
1660                        return Err(RynaError::compiler_error(
1661                            format!("Argument {} is referenced inside {} syntax, but is not present in its RDL pattern", p.1.green(), n.blue()),
1662                            l, vec!()
1663                        ));
1664                    }
1665                }
1666
1667                Ok(())
1668            }
1669
1670            _ => Ok(())
1671        }
1672    }
1673
1674    pub fn interface_impl_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1675        return match expr {
1676            RynaExpr::InterfaceImplementation(l, tm, t, n, ts) => {
1677                match self.get_interface_id(n.clone()) {
1678                    Ok(int_id) => {
1679                        // Forbid custom destructors for types that need generated destructors
1680                        if tm.len() == 0 && int_id == self.get_interface_id("Destroyable".into()).unwrap() {
1681                            if t.has_invalid_destructor(self) {
1682                                return Err(RynaError::compiler_error(
1683                                    format!("Type {} cannot implement Destroyable because it needs a compiler-generated destructor", t.get_name(self)),
1684                                    l, vec!()
1685                                ));
1686                            }
1687                        }
1688
1689                        let fns = &self.interfaces[int_id].fns;
1690                        let uns = &self.interfaces[int_id].uns;
1691                        let bin = &self.interfaces[int_id].bin;
1692                        let nary = &self.interfaces[int_id].nary;
1693
1694                        let max_tms = fns.iter().map(|i| i.2.as_ref().map(|i| i.len()).unwrap_or(0)).max().unwrap_or(0) + 
1695                                      uns.iter().map(|i| i.2.len()).max().unwrap_or(0) + 
1696                                      bin.iter().map(|i| i.2.len()).max().unwrap_or(0) + 
1697                                      nary.iter().map(|i| i.2.len()).max().unwrap_or(0) + 
1698                                      self.interfaces[int_id].params.len();
1699
1700                        let mut offset_t = t.clone();
1701                        let mut offset_ts = ts.clone();
1702                        offset_t.offset_templates(max_tms);
1703                        offset_ts.iter_mut().for_each(|i| i.offset_templates(max_tms));
1704
1705                        let t_subs = (0..offset_ts.len()).zip(offset_ts.clone()).collect::<HashMap<_, _>>();
1706                        
1707                        for (_, f_n, _, args, ret) in fns {
1708                            match self.get_function_id(f_n.clone()) {
1709                                Ok(fn_id) => {
1710                                    let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1711                                    let args_sub = args.iter().map(|(_, tp)| tp.sub_self(&offset_t).sub_templates(&t_subs)).collect::<Vec<_>>();
1712
1713                                    match self.is_function_overload_ambiguous(fn_id, args_sub.clone()) {
1714                                        None => {
1715                                            if let Ok((_, r, _, _)) = self.get_first_function_overload(fn_id, args_sub.clone(), None, true, l) {
1716                                                if !r.bindable_to(&ret_sub, self) {
1717                                                    return Err(RynaError::compiler_error(
1718                                                        format!(
1719                                                            "Function overload for {}({}) needed by interface {} returns {}, which is not bindable to the required {}", 
1720                                                            f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1721                                                            n.green(), r.get_name(self), ret_sub.get_name(self)
1722                                                        ), 
1723                                                        l, vec!()
1724                                                    ));    
1725                                                }
1726
1727                                            } else {
1728                                                return Err(RynaError::compiler_error(
1729                                                    format!(
1730                                                        "Unable to find the function overload for {}({}) needed by interface {}", 
1731                                                        f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1732                                                        n.green()
1733                                                    ), 
1734                                                    l, vec!()
1735                                                ));    
1736                                            }
1737                                        },
1738                                        
1739                                        Some(ov) => {
1740                                            // Do not check templated types. Check later on calls
1741                                            if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1742                                                return Ok(());
1743                                            }
1744                                            
1745                                            let possibilities = ov.iter().map(|(a, r)| format!("{}{} -> {}", self.functions[fn_id].name, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
1746
1747                                            return Err(RynaError::compiler_error(
1748                                                format!(
1749                                                    "Function call {}({}) is ambiguous", 
1750                                                    f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")
1751                                                ), 
1752                                                l, possibilities
1753                                            ));
1754                                        },
1755                                    }
1756                                }
1757
1758                                Err(err) => {
1759                                    return Err(RynaError::compiler_error(err, l, vec!()));
1760                                }
1761                            }
1762                        }
1763
1764                        for (_, op_id, _, _, at, ret) in uns {
1765                            let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1766                            let arg_sub = at.sub_self(&offset_t).sub_templates(&t_subs);
1767
1768                            match self.is_unary_op_ambiguous(*op_id, arg_sub.clone()) {
1769                                None => {
1770                                    if let Ok((_, r, _, _)) = self.get_first_unary_op(*op_id, arg_sub.clone(), None, true, l) {
1771                                        if !r.bindable_to(&ret_sub, self) {
1772                                            if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1773                                                if *prefix {
1774                                                    return Err(RynaError::compiler_error(
1775                                                        format!(
1776                                                            "Unary operation overload for {}({}) needed by interface {} returns {}, which is not bindable to the required {}", 
1777                                                            representation, arg_sub.get_name(self),
1778                                                            n.green(), r.get_name(self), ret_sub.get_name(self)
1779                                                        ), 
1780                                                        l, vec!()
1781                                                    ));     
1782
1783                                                } else {
1784                                                    return Err(RynaError::compiler_error(
1785                                                        format!(
1786                                                            "Unary operation overload for ({}){} needed by interface {} returns {}, which is not bindable to the required {}", 
1787                                                            arg_sub.get_name(self), representation,
1788                                                            n.green(), r.get_name(self), ret_sub.get_name(self)
1789                                                        ), 
1790                                                        l, vec!()
1791                                                    ));      
1792                                                }
1793                                            }        
1794                                        }
1795                                    
1796                                    } else if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1797                                        if *prefix {
1798                                            return Err(RynaError::compiler_error(
1799                                                format!(
1800                                                    "Unable to find the unary operation overload overload for {}({}) needed by interface {}", 
1801                                                    representation, arg_sub.get_name(self),
1802                                                    n.green()
1803                                                ), 
1804                                                l, vec!()
1805                                            ));   
1806
1807                                        } else {
1808                                            return Err(RynaError::compiler_error(
1809                                                format!(
1810                                                    "Unable to find the unary operation overload overload for ({}){} needed by interface {}", 
1811                                                    arg_sub.get_name(self), representation,
1812                                                    n.green()
1813                                                ), 
1814                                                l, vec!()
1815                                            ));   
1816                                        }                                     
1817                                    }
1818                                },
1819                                
1820                                Some(ov) => {
1821                                    // Do not check templated types. Check later on calls
1822                                    if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1823                                        return Ok(());
1824                                    }
1825                                    
1826                                    if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1827                                        if *prefix {
1828                                            let possibilities = ov.iter().map(|(a, r)| format!("{}({}) -> {}", representation, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
1829                                            
1830                                            return Err(RynaError::compiler_error(
1831                                                format!(
1832                                                    "Unary operation {}({}) is ambiguous",
1833                                                    representation,
1834                                                    t.get_name(self)
1835                                                ), l, 
1836                                                possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1837                                            ));
1838                
1839                                        } else {
1840                                            let possibilities = ov.iter().map(|(a, r)| format!("({}){} -> {}", a.get_name(self), representation, r.get_name(self))).collect::<Vec<_>>();
1841                        
1842                                            return Err(RynaError::compiler_error(
1843                                                format!(
1844                                                    "Unary operation ({}){} is ambiguous",
1845                                                    t.get_name(self),
1846                                                    representation
1847                                                ), l, 
1848                                                possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1849                                            ));
1850                                        }
1851                                        
1852                                    } else {
1853                                        unreachable!();
1854                                    }
1855                                },
1856                            }
1857                        }
1858
1859                        for (_, op_id, _, (_, a0t), (_, a1t), ret) in bin {
1860                            let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1861                            let arg0_sub = a0t.sub_self(&offset_t).sub_templates(&t_subs);
1862                            let arg1_sub = a1t.sub_self(&offset_t).sub_templates(&t_subs);
1863                    
1864                            match self.is_binary_op_ambiguous(*op_id, arg0_sub.clone(), arg1_sub.clone()) {
1865                                None => {
1866                                    if let Operator::Binary{representation, ..} = &self.binary_ops[*op_id] {
1867                                        if let Ok((_, r, _, _)) = self.get_first_binary_op(*op_id, arg0_sub.clone(), arg1_sub.clone(), None, true, l) {
1868                                            if !r.bindable_to(&ret_sub, self) {
1869                                                return Err(RynaError::compiler_error(
1870                                                    format!(
1871                                                        "Binary operation overload for ({}){}({}) needed by interface {} returns {}, which is not bindable to the required {}", 
1872                                                        arg0_sub.get_name(self), representation, arg1_sub.get_name(self),
1873                                                        n.green(), r.get_name(self), ret_sub.get_name(self)
1874                                                    ), 
1875                                                    l, vec!()
1876                                                ));    
1877                                            }
1878    
1879                                        } else {
1880                                            return Err(RynaError::compiler_error(
1881                                                format!(
1882                                                    "Unable to find the binary operation overload for ({}){}({}) needed by interface {}", 
1883                                                    arg0_sub.get_name(self), representation, arg1_sub.get_name(self),
1884                                                    n.green()
1885                                                ), 
1886                                                l, vec!()
1887                                            ));    
1888                                        }    
1889                                    }
1890                                },
1891                                
1892                                Some(ov) => {
1893                                    // Do not check templated types. Check later on calls
1894                                    if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1895                                        return Ok(());
1896                                    }
1897                                    
1898                                    if let Operator::Binary{representation, ..} = &self.binary_ops[*op_id] {
1899                                        let possibilities = ov.iter()
1900                                            .map(|(a1, a2, r)| format!("({}){}({}) -> {}", a1.get_name(self), representation, a2.get_name(self), r.get_name(self)))
1901                                            .collect::<Vec<_>>();                
1902                                        
1903                                        return Err(RynaError::compiler_error(
1904                                            format!(
1905                                                "Binary operation ({}){}({}) is ambiguous",
1906                                                arg0_sub.get_name(self),
1907                                                representation, 
1908                                                arg1_sub.get_name(self)
1909                                            ), l, 
1910                                            possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1911                                        ));
1912                                    }
1913                                }
1914                            }
1915                        }
1916
1917                        for (_, op_id, _, (_, a0t), args, ret) in nary {
1918                            let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1919                            let arg0_sub = a0t.sub_self(&offset_t).sub_templates(&t_subs);
1920                            let args_sub = args.iter().map(|(_, tp)| tp.sub_self(&offset_t).sub_templates(&t_subs)).collect::<Vec<_>>();
1921
1922                            match self.is_nary_op_ambiguous(*op_id, arg0_sub.clone(), args_sub.clone()) {
1923                                None => {
1924                                    if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*op_id] {
1925                                        if let Ok((_, r, _, _)) = self.get_first_nary_op(*op_id, arg0_sub.clone(), args_sub.clone(), None, true, l) {
1926                                            if !r.bindable_to(&ret_sub, self) {
1927                                                return Err(RynaError::compiler_error(
1928                                                    format!(
1929                                                        "N-ary operation overload for {}{}{}{} needed by interface {} returns {}, which is not bindable to the required {}", 
1930                                                        arg0_sub.get_name(self), 
1931                                                        open_rep,
1932                                                        args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1933                                                        close_rep,        
1934                                                        n.green(), r.get_name(self), ret_sub.get_name(self)
1935                                                    ), 
1936                                                    l, vec!()
1937                                                ));    
1938                                            }
1939
1940                                        } else {
1941                                            return Err(RynaError::compiler_error(
1942                                                format!(
1943                                                    "Unable to find the n-ary operation overload for {}{}{}{} needed by interface {}", 
1944                                                    arg0_sub.get_name(self), 
1945                                                    open_rep,
1946                                                    args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1947                                                    close_rep,        
1948                                                    n.green()
1949                                                ), 
1950                                                l, vec!()
1951                                            ));    
1952                                        }
1953                                    }
1954                                },
1955
1956                                Some(ov) => {
1957                                    if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*op_id] {
1958                                        let possibilities = ov.iter()
1959                                            .map(|(f, a, r)| 
1960                                                format!(
1961                                                    "{}{}{}{} -> {}", 
1962                                                    f.get_name(self), 
1963                                                    open_rep,
1964                                                    a.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1965                                                    close_rep,
1966                                                    r.get_name(self)
1967                                                )
1968                                            )
1969                                            .collect::<Vec<_>>();
1970                                
1971                                        return Err(RynaError::compiler_error(
1972                                            format!(
1973                                                "N-ary operation {}{}{}{} is ambiguous",
1974                                                arg0_sub.get_name(self), 
1975                                                open_rep,
1976                                                args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1977                                                close_rep
1978                                            ), l, 
1979                                            possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1980                                        ));
1981                                    }
1982                                }
1983                            }
1984                        }
1985
1986                        Ok(())
1987                    }
1988
1989                    Err(err) => Err(RynaError::compiler_error(err, l, vec!()))
1990                }
1991            }
1992
1993            _ => Ok(())
1994        };
1995    }
1996
1997    pub fn no_template_check_type(&self, t: &Type, l: &Location) -> Result<(), RynaError> {
1998        if t.has_templates() {
1999            Err(RynaError::compiler_error("Template types are not allowed in this context".into(), l, vec!()))
2000
2001        } else {
2002            Ok(())
2003        }
2004    }
2005
2006    pub fn no_template_check_types(&self, t: &[Type], l: &Location) -> Result<(), RynaError> {
2007        if t.iter().any(Type::has_templates) {
2008            Err(RynaError::compiler_error("Template types are not allowed in this context".into(), l, vec!()))
2009
2010        } else {
2011            Ok(())
2012        }
2013    }
2014
2015    pub fn no_template_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2016        match expr {
2017            RynaExpr::Literal(..) |
2018            RynaExpr::CompiledLambda(..) => Ok(()),
2019
2020            RynaExpr::Variable(l, _, _, t, _) => self.no_template_check_type(t, l),
2021
2022            RynaExpr::AttributeAssignment(_, a, b, _) => {
2023                self.no_template_check(a)?;
2024                self.no_template_check(b)
2025            }
2026
2027            RynaExpr::AttributeAccess(_, e, _) => {
2028                self.no_template_check(e)
2029            }
2030
2031            RynaExpr::CompiledVariableAssignment(l, _, _, t, e, _) |
2032            RynaExpr::CompiledVariableDefinition(l, _, _, t, e, _) => {
2033                self.no_template_check_type(t, l)?;
2034                self.no_template_check(e)
2035            }
2036
2037            RynaExpr::DoBlock(_, e, _) |
2038            RynaExpr::Tuple(_, e) => {
2039                for i in e {
2040                    self.no_template_check(i)?;
2041                }
2042
2043                Ok(())
2044            }
2045            
2046            RynaExpr::UnaryOperation(l, _, tm, e) => {
2047                self.no_template_check_types(tm, l)?;
2048                self.no_template_check(e)
2049            }
2050            
2051            RynaExpr::BinaryOperation(l, _, tm, a, b) => {
2052                self.no_template_check_types(tm, l)?;
2053                self.no_template_check(a)?;
2054                self.no_template_check(b)
2055            }
2056            
2057            RynaExpr::NaryOperation(l, _, tm, a, b) => {
2058                self.no_template_check_types(tm, l)?;
2059                self.no_template_check(a)?;
2060
2061                for i in b {
2062                    self.no_template_check(i)?;
2063                }
2064
2065                Ok(())
2066            }
2067            
2068            RynaExpr::FunctionCall(l, _, tm, e) => {
2069                self.no_template_check_types(tm, l)?;
2070
2071                for i in e {
2072                    self.no_template_check(i)?;
2073                }
2074
2075                Ok(())
2076            }
2077
2078            RynaExpr::CompiledFor(_, _, _, _, e, b) |
2079            RynaExpr::While(_, e, b) => {
2080                self.no_template_check(e)?;
2081
2082                for i in b {
2083                    self.no_template_check(i)?;
2084                }
2085
2086                Ok(())
2087            }
2088
2089            RynaExpr::If(_, ih, ib, ei, eb) => {
2090                self.no_template_check(ih)?;
2091
2092                for i in ib {
2093                    self.no_template_check(i)?;
2094                }
2095
2096                for (ei_h, ei_b) in ei {
2097                    self.no_template_check(ei_h)?;
2098
2099                    for i in ei_b {
2100                        self.no_template_check(i)?;
2101                    }   
2102                }
2103
2104                if let Some(eb_inner) = eb {
2105                    for i in eb_inner {
2106                        self.no_template_check(i)?;
2107                    }
2108                }
2109
2110                Ok(())
2111            }
2112
2113            RynaExpr::Return(_, e) => self.no_template_check(e),
2114            
2115            _ => unimplemented!("{:?}", expr)
2116        }
2117    }
2118
2119    pub fn lambda_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2120        if let RynaExpr::CompiledLambda(l, _, c, a, r, b) = expr {
2121            for (_, i) in c {
2122                self.no_template_check(i)?;
2123            }
2124
2125            if r.has_templates() {
2126                return Err(RynaError::compiler_error("Parametric types are not allowed in lambda return types".into(), l, vec!()));
2127            }
2128
2129            if a.iter().map(|(_, t)| t).any(Type::has_templates) {
2130                return Err(RynaError::compiler_error("Parametric types are not allowed in lambda parameters".into(), l, vec!()));
2131            }
2132
2133            for line in b {
2134                self.no_template_check(line)?;
2135            }
2136
2137            Ok(())
2138       
2139        } else {
2140            unreachable!()
2141        }
2142    }
2143
2144    pub fn repeated_args(&self, args: &Vec<&String>, item: &str) -> Result<(), String> {
2145        let mut args_set = HashSet::new();
2146
2147        for i in args {
2148            if args_set.contains(i) {
2149                return Err(format!("{} \"{}\" is defined multiple times", item, i));
2150            }
2151
2152            args_set.insert(i);
2153        }
2154
2155        Ok(())
2156    }
2157
2158    pub fn repeated_arguments_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2159        return match expr {
2160            RynaExpr::PostfixOperationDefinition(l, _, _, t, n, _, _, _) |
2161            RynaExpr::PrefixOperationDefinition(l, _, _, t, n, _, _, _) => {
2162                let err = self.repeated_args(&vec!(n), "Parameter");
2163
2164                if let Err(msg) = err {
2165                    return Err(RynaError::compiler_error(msg, l, vec!()));
2166                }
2167
2168                let err = self.repeated_args(&t.iter().collect(), "Parameter");
2169
2170                if let Err(msg) = err {
2171                    return Err(RynaError::compiler_error(msg, l, vec!()));
2172                }
2173
2174                Ok(())
2175            }
2176
2177            RynaExpr::BinaryOperationDefinition(l, _, _, t, (n1, _), (n2, _), _, _) => {
2178                let err = self.repeated_args(&vec!(n1, n2), "Parameter");
2179
2180                if let Err(msg) = err {
2181                    return Err(RynaError::compiler_error(msg, l, vec!()));
2182                }
2183
2184                let err = self.repeated_args(&t.iter().collect(), "Parameter");
2185
2186                if let Err(msg) = err {
2187                    return Err(RynaError::compiler_error(msg, l, vec!()));
2188                }
2189
2190                Ok(())
2191            }
2192
2193            RynaExpr::NaryOperationDefinition(l, _, _, t, (n1, _), n, _, _) => {
2194                let mut args = vec!(n1);
2195                args.extend(n.iter().map(|(i, _)| i));
2196
2197                let err = self.repeated_args(&args, "Parameter");
2198
2199                if let Err(msg) = err {
2200                    return Err(RynaError::compiler_error(msg, l, vec!()));
2201                }
2202
2203                let err = self.repeated_args(&t.iter().collect(), "Parameter");
2204
2205                if let Err(msg) = err {
2206                    return Err(RynaError::compiler_error(msg, l, vec!()));
2207                }
2208
2209                Ok(())
2210            }
2211
2212            RynaExpr::FunctionDefinition(l, _, _, t, a, _, _) => {
2213                let err = self.repeated_args(&a.iter().map(|(n, _)| n).collect(), "Parameter");
2214
2215                if let Err(msg) = err {
2216                    return Err(RynaError::compiler_error(msg, l, vec!()));
2217                }
2218
2219                let err = self.repeated_args(&t.iter().collect(), "Parameter");
2220
2221                if let Err(msg) = err {
2222                    return Err(RynaError::compiler_error(msg, l, vec!()));
2223                }
2224
2225                Ok(())
2226            }
2227
2228            RynaExpr::CompiledLambda(l, _, c, a, _, _) => {
2229                let err = self.repeated_args(&a.iter().map(|(n, _)| n).collect(), "Parameter");
2230
2231                if let Err(msg) = err {
2232                    return Err(RynaError::compiler_error(msg, l, vec!()));
2233                }
2234
2235                let err = self.repeated_args(&c.iter().map(|(n, _)| n).collect(), "Capture");
2236
2237                if let Err(msg) = err {
2238                    return Err(RynaError::compiler_error(msg, l, vec!()));
2239                }
2240
2241                let cap_names = &c.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
2242                let arg_names = &a.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
2243
2244                for n in cap_names {
2245                    if arg_names.contains(n) {
2246                        return Err(RynaError::compiler_error(format!("Capture \"{}\" is also defined as a parameter", n), l, vec!()));
2247                    }
2248                }
2249
2250                Ok(())
2251            }
2252
2253            _ => Ok(())
2254        };
2255    }
2256
2257    pub fn check_test_annotation(&self, annot: &Annotation, t: &Vec<String>, args: &Vec<(String, Type)>, ret: &Type) -> Result<(), String> {
2258        annot.check_args(&[], &[])?;
2259
2260        if t.len() > 0 {
2261            return Err(format!("Functions annotated with {} cannot be generic", "test".cyan()));
2262        }
2263
2264        if args.len() > 0 {
2265            return Err(format!("Functions annotated with {} cannot take any parameters", "test".cyan()));
2266        }
2267
2268        if ret.deref_type() != &BOOL {
2269            return Err(format!(
2270                "Functions annotated with {} must return {}, {} or {}", 
2271                "test".cyan(), BOOL.get_name(self), BOOL.to_ref().get_name(self), BOOL.to_mut().get_name(self)
2272            ));
2273        }
2274        
2275        Ok(())
2276    }
2277
2278    pub fn check_fn_doc_annotation(&self, annot: &Annotation, args: &Vec<(String, Type)>) -> Result<(), String> {
2279        annot.check_args(
2280            &["0", "1"], 
2281            args.iter()
2282                .map(|(n, _)| n.as_str())
2283                .collect::<Vec<_>>().as_slice()
2284        )?;
2285        
2286        Ok(())
2287    }
2288
2289    pub fn check_noret_doc_annotation(&self, annot: &Annotation, args: &Vec<(String, Type)>) -> Result<(), String> {
2290        annot.check_args(
2291            &["0"], 
2292            args.iter()
2293                .map(|(n, _)| n.as_str())
2294                .collect::<Vec<_>>().as_slice()
2295        )?;
2296        
2297        Ok(())
2298    }
2299
2300    pub fn annotation_checks(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2301        match expr {
2302            RynaExpr::Macro(l, an, _, _, _, _) => {
2303                for a in an {
2304                    let res = match a.name.as_str() {
2305                        "test" => Err(format!("Macros cannot have the {} annotation", "test".cyan())),
2306                        "doc" => self.check_noret_doc_annotation(a, &vec!()),
2307
2308                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2309                    };
2310                    
2311                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2312                }
2313            }
2314
2315            RynaExpr::ClassDefinition(l, an, _, _, atts, _, _) => {
2316                for a in an {
2317                    let res = match a.name.as_str() {
2318                        "test" => Err(format!("Classes cannot have the {} annotation", "test".cyan())),
2319                        "doc" => self.check_noret_doc_annotation(a, atts),
2320
2321                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2322                    };
2323                    
2324                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2325                }
2326            }
2327
2328            RynaExpr::InterfaceDefinition(l, an, _, _, fns, unops, binops, naryops) => {
2329                for a in an {
2330                    let res = match a.name.as_str() {
2331                        "test" => Err(format!("Interfaces cannot have the {} annotation", "test".cyan())),
2332                        "doc" => self.check_noret_doc_annotation(a, &vec!()),
2333
2334                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2335                    };
2336                    
2337                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2338                }
2339
2340                for (inner_an, _, _, args, _) in fns {
2341                    for a in inner_an {
2342                        let res = match a.name.as_str() {
2343                            "test" => Err(format!("Interface function headers cannot have the {} annotation", "test".cyan())),
2344                            "doc" => self.check_fn_doc_annotation(a, args),
2345    
2346                            n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2347                        };
2348                        
2349                        res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2350                    }    
2351                }
2352
2353                for (inner_an, _, _, n, t, _) in unops {
2354                    for a in inner_an {
2355                        let res = match a.name.as_str() {
2356                            "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2357                            "doc" => self.check_fn_doc_annotation(a, &vec!((n.clone(), t.clone()))),
2358    
2359                            n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2360                        };
2361                        
2362                        res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2363                    }    
2364                }
2365
2366                for (inner_an, _, _, arg_a, arg_b, _) in binops {
2367                    for a in inner_an {
2368                        let res = match a.name.as_str() {
2369                            "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2370                            "doc" => self.check_fn_doc_annotation(a, &vec!(arg_a.clone(), arg_b.clone())),
2371    
2372                            n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2373                        };
2374                        
2375                        res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2376                    }    
2377                }
2378
2379                for (inner_an, _, _, arg_a, arg_b, _) in naryops {
2380                    let mut all_args = vec!(arg_a.clone());
2381                    all_args.extend(arg_b.iter().cloned());
2382    
2383                    for a in inner_an {
2384                        let res = match a.name.as_str() {
2385                            "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2386                            "doc" => self.check_fn_doc_annotation(a, &all_args),
2387    
2388                            n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2389                        };
2390                        
2391                        res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2392                    }    
2393                }
2394            }
2395
2396            RynaExpr::FunctionDefinition(l, an, _, t, args, r, _) => {
2397                for a in an {
2398                    let res = match a.name.as_str() {
2399                        "test" => self.check_test_annotation(a, t, args, r),
2400                        "doc" => self.check_fn_doc_annotation(a, args),
2401
2402                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2403                    };
2404                    
2405                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2406                }
2407            }
2408
2409            RynaExpr::PrefixOperationDefinition(l, an, _, t, arg_n, arg_t, r, _) |
2410            RynaExpr::PostfixOperationDefinition(l, an, _, t, arg_n, arg_t, r, _) => {
2411                for a in an {
2412                    let res = match a.name.as_str() {
2413                        "test" => self.check_test_annotation(a, t, &vec!((arg_n.clone(), arg_t.clone())), r),
2414                        "doc" => self.check_fn_doc_annotation(a, &vec!((arg_n.clone(), arg_t.clone()))),
2415
2416                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2417                    };
2418                    
2419                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2420                }
2421            }
2422
2423            RynaExpr::BinaryOperationDefinition(l, an, _, t, arg_a, arg_b, r, _) => {
2424                for a in an {
2425                    let res = match a.name.as_str() {
2426                        "test" => self.check_test_annotation(a, t, &vec!(arg_a.clone(), arg_b.clone()), r),
2427                        "doc" => self.check_fn_doc_annotation(a, &vec!(arg_a.clone(), arg_b.clone())),
2428
2429                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2430                    };
2431                    
2432                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2433                }
2434            }
2435
2436            RynaExpr::NaryOperationDefinition(l, an, _, t, arg_a, arg_b, r, _) => {
2437                let mut all_args = vec!(arg_a.clone());
2438                all_args.extend(arg_b.iter().cloned());
2439
2440                for a in an {
2441                    let res = match a.name.as_str() {
2442                        "test" => self.check_test_annotation(a, t, &all_args, r),
2443                        "doc" => self.check_fn_doc_annotation(a, &all_args),
2444
2445                        n => Err(format!("Annotation with name {} does not exist", n.cyan()))  
2446                    };
2447                    
2448                    res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2449                }
2450            }
2451
2452            _ => { }
2453        }
2454
2455        Ok(())
2456    }
2457
2458    pub fn check_formats(&self, expr: &RynaExpr) {
2459        match expr {
2460            RynaExpr::ClassDefinition(l, _, n, ts, _, _, _) => {
2461                if let Err(warn) = check_class_name(n) {
2462                    located_ryna_warning!(l, "{}", warn);
2463                }
2464
2465                for t in ts {
2466                    if let Err(warn) = check_template_name(t) {
2467                        located_ryna_warning!(l, "{}", warn);
2468                    }
2469                }
2470            }
2471
2472            RynaExpr::FunctionDefinition(l, _, id, ts, _, _, _) => {
2473                if let Err(warn) = check_fn_name(&self.functions[*id].name) {
2474                    located_ryna_warning!(l, "{}", warn);
2475                }
2476
2477                for t in ts {
2478                    if let Err(warn) = check_template_name(t) {
2479                        located_ryna_warning!(l, "{}", warn);
2480                    }
2481                }
2482            }
2483
2484            RynaExpr::InterfaceDefinition(l, _, n, ts, fns, _, _, _) => {
2485                if let Err(warn) = check_interface_name(n) {
2486                    located_ryna_warning!(l, "{}", warn);
2487                }
2488
2489                for t in ts {
2490                    if let Err(warn) = check_template_name(t) {
2491                        located_ryna_warning!(l, "{}", warn);
2492                    }
2493                }
2494
2495                for f in fns {
2496                    if let Err(warn) = check_fn_name(&f.1) {
2497                        located_ryna_warning!(l, "{}", warn);
2498                    }
2499
2500                    for t in f.2.as_ref().unwrap_or(&vec!()) {
2501                        if let Err(warn) = check_template_name(t) {
2502                            located_ryna_warning!(l, "{}", warn);
2503                        }
2504                    }
2505                }
2506            }
2507
2508            _ => {}
2509        }
2510    }
2511
2512    pub fn static_check_expected(&self, expr: &RynaExpr, expected: &Option<Type>) -> Result<(), RynaError> {
2513        self.repeated_arguments_check(expr)?;
2514        self.invalid_type_check(expr)?;
2515        self.type_check(expr)?;
2516        self.ambiguity_check(expr)?;
2517        self.return_check(expr, expected)?;
2518        RynaContext::break_continue_check(expr, false)?;
2519        self.class_check(expr)?;
2520        self.macro_check(expr)?;
2521        self.interface_impl_check(expr)?;
2522        self.annotation_checks(expr)?;
2523        self.check_formats(expr);
2524
2525        Ok(())
2526    }
2527
2528    pub fn static_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2529        self.static_check_expected(expr, &None)
2530    }
2531}
2532
2533/*
2534                                                  ╒═════════╕
2535    ============================================= │  TESTS  │ =============================================
2536                                                  ╘═════════╛
2537*/
2538
2539#[cfg(test)]
2540mod tests {
2541    use crate::context::*;
2542
2543    #[test]
2544    fn type_checks() {
2545        let mut ctx = standard_ctx();
2546        
2547        let code_str = "
2548            let n: Int = 10;
2549
2550            let a: Int = 5 + n;
2551            let b: String = \"Test\";
2552            let c: Array<Int> = arr<Int>();
2553
2554            a = 3;
2555            b = \"Test 2\";
2556            c = arr<Int>();
2557        ".to_string();
2558
2559        ctx.parse_and_compile(&code_str).unwrap();
2560
2561        let mut ctx = standard_ctx();
2562        
2563        let code_str = "
2564            let a: String = 5;
2565        ".to_string();
2566
2567        assert!(ctx.parse_and_compile(&code_str).is_err());
2568
2569        let mut ctx = standard_ctx();
2570        
2571        let code_str = "
2572            let a: Int = 5;
2573
2574            a = \"Test\";
2575        ".to_string();
2576
2577        assert!(ctx.parse_and_compile(&code_str).is_err());
2578
2579        let mut ctx = standard_ctx();
2580        
2581        let code_str = "
2582            let a: Array<Int> = 5;
2583        ".to_string();
2584
2585        assert!(ctx.parse_and_compile(&code_str).is_err());
2586
2587        let mut ctx = standard_ctx();
2588        
2589        let code_str = "
2590            let a: Array<Int> = arr<Int>();
2591
2592            a = arr<String>();
2593        ".to_string();
2594
2595        assert!(ctx.parse_and_compile(&code_str).is_err());
2596    }
2597
2598    #[test]
2599    fn function_ambiguity_check() {
2600        let mut ctx = standard_ctx();
2601        
2602        let code_str = "
2603            fn inc(a: String) -> @String {
2604                return a;
2605            }
2606
2607            let a: Int = 5;
2608
2609            a.inc();
2610            inc(\"Test\");
2611        ".to_string();
2612
2613        ctx.parse_and_compile(&code_str).unwrap();
2614        let mut ctx = standard_ctx();
2615        
2616        let code_str = "
2617            fn test(a: Bool | String) -> String {
2618                return \"Test\";
2619            }
2620            
2621            fn test(a: Bool | Int) -> String {
2622                return \"Test\";
2623            }
2624
2625            test(true);
2626        ".to_string();
2627
2628        assert!(ctx.parse_and_compile(&code_str).is_err());
2629    }
2630
2631    #[test]
2632    fn unary_ambiguity_check() {
2633        let mut ctx = standard_ctx();
2634        
2635        let code_str = "
2636            op !(a: String) -> @String {
2637                return a;
2638            }
2639
2640            !\"Test\";
2641        ".to_string();
2642
2643        ctx.parse_and_compile(&code_str).unwrap();
2644        let mut ctx = standard_ctx();
2645        
2646        let code_str = "
2647            op !(a: Int | String) -> String {
2648                return \"Test\";
2649            }
2650            
2651            op !(a: Int | Array<*>) -> String {
2652                return \"Test\";
2653            }
2654
2655            !5;
2656        ".to_string();
2657
2658        assert!(ctx.parse_and_compile(&code_str).is_err());
2659    }
2660
2661    #[test]
2662    fn binary_ambiguity_check() {
2663        let mut ctx = standard_ctx();
2664        
2665        let code_str = "
2666            op (a: String) + (b: Bool) -> @String {
2667                return a;
2668            }
2669
2670            \"Test\" + true;
2671        ".to_string();
2672
2673        ctx.parse_and_compile(&code_str).unwrap();
2674        let mut ctx = standard_ctx();
2675        
2676        let code_str = "
2677            op (a: String) + (b: Int | Bool) -> String {
2678                return \"Test\";
2679            }
2680            
2681            op (a: String) + (b: Int | Array<*>) -> String {
2682                return \"Test\";
2683            }
2684
2685            \"Test\" + 5;
2686        ".to_string();
2687
2688        assert!(ctx.parse_and_compile(&code_str).is_err());
2689    }
2690
2691    #[test]
2692    fn nary_ambiguity_check() {
2693        let mut ctx = standard_ctx();
2694        
2695        let code_str = "
2696            op (a: String)[b: Bool] -> @String {
2697                return a;
2698            }
2699
2700            \"Test\"[true];
2701        ".to_string();
2702
2703        ctx.parse_and_compile(&code_str).unwrap();
2704        let mut ctx = standard_ctx();
2705        
2706        let code_str = "
2707            op (a: String)[b: Bool | String] -> String {
2708                return \"Test\";
2709            }
2710            
2711            op (a: String)[b: Bool | Array<*>] -> String {
2712                return \"Test\";
2713            }
2714
2715            \"Test\"[true];
2716        ".to_string();
2717
2718        assert!(ctx.parse_and_compile(&code_str).is_err());
2719    }
2720
2721    #[test]
2722    fn return_type_check() {
2723        let mut ctx = standard_ctx();
2724        
2725        let code_str = "
2726            fn test(a: String) -> @String {
2727                return a;
2728            }
2729
2730            test(\"Test\");
2731        ".to_string();
2732
2733        ctx.parse_and_compile(&code_str).unwrap();
2734        let mut ctx = standard_ctx();
2735        
2736        let code_str = "
2737            fn test(a: String) -> Int {
2738                return a;
2739            }
2740
2741            test(\"Test\");
2742        ".to_string();
2743
2744        assert!(ctx.parse_and_compile(&code_str).is_err());
2745    }
2746
2747    #[test]
2748    fn ensured_return_check() {
2749        let mut ctx = standard_ctx();
2750        
2751        let code_str = "
2752            fn test(a: String) -> @String {
2753                return a;
2754            }
2755            
2756            fn test(a: Int) -> Int {
2757                if true {
2758                    return 0;
2759                    
2760                } else {
2761                    return 1;
2762                }
2763            }
2764            
2765            fn test(a: Bool) -> Int {
2766                if true {
2767                    let a = 0;
2768                    
2769                } else {
2770                    return 1;
2771                }
2772
2773                return 0;
2774            }
2775        ".to_string();
2776
2777        ctx.parse_and_compile(&code_str).unwrap();
2778        let mut ctx = standard_ctx();
2779        
2780        let code_str = "
2781            fn test(a: Bool) -> Int {
2782                if true {
2783                    let a = 0;
2784                    
2785                } else {
2786                    return 1;
2787                }
2788            }
2789        ".to_string();
2790
2791        assert!(ctx.parse_and_compile(&code_str).is_err());
2792    }
2793
2794    #[test]
2795    fn class_check() {
2796        let mut ctx = standard_ctx();
2797        
2798        let code_str = "
2799            class Test {
2800                att_1: Int;
2801                att_2: (String, Int);
2802                att_3: Int | Array<Int>;
2803            }
2804        ".to_string();
2805
2806        ctx.parse_and_compile(&code_str).unwrap();
2807        
2808        let mut ctx = standard_ctx();
2809        
2810        let code_str = "
2811            class Test {
2812                att_1: Int;
2813                att_1: (String, Int);
2814                att_3: Int | Array<Int>;
2815            }
2816        ".to_string();
2817
2818        assert!(ctx.parse_and_compile(&code_str).is_err());
2819        
2820        let mut ctx = standard_ctx();
2821        
2822        let code_str = "
2823            class Test {
2824                syntax from Arg(1{d}, att_1) Arg(\"true\" | \"false\", att_2);
2825
2826                att_1: Int;
2827                att_2: Bool;
2828            }
2829        ".to_string();
2830
2831        ctx.parse_and_compile(&code_str).unwrap();
2832        
2833        let mut ctx = standard_ctx();
2834        
2835        let code_str = "
2836            class Test {
2837                syntax from Arg(1{d}, att_1);
2838
2839                att_1: Int;
2840                att_2: Bool;
2841            }
2842        ".to_string();
2843
2844        assert!(ctx.parse_and_compile(&code_str).is_err());
2845    }
2846}