|
1 | 1 | use serde::Serialize; |
2 | 2 |
|
| 3 | +pub mod code { |
| 4 | + pub const MISSING_FILE_MODE: &str = "RS0001"; |
| 5 | + pub const MISSING_RETURN_TYPE: &str = "RS0002"; |
| 6 | + pub const MISSING_PARAMETER_TYPE: &str = "RS0003"; |
| 7 | + pub const UNKNOWN_EFFECT: &str = "RS0004"; |
| 8 | + pub const FILE_MODE_VIOLATION: &str = "RS0101"; |
| 9 | + pub const UNNAMED_ARGUMENT: &str = "RS0201"; |
| 10 | + pub const MISSING_DATA_EFFECT: &str = "RS0202"; |
| 11 | + pub const MANAGED_TO_LOCAL: &str = "RS0301"; |
| 12 | + pub const USE_AFTER_MANAGE: &str = "RS0401"; |
| 13 | + pub const LOCAL_VALUE_RETAINED: &str = "RS0501"; |
| 14 | + pub const FRESH_RETURN_NOT_CLEAN: &str = "RS0601"; |
| 15 | + pub const FRESHNESS_UNKNOWN: &str = "RS0602"; |
| 16 | + pub const RESOURCE_FIELD: &str = "RS0701"; |
| 17 | + pub const RESOURCE_ESCAPE: &str = "RS0702"; |
| 18 | + pub const LOCAL_CAPTURED_BY_MANAGED_CLOSURE: &str = "RS0801"; |
| 19 | + pub const TAKE_HANDLE_FIELD: &str = "RS0901"; |
| 20 | + pub const OPERATOR_OVERLOAD_ATTEMPT: &str = "RS1001"; |
| 21 | + |
| 22 | + pub const REVIEW_MODE_CHANGED: &str = "RSR001"; |
| 23 | + pub const REVIEW_FUNCTION_REMOVED: &str = "RSR002"; |
| 24 | + pub const REVIEW_FUNCTION_ADDED: &str = "RSR003"; |
| 25 | + pub const REVIEW_PARAMS_CHANGED: &str = "RSR004"; |
| 26 | + pub const REVIEW_RETURN_CHANGED: &str = "RSR005"; |
| 27 | + pub const REVIEW_EFFECTS_CHANGED: &str = "RSR006"; |
| 28 | + pub const REVIEW_TYPE_REMOVED: &str = "RSR007"; |
| 29 | + pub const REVIEW_TYPE_ADDED: &str = "RSR008"; |
| 30 | + pub const REVIEW_TYPE_KIND_CHANGED: &str = "RSR009"; |
| 31 | + pub const REVIEW_TYPE_FIELDS_CHANGED: &str = "RSR010"; |
| 32 | + pub const REVIEW_BOUNDARY_CHANGED: &str = "RSR011"; |
| 33 | +} |
| 34 | + |
3 | 35 | #[derive(Debug, Clone, PartialEq, Eq)] |
4 | 36 | pub enum Severity { |
5 | 37 | Error, |
@@ -153,87 +185,87 @@ pub fn format_diagnostics_human(diagnostics: &[Diagnostic]) -> String { |
153 | 185 |
|
154 | 186 | static DIAGNOSTIC_EXPLANATIONS: &[DiagnosticExplanation] = &[ |
155 | 187 | DiagnosticExplanation { |
156 | | - code: "RS0001", |
| 188 | + code: code::MISSING_FILE_MODE, |
157 | 189 | title: "missing file mode", |
158 | 190 | explanation: "Every RSScript source file must declare `mode: managed` or `mode: uses-local` so reviewers can see whether local ownership features are allowed.", |
159 | 191 | }, |
160 | 192 | DiagnosticExplanation { |
161 | | - code: "RS0002", |
| 193 | + code: code::MISSING_RETURN_TYPE, |
162 | 194 | title: "missing return type", |
163 | 195 | explanation: "Function signatures must spell out their return type. The checker applies this review rule broadly so API contracts do not rely on inference.", |
164 | 196 | }, |
165 | 197 | DiagnosticExplanation { |
166 | | - code: "RS0003", |
| 198 | + code: code::MISSING_PARAMETER_TYPE, |
167 | 199 | title: "missing parameter type", |
168 | 200 | explanation: "Parameters must have explicit types so call effects, freshness, and resource rules can be checked against a stable signature.", |
169 | 201 | }, |
170 | 202 | DiagnosticExplanation { |
171 | | - code: "RS0004", |
| 203 | + code: code::UNKNOWN_EFFECT, |
172 | 204 | title: "unknown effect", |
173 | 205 | explanation: "The effect list contains an effect name outside the currently recognized MVP surface.", |
174 | 206 | }, |
175 | 207 | DiagnosticExplanation { |
176 | | - code: "RS0101", |
| 208 | + code: code::FILE_MODE_VIOLATION, |
177 | 209 | title: "file mode violation", |
178 | 210 | explanation: "`mode: managed` files cannot use local-only features such as `local`, `manage`, `take`, or `ResourcePool<T>`.", |
179 | 211 | }, |
180 | 212 | DiagnosticExplanation { |
181 | | - code: "RS0201", |
| 213 | + code: code::UNNAMED_ARGUMENT, |
182 | 214 | title: "unnamed argument", |
183 | 215 | explanation: "RSScript requires named call arguments so signature and review diffs remain readable.", |
184 | 216 | }, |
185 | 217 | DiagnosticExplanation { |
186 | | - code: "RS0202", |
| 218 | + code: code::MISSING_DATA_EFFECT, |
187 | 219 | title: "missing call-site data effect", |
188 | 220 | explanation: "Arguments for non-Copy parameters must use an explicit `read`, `mut`, or `take` effect matching the callee signature.", |
189 | 221 | }, |
190 | 222 | DiagnosticExplanation { |
191 | | - code: "RS0301", |
| 223 | + code: code::MANAGED_TO_LOCAL, |
192 | 224 | title: "managed-to-local conversion", |
193 | 225 | explanation: "Managed values cannot be rebound as local values. Create the value locally at its origin if local ownership is required.", |
194 | 226 | }, |
195 | 227 | DiagnosticExplanation { |
196 | | - code: "RS0401", |
| 228 | + code: code::USE_AFTER_MANAGE, |
197 | 229 | title: "use after manage", |
198 | 230 | explanation: "`manage value` moves a local value into the managed runtime. The original local binding cannot be used afterwards on any reachable path.", |
199 | 231 | }, |
200 | 232 | DiagnosticExplanation { |
201 | | - code: "RS0501", |
| 233 | + code: code::LOCAL_VALUE_RETAINED, |
202 | 234 | title: "local value retained", |
203 | 235 | explanation: "APIs marked `effects(retains(param))` may store the argument beyond the call. Passing a clean local value directly would let local ownership escape.", |
204 | 236 | }, |
205 | 237 | DiagnosticExplanation { |
206 | | - code: "RS0601", |
| 238 | + code: code::FRESH_RETURN_NOT_CLEAN, |
207 | 239 | title: "fresh return is not clean", |
208 | 240 | explanation: "A `fresh` function may only return a newly created value, a known fresh call, or a clean local value that has not escaped through manage, take, retain, or capture.", |
209 | 241 | }, |
210 | 242 | DiagnosticExplanation { |
211 | | - code: "RS0602", |
| 243 | + code: code::FRESHNESS_UNKNOWN, |
212 | 244 | title: "freshness unknown", |
213 | 245 | explanation: "The MVP checker could not prove the returned value is fresh. Current proof support trusts clean locals, struct constructors, and known fresh calls.", |
214 | 246 | }, |
215 | 247 | DiagnosticExplanation { |
216 | | - code: "RS0701", |
| 248 | + code: code::RESOURCE_FIELD, |
217 | 249 | title: "resource field", |
218 | 250 | explanation: "Resource values cannot be stored directly in ordinary class or struct fields. Use `with` or an approved resource container such as `ResourcePool<T>`.", |
219 | 251 | }, |
220 | 252 | DiagnosticExplanation { |
221 | | - code: "RS0702", |
| 253 | + code: code::RESOURCE_ESCAPE, |
222 | 254 | title: "resource escape", |
223 | 255 | explanation: "A resource introduced by `with` must not escape the block through return, manage, retention, or managed closure capture.", |
224 | 256 | }, |
225 | 257 | DiagnosticExplanation { |
226 | | - code: "RS0801", |
| 258 | + code: code::LOCAL_CAPTURED_BY_MANAGED_CLOSURE, |
227 | 259 | title: "local captured by managed closure", |
228 | 260 | explanation: "A closure bound with `let` is managed and may outlive clean local values. Use a local/noescape callback shape instead.", |
229 | 261 | }, |
230 | 262 | DiagnosticExplanation { |
231 | | - code: "RS0901", |
| 263 | + code: code::TAKE_HANDLE_FIELD, |
232 | 264 | title: "take of handle field", |
233 | 265 | explanation: "Handle fields are managed references. They cannot be consumed with `take` as if they were inline local fields.", |
234 | 266 | }, |
235 | 267 | DiagnosticExplanation { |
236 | | - code: "RS1001", |
| 268 | + code: code::OPERATOR_OVERLOAD_ATTEMPT, |
237 | 269 | title: "operator overload attempt", |
238 | 270 | explanation: "The MVP language surface rejects likely user-defined operator overloads to keep review semantics explicit.", |
239 | 271 | }, |
|
0 commit comments