1use std::sync::Arc;
2
3use miette::{Diagnostic, NamedSource, SourceSpan};
4use thiserror::Error;
5
6use crate::syntax::names::{
7 DeclName, DimName, FieldName, FnName, IndexName, IndexVariantName, ScopedName, StructTypeName,
8 UnitName, UnitRef,
9};
10
11#[derive(Debug, Clone, Error, Diagnostic)]
13pub enum GraphcalError {
14 #[error("duplicate name `{name}`")]
15 #[diagnostic(code(graphcal::N001), help("each name must be unique within a file"))]
16 DuplicateName {
17 name: String,
18 #[source_code]
19 src: NamedSource<Arc<String>>,
20 #[label("duplicate definition here")]
21 duplicate: SourceSpan,
22 #[label("first defined here")]
23 first: SourceSpan,
24 },
25
26 #[error("{kind} `{name}` shadows a built-in name")]
27 #[diagnostic(
28 code(graphcal::N009),
29 help("choose a different name; built-in dimensions, types, and units cannot be redefined")
30 )]
31 BuiltinNameShadowed {
32 kind: &'static str,
33 name: String,
34 #[source_code]
35 src: NamedSource<Arc<String>>,
36 #[label("shadows a built-in name")]
37 span: SourceSpan,
38 },
39
40 #[error("conflicting definitions of unit `{name}` reach this file through includes")]
41 #[diagnostic(
42 code(graphcal::N010),
43 help(
44 "included modules share this file's unit scope, and two of them define `{name}` with different dimensions or scales, so references would be ambiguous — rename one of the definitions"
45 )
46 )]
47 ConflictingImportedUnit {
48 name: UnitRef,
49 #[source_code]
50 src: NamedSource<Arc<String>>,
51 #[label("import brings in a conflicting `{name}`")]
52 span: SourceSpan,
53 },
54
55 #[error("property `{property}` is not valid in {context}")]
56 #[diagnostic(code(graphcal::N011), help("{valid}"))]
57 InvalidPlotProperty {
58 property: String,
59 context: &'static str,
60 valid: String,
62 #[source_code]
63 src: NamedSource<Arc<String>>,
64 #[label("not a {context} property")]
65 span: SourceSpan,
66 },
67
68 #[error("property `{property}` expects {expected}")]
69 #[diagnostic(code(graphcal::D015))]
70 PlotPropertyTypeMismatch {
71 property: &'static str,
72 expected: &'static str,
73 found: String,
74 #[source_code]
75 src: NamedSource<Arc<String>>,
76 #[label("this is {found}")]
77 span: SourceSpan,
78 },
79
80 #[error(
81 "property `{property}` must be dimensionless, but this value has dimension {dimension}"
82 )]
83 #[diagnostic(
84 code(graphcal::D016),
85 help(
86 "plot properties are raw rendering quantities (pixels, ratios); write a plain number instead of a dimensioned value"
87 )
88 )]
89 PlotPropertyDimensioned {
90 property: &'static str,
91 dimension: String,
92 #[source_code]
93 src: NamedSource<Arc<String>>,
94 #[label("dimensioned value")]
95 span: SourceSpan,
96 },
97
98 #[error("cannot `import` plot `{name}`")]
99 #[diagnostic(
100 code(graphcal::M021),
101 help(
102 "plots are runtime sinks evaluated against an instance; request them through an include brace list instead: `include path(...).{{ {name} }}`"
103 )
104 )]
105 ImportPlotItem {
106 name: String,
107 #[source_code]
108 src: NamedSource<Arc<String>>,
109 #[label("plots cannot travel through `import`")]
110 span: SourceSpan,
111 },
112
113 #[error("attribute `hidden` does not apply to include item `{name}`")]
114 #[diagnostic(
115 code(graphcal::A018),
116 help("`#[hidden]` on an include item is only valid when the item names a plot")
117 )]
118 HiddenIncludeItemNotAPlot {
119 name: String,
120 #[source_code]
121 src: NamedSource<Arc<String>>,
122 #[label("not a plot item")]
123 span: SourceSpan,
124 },
125
126 #[error("{owner_kind} `{owner}` references unknown plot `{name}`")]
127 #[diagnostic(
128 code(graphcal::N012),
129 help("`plots:` entries must name `plot` declarations visible in this file")
130 )]
131 UnknownPlotReference {
132 owner_kind: &'static str,
133 owner: ScopedName,
134 name: ScopedName,
135 #[source_code]
136 src: NamedSource<Arc<String>>,
137 #[label("no plot with this name")]
138 span: SourceSpan,
139 },
140
141 #[error("`{name}` is a {actual_kind}, not a plot")]
142 #[diagnostic(
143 code(graphcal::N013),
144 help("{owner_kind}s compose `plot` declarations; they cannot nest other {actual_kind}s")
145 )]
146 CompositionReferencesNonPlot {
147 owner_kind: &'static str,
148 actual_kind: &'static str,
149 name: ScopedName,
150 #[source_code]
151 src: NamedSource<Arc<String>>,
152 #[label("this names a {actual_kind}")]
153 span: SourceSpan,
154 },
155
156 #[error("{owner_kind} `{owner}` lists plot `{name}` more than once")]
157 #[diagnostic(
158 code(graphcal::N014),
159 help("each plot may appear at most once in a `plots:` list")
160 )]
161 DuplicatePlotReference {
162 owner_kind: &'static str,
163 owner: ScopedName,
164 name: ScopedName,
165 #[source_code]
166 src: NamedSource<Arc<String>>,
167 #[label("duplicate entry")]
168 span: SourceSpan,
169 },
170
171 #[error("unknown graph reference `@{name}`")]
172 #[diagnostic(
173 code(graphcal::N002),
174 help("graph references must point to a `param` or `node`")
175 )]
176 UnknownGraphRef {
177 name: ScopedName,
178 #[source_code]
179 src: NamedSource<Arc<String>>,
180 #[label("not found")]
181 span: SourceSpan,
182 },
183
184 #[error("unknown constant `{name}`")]
185 #[diagnostic(
186 code(graphcal::N003),
187 help("constant references must point to a `const` or built-in constant (PI, E)")
188 )]
189 UnknownConstRef {
190 name: ScopedName,
191 #[source_code]
192 src: NamedSource<Arc<String>>,
193 #[label("not found")]
194 span: SourceSpan,
195 },
196
197 #[error("unknown function `{name}`")]
198 #[diagnostic(
199 code(graphcal::N004),
200 help("check function name and ensure it is defined")
201 )]
202 UnknownFunction {
203 name: String,
204 #[source_code]
205 src: NamedSource<Arc<String>>,
206 #[label("unknown function")]
207 span: SourceSpan,
208 },
209
210 #[error("graph reference `@{name}` not allowed in const expression")]
211 #[diagnostic(
212 code(graphcal::N005),
213 help(
214 "const expressions are evaluated at compile time and cannot reference params or nodes"
215 )
216 )]
217 GraphRefInConst {
218 name: ScopedName,
219 #[source_code]
220 src: NamedSource<Arc<String>>,
221 #[label("@ reference not allowed here")]
222 span: SourceSpan,
223 },
224
225 #[error("graph reference `@{name}` not allowed in const unit scale")]
226 #[diagnostic(
227 code(graphcal::D017),
228 help(
229 "`const unit` scales are compile-time constants; use plain `unit` for runtime-dependent units"
230 )
231 )]
232 GraphRefInConstUnit {
233 name: ScopedName,
234 #[source_code]
235 src: NamedSource<Arc<String>>,
236 #[label("@ reference not allowed in a const unit")]
237 span: SourceSpan,
238 },
239
240 #[error("non-const unit `{name}` not allowed in const expression")]
241 #[diagnostic(
242 code(graphcal::D018),
243 help(
244 "`const node` bodies and `const unit` definitions can only use prelude units, `base unit`, or `const unit` declarations; use `node` or plain `unit` for runtime-unit calculations"
245 )
246 )]
247 NonConstUnitInConst {
248 name: UnitRef,
249 #[source_code]
250 src: NamedSource<Arc<String>>,
251 #[label("unit is not const")]
252 span: SourceSpan,
253 },
254
255 #[error("graph reference `@{name}` not allowed in function body")]
256 #[diagnostic(code(graphcal::F001))]
257 GraphRefInFn {
258 name: ScopedName,
259 #[source_code]
260 src: NamedSource<Arc<String>>,
261 #[label("@ reference not allowed here")]
262 span: SourceSpan,
263 #[help]
264 help: String,
265 },
266
267 #[error("recursive function `{name}` detected")]
268 #[diagnostic(
269 code(graphcal::F002),
270 help("graphcal does not support recursive functions")
271 )]
272 RecursiveFunction {
273 name: FnName,
274 #[source_code]
275 src: NamedSource<Arc<String>>,
276 #[label("involved in recursion")]
277 span: SourceSpan,
278 },
279
280 #[error("function `{name}` expects {expected} argument(s), got {got}")]
281 #[diagnostic(code(graphcal::N006))]
282 WrongArity {
283 name: FnName,
284 expected: usize,
285 got: usize,
286 #[source_code]
287 src: NamedSource<Arc<String>>,
288 #[label("wrong number of arguments")]
289 span: SourceSpan,
290 },
291
292 #[error("function `{name}` expects {expected} generic argument(s), got {got}")]
293 #[diagnostic(
294 code(graphcal::N007),
295 help("provide all generic parameters or none (to infer)")
296 )]
297 WrongGenericArity {
298 name: FnName,
299 expected: usize,
300 got: usize,
301 #[source_code]
302 src: NamedSource<Arc<String>>,
303 #[label("wrong number of generic arguments")]
304 span: SourceSpan,
305 },
306
307 #[error(
308 "generic argument type mismatch for parameter `{param}` of function `{name}`: expected {expected} constraint, got {found}"
309 )]
310 #[diagnostic(code(graphcal::N008))]
311 GenericArgMismatch {
312 name: FnName,
313 param: String,
314 expected: String,
315 found: String,
316 #[source_code]
317 src: NamedSource<Arc<String>>,
318 #[label("this generic argument")]
319 span: SourceSpan,
320 },
321
322 #[error("cyclic dependency involving `{name}`")]
323 #[diagnostic(
324 code(graphcal::G001),
325 help("declarations cannot form dependency cycles")
326 )]
327 CyclicDependency {
328 name: String,
329 #[source_code]
330 src: NamedSource<Arc<String>>,
331 #[label("involved in cycle")]
332 span: SourceSpan,
333 },
334
335 #[error("{message}")]
336 #[diagnostic(code(graphcal::E001))]
337 EvalError {
338 message: String,
339 #[source_code]
340 src: NamedSource<Arc<String>>,
341 #[label("error here")]
342 span: SourceSpan,
343 },
344
345 #[error("internal error: {message}")]
348 #[diagnostic(
349 code(graphcal::X001),
350 help("this is a compiler bug — please report it")
351 )]
352 InternalError {
353 message: String,
354 #[source_code]
355 src: NamedSource<Arc<String>>,
356 #[label("unexpected state here")]
357 span: SourceSpan,
358 },
359
360 #[error("dimension exponent overflow")]
361 #[diagnostic(
362 code(graphcal::D010),
363 help("dimension exponents are stored as `i32`; reduce the magnitude of the exponent")
364 )]
365 DimensionOverflow {
366 #[source_code]
367 src: NamedSource<Arc<String>>,
368 #[label("overflow here")]
369 span: SourceSpan,
370 },
371
372 #[error("dimension mismatch: expected {expected}, found {found}")]
373 #[diagnostic(code(graphcal::D001))]
374 DimensionMismatch {
375 expected: String,
376 found: String,
377 #[source_code]
378 src: NamedSource<Arc<String>>,
379 #[label("has dimension {found}")]
380 span: SourceSpan,
381 #[help]
382 help: String,
383 },
384
385 #[error("mismatched index axes in {context}: {lhs} vs {rhs}")]
386 #[diagnostic(
387 code(graphcal::D011),
388 help(
389 "element-wise operands must be indexed by the same axes in the same order; a scalar operand broadcasts to every key"
390 )
391 )]
392 IndexedShapeMismatch {
393 context: String,
394 lhs: String,
395 rhs: String,
396 #[source_code]
397 src: NamedSource<Arc<String>>,
398 #[label("has type {rhs}")]
399 span: SourceSpan,
400 },
401
402 #[error("type annotation mismatch: declared {declared}, inferred {inferred}")]
403 #[diagnostic(
404 code(graphcal::D002),
405 help("the declared type must match the inferred dimension of the expression")
406 )]
407 DimensionMismatchInAnnotation {
408 declared: String,
409 inferred: String,
410 #[source_code]
411 src: NamedSource<Arc<String>>,
412 #[label("declared as {declared}")]
413 span: SourceSpan,
414 },
415
416 #[error("unknown unit `{name}`")]
417 #[diagnostic(
418 code(graphcal::D003),
419 help(
420 "a bare unit name must be declared in this file, selectively imported, or part of the prelude; units of a module imported with an alias are referenced as `alias.unit`"
421 )
422 )]
423 UnknownUnit {
424 name: UnitRef,
425 #[source_code]
426 src: NamedSource<Arc<String>>,
427 #[label("unknown unit")]
428 span: SourceSpan,
429 },
430
431 #[error("unknown dimension `{name}`")]
432 #[diagnostic(
433 code(graphcal::D004),
434 help("dimension must be declared or part of the prelude")
435 )]
436 UnknownDimension {
437 name: DimName,
438 #[source_code]
439 src: NamedSource<Arc<String>>,
440 #[label("unknown dimension")]
441 span: SourceSpan,
442 },
443
444 #[error("cyclic dimension dependency involving `{name}`")]
445 #[diagnostic(
446 code(graphcal::D008),
447 help("derived dimensions cannot form dependency cycles")
448 )]
449 CyclicDimension {
450 name: DimName,
451 #[source_code]
452 src: NamedSource<Arc<String>>,
453 #[label("involved in cycle")]
454 span: SourceSpan,
455 },
456
457 #[error("cyclic unit dependency involving `{name}`")]
458 #[diagnostic(code(graphcal::D009), help("units cannot form dependency cycles"))]
459 CyclicUnit {
460 name: UnitName,
461 #[source_code]
462 src: NamedSource<Arc<String>>,
463 #[label("involved in cycle")]
464 span: SourceSpan,
465 },
466
467 #[error("exponent in power must be a numeric literal for dimensional analysis")]
468 #[diagnostic(
469 code(graphcal::D005),
470 help("use a literal exponent like `x ^ 2.0` so dimensions can be checked at compile time")
471 )]
472 NonLiteralExponent {
473 #[source_code]
474 src: NamedSource<Arc<String>>,
475 #[label("non-literal exponent")]
476 span: SourceSpan,
477 },
478
479 #[error("conversion target dimension {target} does not match expression dimension {expr_dim}")]
480 #[diagnostic(
481 code(graphcal::D006),
482 help("the `->` conversion operator can only change units within the same dimension")
483 )]
484 ConversionDimensionMismatch {
485 target: String,
486 expr_dim: String,
487 #[source_code]
488 src: NamedSource<Arc<String>>,
489 #[label("target unit has different dimension")]
490 span: SourceSpan,
491 },
492
493 #[error("`->` cannot be applied to an expression that already has a display target")]
494 #[diagnostic(
495 code(graphcal::D012),
496 help(
497 "an expression carries at most one `->` target; remove the inner conversion — only the outermost target takes effect"
498 )
499 )]
500 NestedConversion {
501 #[source_code]
502 src: NamedSource<Arc<String>>,
503 #[label("the operand of this conversion is itself a conversion")]
504 span: SourceSpan,
505 },
506
507 #[error("`->` has no effect in this position")]
508 #[diagnostic(
509 code(graphcal::D013),
510 help(
511 "a conversion only affects how a declaration's final value is displayed; move it to the top level of the declaration (or a selected `if`/`match` branch, constructor field, map entry, for-comprehension body, or scan/unfold init), or remove it"
512 )
513 )]
514 IneffectiveConversion {
515 #[source_code]
516 src: NamedSource<Arc<String>>,
517 #[label("this conversion's display target is discarded")]
518 span: SourceSpan,
519 },
520
521 #[error("user-defined units on dimension `{dim}` are not supported")]
522 #[diagnostic(
523 code(graphcal::D014),
524 help(
525 "common units of this dimension (e.g. \u{b0}C, \u{b0}F for Temperature) are affine scales with an offset; a purely multiplicative `unit` definition would display silently wrong values. Keep values in the base unit, or model the offset explicitly in your expressions"
526 )
527 )]
528 AffineProneUnitDefinition {
529 dim: String,
530 #[source_code]
531 src: NamedSource<Arc<String>>,
532 #[label("unit defined on an affine-prone dimension")]
533 span: SourceSpan,
534 },
535
536 #[error("unknown struct type `{name}`")]
537 #[diagnostic(
538 code(graphcal::S002),
539 help("struct types must be declared with `type` before use")
540 )]
541 UnknownStructType {
542 name: String,
543 #[source_code]
544 src: NamedSource<Arc<String>>,
545 #[label("not found")]
546 span: SourceSpan,
547 },
548
549 #[error("unknown field `{field_name}` on struct `{type_name}`")]
550 #[diagnostic(code(graphcal::S003))]
551 UnknownField {
552 type_name: StructTypeName,
553 field_name: FieldName,
554 #[source_code]
555 src: NamedSource<Arc<String>>,
556 #[label("no such field")]
557 span: SourceSpan,
558 },
559
560 #[error("missing field(s) {missing:?} in construction of `{type_name}`")]
561 #[diagnostic(
562 code(graphcal::S004),
563 help("all fields are required when constructing a struct")
564 )]
565 MissingFields {
566 type_name: StructTypeName,
567 missing: Vec<FieldName>,
568 #[source_code]
569 src: NamedSource<Arc<String>>,
570 #[label("incomplete construction")]
571 span: SourceSpan,
572 },
573
574 #[error("extra field(s) {extra:?} in construction of `{type_name}`")]
575 #[diagnostic(
576 code(graphcal::S005),
577 help("only fields declared in the struct type are allowed")
578 )]
579 ExtraFields {
580 type_name: StructTypeName,
581 extra: Vec<FieldName>,
582 #[source_code]
583 src: NamedSource<Arc<String>>,
584 #[label("unexpected fields")]
585 span: SourceSpan,
586 },
587
588 #[error("field `{field_name}` of `{type_name}`: expected dimension {expected}, found {found}")]
589 #[diagnostic(code(graphcal::S006))]
590 FieldDimensionMismatch {
591 type_name: StructTypeName,
592 field_name: FieldName,
593 expected: String,
594 found: String,
595 #[source_code]
596 src: NamedSource<Arc<String>>,
597 #[label("has dimension {found}")]
598 span: SourceSpan,
599 },
600
601 #[error("cannot access field of non-struct value `{name}`")]
602 #[diagnostic(
603 code(graphcal::S007),
604 help("field access `.field` is only valid on struct values")
605 )]
606 NotAStruct {
607 name: String,
608 #[source_code]
609 src: NamedSource<Arc<String>>,
610 #[label("not a struct")]
611 span: SourceSpan,
612 },
613
614 #[error("unknown local variable `{name}`")]
615 #[diagnostic(
616 code(graphcal::S008),
617 help(
618 "local variables are introduced by `for`, `scan`, `unfold`, `match`, or function parameters"
619 )
620 )]
621 UnknownLocalRef {
622 name: String,
623 #[source_code]
624 src: NamedSource<Arc<String>>,
625 #[label("not found")]
626 span: SourceSpan,
627 },
628
629 #[error("unknown index `{name}`")]
630 #[diagnostic(
631 code(graphcal::I001),
632 help(
633 "declare with `index Name = {{ Variant1, Variant2, ... }};` or `index Name = linspace(start, end, step: step);`"
634 )
635 )]
636 UnknownIndex {
637 name: IndexName,
638 #[source_code]
639 src: NamedSource<Arc<String>>,
640 #[label("unknown index")]
641 span: SourceSpan,
642 },
643
644 #[error("unknown variant `{variant_name}` in index `{index_name}`")]
645 #[diagnostic(code(graphcal::I002))]
646 UnknownVariant {
647 index_name: IndexName,
648 variant_name: IndexVariantName,
649 #[source_code]
650 src: NamedSource<Arc<String>>,
651 #[label("not a variant of `{index_name}`")]
652 span: SourceSpan,
653 },
654
655 #[error("missing variant(s) {missing:?} in map literal for index `{index_name}`")]
656 #[diagnostic(
657 code(graphcal::I003),
658 help("map literals must cover all variants of the index")
659 )]
660 MissingVariants {
661 index_name: IndexName,
662 missing: Vec<IndexVariantName>,
663 #[source_code]
664 src: NamedSource<Arc<String>>,
665 #[label("incomplete map literal")]
666 span: SourceSpan,
667 },
668
669 #[error("extra variant(s) {extra:?} in map literal for index `{index_name}`")]
670 #[diagnostic(
671 code(graphcal::I004),
672 help("only variants declared in the index are allowed")
673 )]
674 ExtraVariants {
675 index_name: IndexName,
676 extra: Vec<IndexVariantName>,
677 #[source_code]
678 src: NamedSource<Arc<String>>,
679 #[label("unexpected variants")]
680 span: SourceSpan,
681 },
682
683 #[error("index mismatch: expected `{expected}`, found `{found}`")]
684 #[diagnostic(code(graphcal::I005))]
685 IndexMismatch {
686 expected: IndexName,
687 found: IndexName,
688 #[source_code]
689 src: NamedSource<Arc<String>>,
690 #[label("wrong index")]
691 span: SourceSpan,
692 },
693
694 #[error("file not found: {path}")]
695 #[diagnostic(code(graphcal::M000), help("check that the file path is correct"))]
696 FileNotFound { path: String },
697
698 #[error("circular import detected: {cycle}")]
699 #[diagnostic(
700 code(graphcal::M001),
701 help("files cannot import each other in a cycle")
702 )]
703 CircularImport { cycle: String },
704
705 #[error("imported file not found: {path}")]
706 #[diagnostic(code(graphcal::M002))]
707 ImportFileNotFound {
708 path: String,
709 #[source_code]
710 src: NamedSource<Arc<String>>,
711 #[label("referenced here")]
712 span: SourceSpan,
713 },
714
715 #[error("name `{name}` not found in imported file `{file_path}`")]
716 #[diagnostic(
717 code(graphcal::M003),
718 help("check that the name is declared in the imported file")
719 )]
720 ImportNameNotFound {
721 name: String,
722 file_path: String,
723 #[source_code]
724 src: NamedSource<Arc<String>>,
725 #[label("not found in imported file")]
726 span: SourceSpan,
727 },
728
729 #[error("filename `{stem}` is not a valid module name")]
730 #[diagnostic(
731 code(graphcal::M004),
732 help(
733 "module names must be lower_snake_case identifiers; use `as alias` to specify an explicit name"
734 )
735 )]
736 InvalidModuleName {
737 stem: String,
738 #[source_code]
739 src: NamedSource<Arc<String>>,
740 #[label("imported here")]
741 span: SourceSpan,
742 },
743
744 #[error("duplicate module name `{name}`")]
745 #[diagnostic(code(graphcal::M005))]
746 DuplicateModuleName {
747 name: String,
748 #[source_code]
749 src: NamedSource<Arc<String>>,
750 #[label("duplicate module import")]
751 span: SourceSpan,
752 #[label("first imported here")]
753 first: SourceSpan,
754 },
755
756 #[error("unknown module `{name}`")]
757 #[diagnostic(
758 code(graphcal::M006),
759 help("check that an `import` declaration imports this module")
760 )]
761 UnknownModule {
762 name: String,
763 #[source_code]
764 src: NamedSource<Arc<String>>,
765 #[label("unknown module")]
766 span: SourceSpan,
767 },
768
769 #[error("name `{name}` not found in module `{module}`")]
770 #[diagnostic(
771 code(graphcal::M007),
772 help("check that the name is declared in the imported file")
773 )]
774 QualifiedNameNotFound {
775 module: String,
776 name: String,
777 #[source_code]
778 src: NamedSource<Arc<String>>,
779 #[label("not found in module")]
780 span: SourceSpan,
781 },
782
783 #[error(
784 "range index `{name}`: start, end, and step must have the same dimension (found {start_dim}, {end_dim}, {step_dim})"
785 )]
786 #[diagnostic(
787 code(graphcal::I006),
788 help("all three values in range(start, end, step: step) must share the same dimension")
789 )]
790 RangeIndexDimensionMismatch {
791 name: IndexName,
792 start_dim: String,
793 end_dim: String,
794 step_dim: String,
795 #[source_code]
796 src: NamedSource<Arc<String>>,
797 #[label("dimension mismatch")]
798 span: SourceSpan,
799 },
800
801 #[error("range index `{name}`: {message}")]
802 #[diagnostic(code(graphcal::I007))]
803 RangeIndexInvalid {
804 name: IndexName,
805 message: String,
806 #[source_code]
807 src: NamedSource<Arc<String>>,
808 #[label("invalid range")]
809 span: SourceSpan,
810 },
811
812 #[error("cannot reference assert `{name}` with `@`")]
813 #[diagnostic(
814 code(graphcal::A003),
815 help("assert declarations are post-evaluation checks and cannot be referenced with `@`")
816 )]
817 GraphRefToAssert {
818 name: DeclName,
819 #[source_code]
820 src: NamedSource<Arc<String>>,
821 #[label("`@{name}` is an assert, not a param or node")]
822 span: SourceSpan,
823 },
824
825 #[error("assert body must evaluate to Bool, got {found}")]
826 #[diagnostic(
827 code(graphcal::A004),
828 help("assert declarations must have a body that evaluates to Bool")
829 )]
830 AssertBodyNotBool {
831 found: String,
832 #[source_code]
833 src: NamedSource<Arc<String>>,
834 #[label("expected Bool, found {found}")]
835 span: SourceSpan,
836 },
837
838 #[error("assumed assertion `{name}` failed")]
839 #[diagnostic(code(graphcal::A002))]
840 AssumedAssertionFailed {
841 name: DeclName,
842 #[source_code]
843 src: NamedSource<Arc<String>>,
844 #[label("this assertion failed")]
845 span: SourceSpan,
846 #[help]
847 help: String,
848 },
849
850 #[error("unknown assert `{name}` in #[assumes(...)]")]
851 #[diagnostic(
852 code(graphcal::A005),
853 help("`#[assumes(...)]` arguments must reference `assert` declarations")
854 )]
855 UnknownAssertInAssumes {
856 name: String,
857 #[source_code]
858 src: NamedSource<Arc<String>>,
859 #[label("not an assert declaration")]
860 span: SourceSpan,
861 },
862
863 #[error("`#[assumes(...)]` is not valid on `{kind}` declarations")]
864 #[diagnostic(
865 code(graphcal::A006),
866 help("`#[assumes(...)]` is only valid on `node` and `param` declarations")
867 )]
868 InvalidAssumesTarget {
869 kind: String,
870 #[source_code]
871 src: NamedSource<Arc<String>>,
872 #[label("not a node or param")]
873 span: SourceSpan,
874 },
875
876 #[error("attribute `hidden` does not apply to `{kind}` declarations")]
877 #[diagnostic(
878 code(graphcal::A017),
879 help(
880 "`#[hidden]` suppresses a plot's standalone output; it is only valid on `plot` declarations"
881 )
882 )]
883 InvalidHiddenTarget {
884 kind: String,
885 #[source_code]
886 src: NamedSource<Arc<String>>,
887 #[label("not a plot")]
888 span: SourceSpan,
889 },
890
891 #[error("unknown attribute `{name}`")]
892 #[diagnostic(
893 code(graphcal::A007),
894 help(
895 "recognized attributes are `#[assumes(...)]`, `#[expected_fail]`, `#[hidden]`, and `#[lazy]`"
896 )
897 )]
898 UnknownAttribute {
899 name: String,
900 #[source_code]
901 src: NamedSource<Arc<String>>,
902 #[label("unknown attribute")]
903 span: SourceSpan,
904 },
905
906 #[error("`#[expected_fail]` is not valid on `{kind}` declarations")]
907 #[diagnostic(
908 code(graphcal::A008),
909 help("`#[expected_fail]` is only valid on `assert` declarations")
910 )]
911 InvalidExpectedFailTarget {
912 kind: String,
913 #[source_code]
914 src: NamedSource<Arc<String>>,
915 #[label("not an assert")]
916 span: SourceSpan,
917 },
918
919 #[error(
920 "invalid argument in `#[expected_fail(...)]`: expected `Index.Variant`, `module.Index.Variant`, `#N` (range axes), or grouped variants"
921 )]
922 #[diagnostic(code(graphcal::A009))]
923 ExpectedFailInvalidArg {
924 #[source_code]
925 src: NamedSource<Arc<String>>,
926 #[label("invalid argument")]
927 span: SourceSpan,
928 },
929
930 #[error("`#[expected_fail(...)]` on non-indexed assertion")]
931 #[diagnostic(
932 code(graphcal::A010),
933 help("use `#[expected_fail]` without arguments for non-indexed assertions")
934 )]
935 ExpectedFailNotIndexed {
936 #[source_code]
937 src: NamedSource<Arc<String>>,
938 #[label("this assertion is not indexed")]
939 span: SourceSpan,
940 },
941
942 #[error("`#[expected_fail]` without arguments on indexed assertion")]
943 #[diagnostic(
944 code(graphcal::A011),
945 help(
946 "use `#[expected_fail(Index.Variant, ...)]` (qualified `module.Index.Variant` also works) to specify which variants are expected to fail; for Nat range axes use `#[expected_fail(#N, ...)]`"
947 )
948 )]
949 ExpectedFailAllOnIndexed {
950 #[source_code]
951 src: NamedSource<Arc<String>>,
952 #[label("this assertion is indexed")]
953 span: SourceSpan,
954 },
955
956 #[error("duplicate key in `#[expected_fail(...)]`")]
957 #[diagnostic(code(graphcal::A012), help("each expected-fail key must be unique"))]
958 ExpectedFailDuplicateKey {
959 #[source_code]
960 src: NamedSource<Arc<String>>,
961 #[label("duplicate expected-fail key")]
962 span: SourceSpan,
963 },
964
965 #[error("`#[expected_fail(...)]` key has the wrong index shape")]
966 #[diagnostic(
967 code(graphcal::A013),
968 help(
969 "single-index assertions require `Index.Variant` keys; multi-index assertions require full tuple keys in assertion axis order"
970 )
971 )]
972 ExpectedFailKeyShapeMismatch {
973 expected: usize,
974 found: usize,
975 #[source_code]
976 src: NamedSource<Arc<String>>,
977 #[label("expected {expected} index axis/axes, found {found}")]
978 span: SourceSpan,
979 },
980
981 #[error("`#[expected_fail(...)]` key does not belong to the assertion index")]
982 #[diagnostic(
983 code(graphcal::A014),
984 help("expected-fail keys must use the assertion's indexes in axis order")
985 )]
986 ExpectedFailKeyIndexMismatch {
987 expected: String,
988 found: String,
989 #[source_code]
990 src: NamedSource<Arc<String>>,
991 #[label("expected index `{expected}`, found `{found}`")]
992 span: SourceSpan,
993 },
994
995 #[error("`#[expected_fail(...)]` range step `#{step}` is out of bounds")]
996 #[diagnostic(
997 code(graphcal::A016),
998 help(
999 "range steps in expected-fail keys must satisfy `0 <= N < size` for a `range(size)` axis"
1000 )
1001 )]
1002 ExpectedFailRangeStepOutOfBounds {
1003 step: u64,
1004 size: u64,
1005 #[source_code]
1006 src: NamedSource<Arc<String>>,
1007 #[label("step #{step} on an axis of size {size}")]
1008 span: SourceSpan,
1009 },
1010
1011 #[error("negative tolerance in tolerance assertion")]
1012 #[diagnostic(
1013 code(graphcal::A015),
1014 help(
1015 "the tolerance in `~= expected +/- tolerance` must be non-negative; use `0` for exact-match semantics"
1016 )
1017 )]
1018 NegativeTolerance {
1019 found: String,
1020 #[source_code]
1021 src: NamedSource<Arc<String>>,
1022 #[label("tolerance is {found}")]
1023 span: SourceSpan,
1024 },
1025
1026 #[error("import path `{path}` resolves outside the project root")]
1027 #[diagnostic(
1028 code(graphcal::M008),
1029 help(
1030 "imports must reference files within the project directory tree; place a `graphcal.toml` in an ancestor directory to widen the project root"
1031 )
1032 )]
1033 ImportOutsideRoot {
1034 path: String,
1035 #[source_code]
1036 src: NamedSource<Arc<String>>,
1037 #[label("resolves outside project root")]
1038 span: SourceSpan,
1039 },
1040
1041 #[error("cannot override `{name}`: it is a {actual_kind}, not a param")]
1042 #[diagnostic(
1043 code(graphcal::O001),
1044 help("only `param` declarations can be overridden with --set")
1045 )]
1046 OverrideNotAParam {
1047 name: DeclName,
1048 actual_kind: crate::registry::resolve_types::DeclCategory,
1049 },
1050
1051 #[error("unknown parameter `{name}` in --set override")]
1052 #[diagnostic(
1053 code(graphcal::O002),
1054 help("the name must match a `param` declared in the file")
1055 )]
1056 OverrideUnknownParam { name: DeclName },
1057
1058 #[error("required param `{name}` has no value")]
1059 #[diagnostic(
1060 code(graphcal::O003),
1061 help(
1062 "provide a value via `--set '{name}=<value>'`, `--input`, or a parameterized import binding"
1063 )
1064 )]
1065 RequiredParamNotProvided {
1066 name: String,
1067 #[source_code]
1068 src: NamedSource<Arc<String>>,
1069 #[label("declared here without a default value")]
1070 span: SourceSpan,
1071 },
1072
1073 #[error("unknown param `{name}` in import binding for `{file_path}`")]
1074 #[diagnostic(
1075 code(graphcal::M009),
1076 help("param bindings must reference `param` declarations in the imported file")
1077 )]
1078 UnknownParamBinding {
1079 name: String,
1080 file_path: String,
1081 #[source_code]
1082 src: NamedSource<Arc<String>>,
1083 #[label("not a param in the imported file")]
1084 span: SourceSpan,
1085 },
1086
1087 #[error("binding target `{name}` is a {actual_kind}, not a param")]
1088 #[diagnostic(
1089 code(graphcal::M010),
1090 help("only `param` declarations can be overridden in import bindings")
1091 )]
1092 BindingNotAParam {
1093 name: String,
1094 actual_kind: String,
1095 #[source_code]
1096 src: NamedSource<Arc<String>>,
1097 #[label("targets a {actual_kind}, not a param")]
1098 span: SourceSpan,
1099 },
1100
1101 #[error("instantiated import requires an alias or selective names")]
1102 #[diagnostic(
1103 code(graphcal::M011),
1104 help("use `import \"path\"(...) as alias;` or `import \"path\"(...) {{ name1, name2 }};`")
1105 )]
1106 InstantiatedImportNeedsNamespace {
1107 #[source_code]
1108 src: NamedSource<Arc<String>>,
1109 #[label("instantiated import without alias or selective names")]
1110 span: SourceSpan,
1111 },
1112
1113 #[error("bare module import requires a graphcal.toml with [package].name")]
1114 #[diagnostic(
1115 code(graphcal::M012),
1116 help(
1117 "create a graphcal.toml file in the project root with:\n\n[package]\nname = \"your_package_name\""
1118 )
1119 )]
1120 BareImportWithoutManifest {
1121 path: String,
1122 #[source_code]
1123 src: NamedSource<Arc<String>>,
1124 #[label("bare module path requires a manifest")]
1125 span: SourceSpan,
1126 },
1127
1128 #[error("module path starts with `{path_first}` but package name is `{package_name}`")]
1129 #[diagnostic(
1130 code(graphcal::M013),
1131 help("module paths must start with the package name from graphcal.toml")
1132 )]
1133 PackageNameMismatch {
1134 path_first: String,
1135 package_name: String,
1136 #[source_code]
1137 src: NamedSource<Arc<String>>,
1138 #[label("should start with `{package_name}`")]
1139 span: SourceSpan,
1140 },
1141
1142 #[error("standard library modules are not yet implemented")]
1143 #[diagnostic(
1144 code(graphcal::M014),
1145 help(
1146 "the graphcal standard library (graphcal/math, etc.) will be available in a future release"
1147 )
1148 )]
1149 StdlibNotImplemented {
1150 path: String,
1151 #[source_code]
1152 src: NamedSource<Arc<String>>,
1153 #[label("stdlib not yet available")]
1154 span: SourceSpan,
1155 },
1156
1157 #[error("failed to parse graphcal.toml: {message}")]
1158 #[diagnostic(code(graphcal::M015))]
1159 ManifestError { message: String },
1160
1161 #[error("cross-file import `{path}` from a file outside any package")]
1162 #[diagnostic(
1163 code(graphcal::M017),
1164 help(
1165 "a Graphcal file is either part of a real package (lives at `<source_dir>/<package>.gcl` or under `<source_dir>/<package>/`) or a standalone virtual-package script. Standalone files may only reference their own top-level decls (via `import <file_stem>.{{...}};`) or their own inline DAGs. To pull symbols from a sibling file, add a `graphcal.toml` and place this file inside the package's namespace directory."
1166 )
1167 )]
1168 CrossFileImportInVirtualPackage {
1169 path: String,
1170 #[source_code]
1171 src: NamedSource<Arc<String>>,
1172 #[label("not reachable from a virtual-package file")]
1173 span: SourceSpan,
1174 },
1175
1176 #[error("binding target `{name}` is an index, not a param")]
1177 #[diagnostic(
1178 code(graphcal::M016),
1179 help("index bindings must use another index name as the value, e.g., `{name} = MyIndex`")
1180 )]
1181 BindingTargetsIndex {
1182 name: String,
1183 #[source_code]
1184 src: NamedSource<Arc<String>>,
1185 #[label("targets an index, not a param")]
1186 span: SourceSpan,
1187 },
1188
1189 #[error("index binding `{dep_index} = {value}`: `{value}` is not a known index")]
1190 #[diagnostic(
1191 code(graphcal::M017),
1192 help(
1193 "the right-hand side of an index binding must be a `cat` or `range` index declared in the importing file or its transitive imports"
1194 )
1195 )]
1196 IndexBindingNotAnIndex {
1197 dep_index: String,
1198 value: String,
1199 #[source_code]
1200 src: NamedSource<Arc<String>>,
1201 #[label("not a known index")]
1202 span: SourceSpan,
1203 },
1204
1205 #[error("index kind mismatch: `{dep_index}` is {dep_kind} but `{bound_index}` is {bound_kind}")]
1206 #[diagnostic(
1207 code(graphcal::M018),
1208 help(
1209 "named indexes (`cat`) can only be bound to named indexes; range indexes can only be bound to range indexes"
1210 )
1211 )]
1212 IndexKindMismatch {
1213 dep_index: String,
1214 dep_kind: String,
1215 bound_index: String,
1216 bound_kind: String,
1217 #[source_code]
1218 src: NamedSource<Arc<String>>,
1219 #[label("kind mismatch")]
1220 span: SourceSpan,
1221 },
1222
1223 #[error(
1224 "index dimension mismatch: `{dep_index}` requires dimension {expected_dim} but `{bound_index}` has dimension {found_dim}"
1225 )]
1226 #[diagnostic(
1227 code(graphcal::I009),
1228 help("range index bindings must have matching dimensions")
1229 )]
1230 IndexBindingDimensionMismatch {
1231 dep_index: String,
1232 expected_dim: String,
1233 bound_index: String,
1234 found_dim: String,
1235 #[source_code]
1236 src: NamedSource<Arc<String>>,
1237 #[label("dimension mismatch")]
1238 span: SourceSpan,
1239 },
1240
1241 #[error("required index `{name}` must be bound via parameterized include")]
1246 #[diagnostic(
1247 code(graphcal::I010),
1248 help("use `include \"./file.gcl\"({name}: SomeIndex)` to bind this index")
1249 )]
1250 RequiredIndexNotBound {
1251 name: String,
1252 #[source_code]
1253 src: NamedSource<Arc<String>>,
1254 #[label("required index declared here")]
1255 span: SourceSpan,
1256 },
1257
1258 #[error("cannot import runtime item `{name}`; use `include` for runtime nodes and params")]
1259 #[diagnostic(
1260 code(graphcal::M020),
1261 help(
1262 "`import` only allows compile-time items (const, dimension, unit, type, index, dag); use `include` for runtime nodes and params"
1263 )
1264 )]
1265 ImportRuntimeItem {
1266 name: String,
1267 #[source_code]
1268 src: NamedSource<Arc<String>>,
1269 #[label("runtime item cannot be imported")]
1270 span: SourceSpan,
1271 },
1272
1273 #[error("unknown timezone `{timezone}`")]
1275 #[diagnostic(
1276 code(graphcal::D007),
1277 help(
1278 "use a valid IANA timezone name like \"UTC\", \"America/New_York\", or \"Asia/Tokyo\""
1279 )
1280 )]
1281 InvalidTimezone {
1282 timezone: String,
1283 #[source_code]
1284 src: NamedSource<Arc<String>>,
1285 #[label("not a recognized IANA timezone")]
1286 span: SourceSpan,
1287 },
1288
1289 #[error("domain violation: `{name}` value {value} is {violation}")]
1290 #[diagnostic(
1291 code(graphcal::C001),
1292 help("the value must satisfy the domain constraints declared on the type")
1293 )]
1294 DomainViolation {
1295 name: String,
1296 value: String,
1297 violation: String,
1298 #[source_code]
1299 src: NamedSource<Arc<String>>,
1300 #[label("value out of declared domain")]
1301 span: SourceSpan,
1302 },
1303
1304 #[error(
1305 "domain bound dimension mismatch on `{name}`: type has dimension {type_dim}, but {bound_name} bound has dimension {bound_dim}"
1306 )]
1307 #[diagnostic(
1308 code(graphcal::C002),
1309 help("domain bounds must have the same dimension as the constrained type")
1310 )]
1311 DomainDimensionMismatch {
1312 name: String,
1313 type_dim: String,
1314 bound_name: String,
1315 bound_dim: String,
1316 #[source_code]
1317 src: NamedSource<Arc<String>>,
1318 #[label("dimension mismatch in domain bound")]
1319 span: SourceSpan,
1320 },
1321
1322 #[error("domain constraint on `{name}`: min ({min}) exceeds max ({max})")]
1323 #[diagnostic(
1324 code(graphcal::C003),
1325 help("the min bound must be less than or equal to the max bound")
1326 )]
1327 DomainMinExceedsMax {
1328 name: String,
1329 min: String,
1330 max: String,
1331 #[source_code]
1332 src: NamedSource<Arc<String>>,
1333 #[label("min > max")]
1334 span: SourceSpan,
1335 },
1336
1337 #[error("domain constraints are not valid on `{type_kind}` types")]
1338 #[diagnostic(
1339 code(graphcal::C004),
1340 help(
1341 "domain constraints (min/max) are only valid on scalar, Dimensionless, and Int types"
1342 )
1343 )]
1344 InvalidDomainTarget {
1345 type_kind: String,
1346 #[source_code]
1347 src: NamedSource<Arc<String>>,
1348 #[label("constraints not valid here")]
1349 span: SourceSpan,
1350 },
1351
1352 #[error(
1353 "domain bound on Int `{name}` must be unitless: {bound_name} bound has type {bound_type}"
1354 )]
1355 #[diagnostic(
1356 code(graphcal::C005),
1357 help("Int values are unitless; their domain bounds must be Int or dimensionless")
1358 )]
1359 IntDomainBoundNotUnitless {
1360 name: String,
1361 bound_name: String,
1362 bound_type: String,
1363 #[source_code]
1364 src: NamedSource<Arc<String>>,
1365 #[label("Int bound is not unitless")]
1366 span: SourceSpan,
1367 },
1368
1369 #[error("domain constraints are not supported on generic type arguments")]
1370 #[diagnostic(
1371 code(graphcal::C006),
1372 help(
1373 "put the constraint on the field in the struct definition, not on the generic type argument"
1374 )
1375 )]
1376 GenericTypeArgDomainConstraint {
1377 #[source_code]
1378 src: NamedSource<Arc<String>>,
1379 #[label("constraint not allowed here")]
1380 span: SourceSpan,
1381 },
1382
1383 #[error("cannot import private item `{name}` from `{file_path}`")]
1386 #[diagnostic(
1387 code(graphcal::V001),
1388 help("add `pub` to the declaration in the source file to make it importable")
1389 )]
1390 ImportPrivateItem {
1391 name: String,
1392 file_path: String,
1393 #[source_code]
1394 src: NamedSource<Arc<String>>,
1395 #[label("not visible — item is private")]
1396 span: SourceSpan,
1397 },
1398
1399 #[error("required {kind} `{name}` must be declared `pub(bind)`")]
1404 #[diagnostic(
1405 code(graphcal::V002),
1406 help(
1407 "required indexes, types, and dimensions form the bindable interface — add `pub(bind)` before the declaration"
1408 )
1409 )]
1410 RequiredItemMustBeBindable {
1411 kind: String,
1412 name: String,
1413 #[source_code]
1414 src: NamedSource<Arc<String>>,
1415 #[label("required item must be `pub(bind)`")]
1416 span: SourceSpan,
1417 },
1418
1419 #[error(
1426 "`{pub_kind}` `{pub_name}` references private {ref_kind} `{ref_name}` in its signature"
1427 )]
1428 #[diagnostic(
1429 code(graphcal::V003),
1430 help(
1431 "add `pub` to `{ref_name}` so it is visible across the include boundary, or stop exposing `{pub_name}`"
1432 )
1433 )]
1434 PrivateInPublic {
1435 pub_kind: String,
1436 pub_name: String,
1437 ref_kind: String,
1438 ref_name: String,
1439 #[source_code]
1440 src: NamedSource<Arc<String>>,
1441 #[label("references private `{ref_name}`")]
1442 ref_span: SourceSpan,
1443 #[label("visible declaration is here")]
1444 pub_span: SourceSpan,
1445 },
1446
1447 #[error(
1455 "variant literal `{index}.{variant}` of `pub(bind) index` cannot be used in the defining file"
1456 )]
1457 #[diagnostic(
1458 code(graphcal::V004),
1459 help(
1460 "pub(bind) indexes may be overridden by importers; use `param` declarations for variant-specific values, or abstract over the index via `for p : I {{ … }}`"
1461 )
1462 )]
1463 PubIndexVariantLiteral {
1464 index: String,
1465 variant: String,
1466 #[source_code]
1467 src: NamedSource<Arc<String>>,
1468 #[label("variant literal of pub(bind) index")]
1469 span: SourceSpan,
1470 },
1471
1472 #[error(
1483 "include overrides {overridden_kind} `{overridden}` but does not re-bind `{orphan_decl}`, whose default mentions `{detail}`"
1484 )]
1485 #[diagnostic(
1486 code(graphcal::V005),
1487 help(
1488 "add a binding for `{orphan_decl}` to this include, or keep `{overridden}` bound to its default"
1489 )
1490 )]
1491 IncludeMustReconcileOverride {
1492 overridden: String,
1493 overridden_kind: String,
1494 orphan_decl: String,
1495 detail: String,
1496 #[source_code]
1497 src: NamedSource<Arc<String>>,
1498 #[label("include is missing a binding for `{orphan_decl}`")]
1499 span: SourceSpan,
1500 },
1501
1502 #[error(
1513 "re-exported {reexport_kind} `{reexport_name}`'s signature references private {leaked_kind} `{leaked_name}`"
1514 )]
1515 #[diagnostic(
1516 code(graphcal::V006),
1517 help(
1518 "make `{leaked_name}` `pub` at the importing file, or drop the `pub` / `pub(..)` re-export marker on this include / import"
1519 )
1520 )]
1521 GenericsLeakage {
1522 reexport_kind: String,
1523 reexport_name: String,
1524 leaked_kind: String,
1525 leaked_name: String,
1526 #[source_code]
1527 src: NamedSource<Arc<String>>,
1528 #[label("leaks private `{leaked_name}` across the include boundary")]
1529 span: SourceSpan,
1530 },
1531
1532 #[error("unknown dag `{name}`")]
1533 #[diagnostic(
1534 code(graphcal::G002),
1535 help("the inline call references a dag that is not declared in this file")
1536 )]
1537 UnknownDag {
1538 name: String,
1539 #[source_code]
1540 src: NamedSource<Arc<String>>,
1541 #[label("unknown dag")]
1542 span: SourceSpan,
1543 },
1544
1545 #[error("unknown param `{name}` in inline dag call to `{dag_name}`")]
1546 #[diagnostic(
1547 code(graphcal::G003),
1548 help("the binding name must match a `param` declared in the called dag")
1549 )]
1550 UnknownInlineDagParam {
1551 name: String,
1552 dag_name: String,
1553 #[source_code]
1554 src: NamedSource<Arc<String>>,
1555 #[label("not a param in `{dag_name}`")]
1556 span: SourceSpan,
1557 },
1558
1559 #[error("missing required binding(s) {missing:?} in inline dag call to `{dag_name}`")]
1560 #[diagnostic(
1561 code(graphcal::G004),
1562 help("every `param` declared in the dag must be bound at each inline call site")
1563 )]
1564 MissingInlineDagBindings {
1565 missing: Vec<String>,
1566 dag_name: String,
1567 #[source_code]
1568 src: NamedSource<Arc<String>>,
1569 #[label("missing binding(s)")]
1570 span: SourceSpan,
1571 },
1572
1573 #[error("unknown output `{name}` in inline dag call to `{dag_name}`")]
1574 #[diagnostic(
1575 code(graphcal::G005),
1576 help("the projection after `).` must name a `node` declared in the called dag")
1577 )]
1578 UnknownInlineDagOutput {
1579 name: String,
1580 dag_name: String,
1581 #[source_code]
1582 src: NamedSource<Arc<String>>,
1583 #[label("not a node in `{dag_name}`")]
1584 span: SourceSpan,
1585 },
1586
1587 #[error("inline dag call binding `{param_name}`: expected {expected}, found {found}")]
1588 #[diagnostic(
1589 code(graphcal::G006),
1590 help("the binding expression must have the same type as the dag's param declaration")
1591 )]
1592 InlineDagArgDimensionMismatch {
1593 param_name: String,
1594 expected: String,
1595 found: String,
1596 #[source_code]
1597 src: NamedSource<Arc<String>>,
1598 #[label("type mismatch")]
1599 span: SourceSpan,
1600 },
1601}
1602
1603impl GraphcalError {
1604 #[must_use]
1618 #[expect(
1619 clippy::too_many_lines,
1620 reason = "exhaustive variant list; one arm per error variant"
1621 )]
1622 pub const fn named_source(&self) -> Option<&NamedSource<Arc<String>>> {
1623 let src = match self {
1624 Self::FileNotFound { .. }
1625 | Self::CircularImport { .. }
1626 | Self::ManifestError { .. }
1627 | Self::OverrideNotAParam { .. }
1628 | Self::OverrideUnknownParam { .. } => return None,
1629 Self::DuplicateName { src, .. }
1630 | Self::BuiltinNameShadowed { src, .. }
1631 | Self::ConflictingImportedUnit { src, .. }
1632 | Self::InvalidPlotProperty { src, .. }
1633 | Self::PlotPropertyTypeMismatch { src, .. }
1634 | Self::PlotPropertyDimensioned { src, .. }
1635 | Self::UnknownPlotReference { src, .. }
1636 | Self::CompositionReferencesNonPlot { src, .. }
1637 | Self::DuplicatePlotReference { src, .. }
1638 | Self::ImportPlotItem { src, .. }
1639 | Self::HiddenIncludeItemNotAPlot { src, .. }
1640 | Self::UnknownGraphRef { src, .. }
1641 | Self::UnknownConstRef { src, .. }
1642 | Self::UnknownFunction { src, .. }
1643 | Self::GraphRefInConst { src, .. }
1644 | Self::GraphRefInConstUnit { src, .. }
1645 | Self::NonConstUnitInConst { src, .. }
1646 | Self::GraphRefInFn { src, .. }
1647 | Self::RecursiveFunction { src, .. }
1648 | Self::WrongArity { src, .. }
1649 | Self::WrongGenericArity { src, .. }
1650 | Self::GenericArgMismatch { src, .. }
1651 | Self::CyclicDependency { src, .. }
1652 | Self::EvalError { src, .. }
1653 | Self::InternalError { src, .. }
1654 | Self::DimensionOverflow { src, .. }
1655 | Self::DimensionMismatch { src, .. }
1656 | Self::IndexedShapeMismatch { src, .. }
1657 | Self::DimensionMismatchInAnnotation { src, .. }
1658 | Self::UnknownUnit { src, .. }
1659 | Self::UnknownDimension { src, .. }
1660 | Self::CyclicDimension { src, .. }
1661 | Self::CyclicUnit { src, .. }
1662 | Self::NonLiteralExponent { src, .. }
1663 | Self::ConversionDimensionMismatch { src, .. }
1664 | Self::NestedConversion { src, .. }
1665 | Self::IneffectiveConversion { src, .. }
1666 | Self::AffineProneUnitDefinition { src, .. }
1667 | Self::UnknownStructType { src, .. }
1668 | Self::UnknownField { src, .. }
1669 | Self::MissingFields { src, .. }
1670 | Self::ExtraFields { src, .. }
1671 | Self::FieldDimensionMismatch { src, .. }
1672 | Self::NotAStruct { src, .. }
1673 | Self::UnknownLocalRef { src, .. }
1674 | Self::UnknownIndex { src, .. }
1675 | Self::UnknownVariant { src, .. }
1676 | Self::MissingVariants { src, .. }
1677 | Self::ExtraVariants { src, .. }
1678 | Self::IndexMismatch { src, .. }
1679 | Self::ImportFileNotFound { src, .. }
1680 | Self::ImportNameNotFound { src, .. }
1681 | Self::InvalidModuleName { src, .. }
1682 | Self::DuplicateModuleName { src, .. }
1683 | Self::UnknownModule { src, .. }
1684 | Self::QualifiedNameNotFound { src, .. }
1685 | Self::RangeIndexDimensionMismatch { src, .. }
1686 | Self::RangeIndexInvalid { src, .. }
1687 | Self::GraphRefToAssert { src, .. }
1688 | Self::AssertBodyNotBool { src, .. }
1689 | Self::AssumedAssertionFailed { src, .. }
1690 | Self::UnknownAssertInAssumes { src, .. }
1691 | Self::InvalidAssumesTarget { src, .. }
1692 | Self::InvalidHiddenTarget { src, .. }
1693 | Self::UnknownAttribute { src, .. }
1694 | Self::InvalidExpectedFailTarget { src, .. }
1695 | Self::ExpectedFailInvalidArg { src, .. }
1696 | Self::ExpectedFailNotIndexed { src, .. }
1697 | Self::ExpectedFailAllOnIndexed { src, .. }
1698 | Self::ExpectedFailDuplicateKey { src, .. }
1699 | Self::ExpectedFailKeyShapeMismatch { src, .. }
1700 | Self::ExpectedFailKeyIndexMismatch { src, .. }
1701 | Self::ExpectedFailRangeStepOutOfBounds { src, .. }
1702 | Self::NegativeTolerance { src, .. }
1703 | Self::ImportOutsideRoot { src, .. }
1704 | Self::RequiredParamNotProvided { src, .. }
1705 | Self::UnknownParamBinding { src, .. }
1706 | Self::BindingNotAParam { src, .. }
1707 | Self::InstantiatedImportNeedsNamespace { src, .. }
1708 | Self::BareImportWithoutManifest { src, .. }
1709 | Self::PackageNameMismatch { src, .. }
1710 | Self::StdlibNotImplemented { src, .. }
1711 | Self::CrossFileImportInVirtualPackage { src, .. }
1712 | Self::BindingTargetsIndex { src, .. }
1713 | Self::IndexBindingNotAnIndex { src, .. }
1714 | Self::IndexKindMismatch { src, .. }
1715 | Self::IndexBindingDimensionMismatch { src, .. }
1716 | Self::RequiredIndexNotBound { src, .. }
1717 | Self::ImportRuntimeItem { src, .. }
1718 | Self::InvalidTimezone { src, .. }
1719 | Self::DomainViolation { src, .. }
1720 | Self::DomainDimensionMismatch { src, .. }
1721 | Self::DomainMinExceedsMax { src, .. }
1722 | Self::InvalidDomainTarget { src, .. }
1723 | Self::IntDomainBoundNotUnitless { src, .. }
1724 | Self::GenericTypeArgDomainConstraint { src, .. }
1725 | Self::ImportPrivateItem { src, .. }
1726 | Self::RequiredItemMustBeBindable { src, .. }
1727 | Self::PrivateInPublic { src, .. }
1728 | Self::PubIndexVariantLiteral { src, .. }
1729 | Self::IncludeMustReconcileOverride { src, .. }
1730 | Self::GenericsLeakage { src, .. }
1731 | Self::UnknownDag { src, .. }
1732 | Self::UnknownInlineDagParam { src, .. }
1733 | Self::MissingInlineDagBindings { src, .. }
1734 | Self::UnknownInlineDagOutput { src, .. }
1735 | Self::InlineDagArgDimensionMismatch { src, .. } => src,
1736 };
1737 Some(src)
1738 }
1739}