tsz_checker/error_reporter/
generics.rs1use crate::diagnostics::{Diagnostic, diagnostic_codes, diagnostic_messages, format_message};
4use crate::state::CheckerState;
5use tsz_parser::parser::NodeIndex;
6use tsz_solver::TypeId;
7
8impl<'a> CheckerState<'a> {
9 pub fn error_generic_type_requires_type_arguments_at(
15 &mut self,
16 name: &str,
17 required_count: usize,
18 idx: NodeIndex,
19 ) {
20 if let Some(loc) = self.get_source_location(idx) {
21 let message = format_message(
22 diagnostic_messages::GENERIC_TYPE_REQUIRES_TYPE_ARGUMENT_S,
23 &[name, &required_count.to_string()],
24 );
25 self.ctx.push_diagnostic(Diagnostic::error(
27 self.ctx.file_name.clone(),
28 loc.start,
29 loc.length(),
30 message,
31 diagnostic_codes::GENERIC_TYPE_REQUIRES_TYPE_ARGUMENT_S,
32 ));
33 }
34 }
35
36 pub fn error_type_constraint_not_satisfied(
38 &mut self,
39 type_arg: TypeId,
40 constraint: TypeId,
41 idx: NodeIndex,
42 ) {
43 if type_arg == TypeId::ERROR
45 || constraint == TypeId::ERROR
46 || type_arg == TypeId::UNKNOWN
47 || constraint == TypeId::UNKNOWN
48 || type_arg == TypeId::ANY
49 || constraint == TypeId::ANY
50 {
51 return;
52 }
53
54 if tsz_solver::type_queries::contains_error_type_db(self.ctx.types, type_arg)
57 || tsz_solver::type_queries::contains_error_type_db(self.ctx.types, constraint)
58 {
59 return;
60 }
61
62 if let Some(loc) = self.get_source_location(idx) {
63 let key = (
67 loc.start,
68 diagnostic_codes::TYPE_DOES_NOT_SATISFY_THE_CONSTRAINT,
69 );
70 if self.ctx.emitted_diagnostics.contains(&key) {
71 return;
72 }
73 self.ctx.emitted_diagnostics.insert(key);
74
75 let type_str = self.format_type(type_arg);
76 let constraint_str = self.format_type(constraint);
77 let message = format_message(
78 diagnostic_messages::TYPE_DOES_NOT_SATISFY_THE_CONSTRAINT,
79 &[&type_str, &constraint_str],
80 );
81 self.ctx.diagnostics.push(Diagnostic::error(
82 self.ctx.file_name.clone(),
83 loc.start,
84 loc.length(),
85 message,
86 diagnostic_codes::TYPE_DOES_NOT_SATISFY_THE_CONSTRAINT,
87 ));
88 }
89 }
90
91 pub fn error_comparison_no_overlap(
97 &mut self,
98 left_type: TypeId,
99 right_type: TypeId,
100 is_equality: bool,
101 idx: NodeIndex,
102 ) {
103 if left_type == TypeId::ERROR
105 || right_type == TypeId::ERROR
106 || left_type == TypeId::ANY
107 || right_type == TypeId::ANY
108 || left_type == TypeId::UNKNOWN
109 || right_type == TypeId::UNKNOWN
110 {
111 return;
112 }
113
114 if let Some(loc) = self.get_source_location(idx) {
115 let left_str = self.format_type(left_type);
116 let right_str = self.format_type(right_type);
117 let result = if is_equality { "false" } else { "true" };
118 let message = format_message(
119 diagnostic_messages::THIS_COMPARISON_APPEARS_TO_BE_UNINTENTIONAL_BECAUSE_THE_TYPES_AND_HAVE_NO_OVERLA,
120 &[result, &left_str, &right_str],
121 );
122 self.ctx.diagnostics.push(Diagnostic::error(self.ctx.file_name.clone(), loc.start, loc.length(), message, diagnostic_codes::THIS_COMPARISON_APPEARS_TO_BE_UNINTENTIONAL_BECAUSE_THE_TYPES_AND_HAVE_NO_OVERLA));
123 }
124 }
125
126 pub fn error_type_assertion_no_overlap(
129 &mut self,
130 source_type: TypeId,
131 target_type: TypeId,
132 idx: NodeIndex,
133 ) {
134 if let Some(loc) = self.get_source_location(idx) {
135 let source_str = self.format_type(source_type);
136 let target_str = self.format_type(target_type);
137 let message = format_message(
138 diagnostic_messages::CONVERSION_OF_TYPE_TO_TYPE_MAY_BE_A_MISTAKE_BECAUSE_NEITHER_TYPE_SUFFICIENTLY_OV,
139 &[&source_str, &target_str],
140 );
141 self.ctx.diagnostics.push(Diagnostic::error(self.ctx.file_name.clone(), loc.start, loc.length(), message, diagnostic_codes::CONVERSION_OF_TYPE_TO_TYPE_MAY_BE_A_MISTAKE_BECAUSE_NEITHER_TYPE_SUFFICIENTLY_OV));
142 }
143 }
144
145 pub fn create_diagnostic_collector(&self) -> tsz_solver::DiagnosticCollector<'_> {
151 tsz_solver::DiagnosticCollector::new(self.ctx.types, self.ctx.file_name.as_str())
152 }
153
154 pub fn merge_diagnostics(&mut self, collector: &tsz_solver::DiagnosticCollector) {
156 for diag in collector.to_checker_diagnostics() {
157 self.ctx.diagnostics.push(diag);
158 }
159 }
160}