Skip to main content

veryl_analyzer/
analyzer_error.rs

1use crate::multi_sources::{MultiSources, Source};
2use miette::{self, Diagnostic, Severity, SourceSpan};
3use std::fmt;
4use thiserror::Error;
5use veryl_parser::resource_table::StrId;
6use veryl_parser::token_range::TokenRange;
7use veryl_parser::veryl_token::TokenSource;
8
9#[derive(Error, Diagnostic, Debug, PartialEq, Eq)]
10pub enum AnalyzerError {
11    #[diagnostic(
12        severity(Error),
13        code(ambiguous_elsif),
14        help(""),
15        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
16    )]
17    #[error("elsif/else attribute is ambiguous because {cause}")]
18    AmbiguousElsif {
19        cause: String,
20        #[source_code]
21        input: MultiSources,
22        #[label("Error location")]
23        error_location: SourceSpan,
24        token_source: TokenSource,
25    },
26
27    #[diagnostic(
28        severity(Error),
29        code(anonymous_identifier_usage),
30        help(""),
31        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
32    )]
33    #[error("Anonymous identifier can't be placed at here")]
34    AnonymousIdentifierUsage {
35        #[source_code]
36        input: MultiSources,
37        #[label("Error location")]
38        error_location: SourceSpan,
39        token_source: TokenSource,
40    },
41
42    #[diagnostic(
43        severity(Error),
44        code(call_non_function),
45        help("remove call to non-function symbol"),
46        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
47    )]
48    #[error("Calling non-function symbol \"{identifier}\" which has kind \"{kind}\"")]
49    CallNonFunction {
50        identifier: String,
51        kind: String,
52        #[source_code]
53        input: MultiSources,
54        #[label("Error location")]
55        error_location: SourceSpan,
56        #[label(collection, "instantiated at")]
57        inst_context: Vec<SourceSpan>,
58        token_source: TokenSource,
59    },
60
61    #[diagnostic(
62        severity(Error),
63        code(cyclic_type_dependency),
64        help(""),
65        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
66    )]
67    #[error("Cyclic dependency between \"{start}\" and \"{end}\"")]
68    CyclicTypeDependency {
69        start: String,
70        end: String,
71        #[source_code]
72        input: MultiSources,
73        #[label("Error location")]
74        error_location: SourceSpan,
75        token_source: TokenSource,
76    },
77
78    #[diagnostic(
79        severity(Error),
80        code(duplicated_identifier),
81        help("{kind}"),
82        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
83    )]
84    #[error("\"{identifier}\" is duplicated")]
85    DuplicatedIdentifier {
86        identifier: String,
87        kind: DuplicatedIdentifierKind,
88        #[source_code]
89        input: MultiSources,
90        #[label("Error location")]
91        error_location: SourceSpan,
92        token_source: TokenSource,
93    },
94
95    #[diagnostic(
96        severity(Error),
97        code(exceed_limit),
98        help(""),
99        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
100    )]
101    #[error("exceed {kind} limit: {value}")]
102    ExceedLimit {
103        kind: ExceedLimitKind,
104        value: usize,
105        #[source_code]
106        input: MultiSources,
107        #[label("Error location")]
108        error_location: SourceSpan,
109        token_source: TokenSource,
110    },
111
112    #[diagnostic(
113        severity(Error),
114        code(fixed_type_with_signed_modifier),
115        help("remove 'signed` modifier"),
116        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
117    )]
118    #[error("'signed' modifier can't be used with fixed type")]
119    FixedTypeWithSignedModifier {
120        #[source_code]
121        input: MultiSources,
122        #[label("Error location")]
123        error_location: SourceSpan,
124        token_source: TokenSource,
125    },
126
127    #[diagnostic(
128        severity(Error),
129        code(include_failure),
130        help(""),
131        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
132    )]
133    #[error("\"{name}\" can't be read because \"{cause}\"")]
134    IncludeFailure {
135        name: String,
136        cause: String,
137        #[source_code]
138        input: MultiSources,
139        #[label("Error location")]
140        error_location: SourceSpan,
141        token_source: TokenSource,
142    },
143
144    #[diagnostic(
145        severity(Error),
146        code(incompat_proto),
147        help(""),
148        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
149    )]
150    #[error("\"{identifier}\" is incompatible with \"{proto}\" because {cause}")]
151    IncompatProto {
152        identifier: String,
153        proto: String,
154        cause: IncompatProtoKind,
155        #[source_code]
156        input: MultiSources,
157        #[label("Error location")]
158        error_location: SourceSpan,
159        token_source: TokenSource,
160    },
161
162    #[diagnostic(
163        severity(Error),
164        code(infinite_recursion),
165        help(""),
166        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
167    )]
168    #[error("infinite instance recursion is detected")]
169    InfiniteRecursion {
170        #[source_code]
171        input: MultiSources,
172        #[label("Error location")]
173        error_location: SourceSpan,
174        token_source: TokenSource,
175    },
176
177    #[diagnostic(
178        severity(Error),
179        code(invalid_assignment),
180        help("remove the assignment"),
181        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
182    )]
183    #[error("\"{identifier}\" can't be assigned because it is {kind}")]
184    InvalidAssignment {
185        identifier: String,
186        kind: String,
187        #[source_code]
188        input: MultiSources,
189        #[label("Error location")]
190        error_location: SourceSpan,
191        token_source: TokenSource,
192    },
193
194    #[diagnostic(
195        severity(Error),
196        code(invalid_cast),
197        help(""),
198        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
199    )]
200    #[error("Casting from {from} to {to} is incompatible")]
201    InvalidCast {
202        from: String,
203        to: String,
204        #[source_code]
205        input: MultiSources,
206        #[label("Error location")]
207        error_location: SourceSpan,
208        token_source: TokenSource,
209    },
210
211    #[diagnostic(
212        severity(Error),
213        code(invalid_clock),
214        help(""),
215        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
216    )]
217    #[error(
218        "\"{identifier}\" can't be used as a clock because it is not 'clock' type nor a single bit signal"
219    )]
220    InvalidClock {
221        identifier: String,
222        #[source_code]
223        input: MultiSources,
224        #[label("Error location")]
225        error_location: SourceSpan,
226        token_source: TokenSource,
227    },
228
229    #[diagnostic(
230        severity(Error),
231        code(invalid_clock_domain),
232        help("Remove the clock domain annotation"),
233        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
234    )]
235    #[error("Cannot specify clock domain annotation to module instance")]
236    InvalidClockDomain {
237        #[source_code]
238        input: MultiSources,
239        #[label("Error location")]
240        error_location: SourceSpan,
241        token_source: TokenSource,
242    },
243
244    #[diagnostic(
245        severity(Error),
246        code(invalid_connect_operand),
247        help(""),
248        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
249    )]
250    #[error("\"{identifier}\" can't be used as a connect operand because {reason}")]
251    InvalidConnectOperand {
252        identifier: String,
253        reason: InvalidConnectOperandKind,
254        #[source_code]
255        input: MultiSources,
256        #[label("Error location")]
257        error_location: SourceSpan,
258        token_source: TokenSource,
259    },
260
261    #[diagnostic(
262        severity(Error),
263        code(invalid_direction),
264        help("remove {kind} direction"),
265        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
266    )]
267    #[error("{kind} direction can't be placed at here")]
268    InvalidDirection {
269        kind: String,
270        #[source_code]
271        input: MultiSources,
272        #[label("Error location")]
273        error_location: SourceSpan,
274        token_source: TokenSource,
275    },
276
277    #[diagnostic(
278        severity(Error),
279        code(invalid_embed),
280        help(""),
281        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
282    )]
283    #[error("embed (way: {way}/lang: {lang}) can't be used at here")]
284    InvalidEmbed {
285        way: String,
286        lang: String,
287        #[source_code]
288        input: MultiSources,
289        #[label("Error location")]
290        error_location: SourceSpan,
291        token_source: TokenSource,
292    },
293
294    #[diagnostic(
295        severity(Error),
296        code(invalid_embed_identifier),
297        help(""),
298        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
299    )]
300    #[error("embed identifier can be used in (way: inline/lang: sv) code block only")]
301    InvalidEmbedIdentifier {
302        #[source_code]
303        input: MultiSources,
304        #[label("Error location")]
305        error_location: SourceSpan,
306        token_source: TokenSource,
307    },
308
309    #[diagnostic(
310        severity(Error),
311        code(invalid_enum_variant),
312        help(""),
313        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
314    )]
315    #[error("The value of enum variant \"{identifier}\" is not encoded value by {encoding}")]
316    InvalidEnumVariant {
317        identifier: String,
318        encoding: String,
319        #[source_code]
320        input: MultiSources,
321        #[label("Error location")]
322        error_location: SourceSpan,
323        token_source: TokenSource,
324    },
325
326    #[diagnostic(
327        severity(Error),
328        code(invalid_factor),
329        help("remove {kind} from expression"),
330        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
331    )]
332    #[error("{} cannot be used as a factor in an expression", match .identifier {
333        Some(x) => format!("\"{}\" of {}", x, .kind),
334        None => format!("{}", .kind),
335    })]
336    InvalidFactor {
337        identifier: Option<String>,
338        kind: String,
339        #[source_code]
340        input: MultiSources,
341        #[label("Error location")]
342        error_location: SourceSpan,
343        #[label(collection, "instantiated at")]
344        inst_context: Vec<SourceSpan>,
345        token_source: TokenSource,
346    },
347
348    #[diagnostic(
349        severity(Warning),
350        code(invalid_identifier),
351        help("follow naming rule"),
352        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
353    )]
354    #[error("\"{identifier}\" violate \"{rule}\" naming rule")]
355    InvalidIdentifier {
356        identifier: String,
357        rule: String,
358        #[source_code]
359        input: MultiSources,
360        #[label("Error location")]
361        error_location: SourceSpan,
362        token_source: TokenSource,
363    },
364
365    #[diagnostic(
366        severity(Error),
367        code(invalid_import),
368        help("fix import item"),
369        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
370    )]
371    #[error("This item can't be imported")]
372    InvalidImport {
373        #[source_code]
374        input: MultiSources,
375        #[label("Error location")]
376        error_location: SourceSpan,
377        token_source: TokenSource,
378    },
379
380    #[diagnostic(
381        severity(Warning),
382        code(invalid_logical_operand),
383        help(""),
384        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
385    )]
386    #[error("{kind} should be 1-bit value")]
387    InvalidLogicalOperand {
388        kind: String,
389        #[source_code]
390        input: MultiSources,
391        #[label("Error location")]
392        error_location: SourceSpan,
393        token_source: TokenSource,
394    },
395
396    #[diagnostic(
397        severity(Warning),
398        code(unsigned_arith_shift),
399        help("consider using logical shift (<<, >>) or casting the operand to signed"),
400        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
401    )]
402    #[error("Arithmetic shift on unsigned operand has no effect different from logical shift")]
403    UnsignedArithShift {
404        #[source_code]
405        input: MultiSources,
406        #[label("Error location")]
407        error_location: SourceSpan,
408        token_source: TokenSource,
409    },
410
411    #[diagnostic(
412        severity(Error),
413        code(invalid_lsb),
414        help("remove lsb"),
415        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
416    )]
417    #[error("lsb can't be placed at here")]
418    InvalidLsb {
419        #[source_code]
420        input: MultiSources,
421        #[label("Error location")]
422        error_location: SourceSpan,
423        token_source: TokenSource,
424    },
425
426    #[diagnostic(
427        severity(Error),
428        code(invalid_modifier),
429        help("remove the modifier"),
430        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
431    )]
432    #[error("{kind} modifier can't be used because {reason}")]
433    InvalidModifier {
434        kind: String,
435        reason: InvalidModifierKind,
436        #[source_code]
437        input: MultiSources,
438        #[label("Error location")]
439        error_location: SourceSpan,
440        token_source: TokenSource,
441    },
442
443    #[diagnostic(
444        severity(Error),
445        code(invalid_modport_item),
446        help(""),
447        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
448    )]
449    #[error("\"{identifier}\" is not a {kind}")]
450    InvalidModportItem {
451        kind: InvalidModportItemKind,
452        identifier: String,
453        #[source_code]
454        input: MultiSources,
455        #[label("Error location")]
456        error_location: SourceSpan,
457        token_source: TokenSource,
458    },
459
460    #[diagnostic(
461        severity(Error),
462        code(invalid_msb),
463        help("remove msb"),
464        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
465    )]
466    #[error("msb can't be placed at here")]
467    InvalidMsb {
468        #[source_code]
469        input: MultiSources,
470        #[label("Error location")]
471        error_location: SourceSpan,
472        token_source: TokenSource,
473    },
474
475    #[diagnostic(
476        severity(Error),
477        code(invalid_number_character),
478        help(""),
479        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
480    )]
481    #[error("{kind} number can't contain {cause}")]
482    InvalidNumberCharacter {
483        cause: char,
484        kind: String,
485        #[source_code]
486        input: MultiSources,
487        #[label("Error location")]
488        error_location: SourceSpan,
489        token_source: TokenSource,
490    },
491
492    #[diagnostic(
493        severity(Error),
494        code(invalid_operand),
495        help(""),
496        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
497    )]
498    #[error("{kind} cannot be used as a operand of {op} operator")]
499    InvalidOperand {
500        kind: String,
501        op: String,
502        #[source_code]
503        input: MultiSources,
504        #[label("Error location")]
505        error_location: SourceSpan,
506        // TODO
507        //#[label(collection, "instantiated at")]
508        //inst_context: Vec<SourceSpan>,
509        token_source: TokenSource,
510    },
511
512    #[diagnostic(
513        severity(Error),
514        code(invalid_port_default_value),
515        help(""),
516        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
517    )]
518    #[error("{kind}")]
519    InvalidPortDefaultValue {
520        kind: InvalidPortDefaultValueKind,
521        #[source_code]
522        input: MultiSources,
523        #[label("Error location")]
524        error_location: SourceSpan,
525        token_source: TokenSource,
526    },
527
528    #[diagnostic(
529        severity(Error),
530        code(invalid_reset),
531        help(""),
532        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
533    )]
534    #[error(
535        "\"{identifier}\" can't be used as a reset because it is not 'reset' type nor a single bit signal"
536    )]
537    InvalidReset {
538        identifier: String,
539        #[source_code]
540        input: MultiSources,
541        #[label("Error location")]
542        error_location: SourceSpan,
543        token_source: TokenSource,
544    },
545
546    #[diagnostic(
547        severity(Warning),
548        code(invalid_select),
549        help(""),
550        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
551    )]
552    #[error("invalid select caused by {kind}")]
553    InvalidSelect {
554        kind: InvalidSelectKind,
555        #[source_code]
556        input: MultiSources,
557        #[label("Error location")]
558        error_location: SourceSpan,
559        #[label(collection, "instantiated at")]
560        inst_context: Vec<SourceSpan>,
561        token_source: TokenSource,
562    },
563
564    #[diagnostic(
565        severity(Error),
566        code(invalid_statement),
567        help("remove {kind} statement"),
568        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
569    )]
570    #[error("{kind} statement can't be placed at here")]
571    InvalidStatement {
572        kind: String,
573        #[source_code]
574        input: MultiSources,
575        #[label("Error location")]
576        error_location: SourceSpan,
577        token_source: TokenSource,
578    },
579
580    #[diagnostic(
581        severity(Error),
582        code(invalid_test),
583        help(""),
584        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
585    )]
586    #[error("test is invalid because {cause}")]
587    InvalidTest {
588        cause: InvalidTestKind,
589        #[source_code]
590        input: MultiSources,
591        #[label("Error location")]
592        error_location: SourceSpan,
593        token_source: TokenSource,
594    },
595
596    #[diagnostic(
597        severity(Error),
598        code(invalid_tb_usage),
599        help(""),
600        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
601    )]
602    #[error("$tb component can only be used inside a test module")]
603    InvalidTbUsage {
604        #[source_code]
605        input: MultiSources,
606        #[label("Error location")]
607        error_location: SourceSpan,
608        token_source: TokenSource,
609    },
610
611    #[diagnostic(
612        severity(Error),
613        code(missing_tb_port),
614        help("add \"{port}\" port connection"),
615        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
616    )]
617    #[error("$tb component \"{name}\" requires \"{port}\" port, but it is not connected")]
618    MissingTbPort {
619        name: String,
620        port: String,
621        #[source_code]
622        input: MultiSources,
623        #[label("Error location")]
624        error_location: SourceSpan,
625        token_source: TokenSource,
626    },
627
628    #[diagnostic(
629        severity(Error),
630        code(unknown_tb_port),
631        help("remove \"{port}\" connection"),
632        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
633    )]
634    #[error("$tb component \"{name}\" has no \"{port}\" port")]
635    UnknownTbPort {
636        name: String,
637        port: String,
638        #[source_code]
639        input: MultiSources,
640        #[label("Error location")]
641        error_location: SourceSpan,
642        token_source: TokenSource,
643    },
644
645    #[diagnostic(
646        severity(Error),
647        code(invalid_type_declaration),
648        help(""),
649        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
650    )]
651    #[error("{kind} can't be declared in interface declaration")]
652    InvalidTypeDeclaration {
653        kind: String,
654        #[source_code]
655        input: MultiSources,
656        #[label("Error location")]
657        error_location: SourceSpan,
658        token_source: TokenSource,
659    },
660
661    #[diagnostic(
662        severity(Error),
663        code(invisible_identifier),
664        help(""),
665        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
666    )]
667    #[error("cannot refer indentifier \"{identifier}\" because it is invisible at here")]
668    InvisibleIndentifier {
669        identifier: String,
670        #[source_code]
671        input: MultiSources,
672        #[label("Error location")]
673        error_location: SourceSpan,
674        token_source: TokenSource,
675    },
676
677    #[diagnostic(
678        severity(Error),
679        code(last_item_with_define),
680        help(""),
681        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
682    )]
683    #[error(
684        "ifdef/ifndef/elsif/else attribute can't be used with the last item in comma-separated list"
685    )]
686    LastItemWithDefine {
687        #[source_code]
688        input: MultiSources,
689        #[label("Error location")]
690        error_location: SourceSpan,
691        token_source: TokenSource,
692    },
693
694    #[diagnostic(
695        severity(Error),
696        code(member_access_on_array),
697        help("\"{name}\" has {array_dims} array dimension(s); index all of them before accessing member \"{member}\""),
698        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
699    )]
700    #[error("\"{name}\" is an array; index it before accessing member \"{member}\"")]
701    MemberAccessOnArray {
702        name: String,
703        member: String,
704        array_dims: usize,
705        #[source_code]
706        input: MultiSources,
707        #[label("Error location")]
708        error_location: SourceSpan,
709        token_source: TokenSource,
710    },
711
712    #[diagnostic(
713        severity(Warning),
714        code(mismatch_assignment),
715        help(""),
716        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
717    )]
718    #[error("\"{src}\" can't be assigned to \"{dst}\"")]
719    MismatchAssignment {
720        src: String,
721        dst: String,
722        #[source_code]
723        input: MultiSources,
724        #[label("Error location")]
725        error_location: SourceSpan,
726        #[label(collection, "instantiated at")]
727        inst_context: Vec<SourceSpan>,
728        token_source: TokenSource,
729    },
730
731    #[diagnostic(
732        severity(Error),
733        code(non_positive_value),
734        help("positive types (p8/p16/p32/p64) can only accept values > 0"),
735        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
736    )]
737    #[error("Value {value} cannot be assigned to positive type \"{typ}\"")]
738    NonPositiveValue {
739        value: String,
740        typ: String,
741        #[source_code]
742        input: MultiSources,
743        #[label("Error location")]
744        error_location: SourceSpan,
745        token_source: TokenSource,
746    },
747
748    #[diagnostic(
749        severity(Error),
750        code(mismatch_attribute_args),
751        help(""),
752        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
753    )]
754    #[error("Arguments of \"{name}\" is expected to \"{expected}\"")]
755    MismatchAttributeArgs {
756        name: String,
757        expected: String,
758        #[source_code]
759        input: MultiSources,
760        #[label("Error location")]
761        error_location: SourceSpan,
762        token_source: TokenSource,
763    },
764
765    #[diagnostic(
766        severity(Error),
767        code(mismatch_clock_domain),
768        help(""),
769        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
770    )]
771    #[error("Clock domain crossing is detected")]
772    MismatchClockDomain {
773        clock_domain: String,
774        other_domain: String,
775        #[source_code]
776        input: MultiSources,
777        #[label("clock domain {clock_domain}")]
778        error_location: SourceSpan,
779        #[label("clock domain {other_domain}")]
780        other_location: SourceSpan,
781        token_source: TokenSource,
782    },
783
784    #[diagnostic(
785        severity(Warning),
786        code(mismatch_function_arg),
787        help(""),
788        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
789    )]
790    #[error("\"{src}\" type can't be used as an argument of function \"{name}\"")]
791    MismatchFunctionArg {
792        name: String,
793        src: String,
794        #[source_code]
795        input: MultiSources,
796        #[label("Error location")]
797        error_location: SourceSpan,
798        token_source: TokenSource,
799    },
800
801    #[diagnostic(
802        severity(Error),
803        code(mismatch_function_arity),
804        help("fix function arguments"),
805        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
806    )]
807    #[error("function \"{name}\" has {arity} arguments, but {args} arguments are supplied")]
808    MismatchFunctionArity {
809        name: String,
810        arity: usize,
811        args: usize,
812        #[source_code]
813        input: MultiSources,
814        #[label("Error location")]
815        error_location: SourceSpan,
816        token_source: TokenSource,
817    },
818
819    #[diagnostic(
820        severity(Error),
821        code(mismatch_generics_arity),
822        help("fix generics arguments"),
823        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
824    )]
825    #[error("generics \"{name}\" has {arity} generic arguments, but {args} arguments are supplied")]
826    MismatchGenericsArity {
827        name: String,
828        arity: usize,
829        args: usize,
830        #[source_code]
831        input: MultiSources,
832        #[label("Error location")]
833        error_location: SourceSpan,
834        token_source: TokenSource,
835    },
836
837    #[diagnostic(
838        severity(Error),
839        code(mismatch_type),
840        help(""),
841        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
842    )]
843    #[error("{kind}")]
844    MismatchType {
845        kind: MismatchTypeKind,
846        #[source_code]
847        input: MultiSources,
848        #[label("Error location")]
849        error_location: SourceSpan,
850        token_source: TokenSource,
851    },
852
853    #[diagnostic(
854        severity(Error),
855        code(missing_clock_domain),
856        help("add clock domain annotation"),
857        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
858    )]
859    #[error("clock domain annotation is required when there are multiple clocks")]
860    MissingClockDomain {
861        #[source_code]
862        input: MultiSources,
863        #[label("Error location")]
864        error_location: SourceSpan,
865        token_source: TokenSource,
866    },
867
868    #[diagnostic(
869        severity(Error),
870        code(missing_clock_signal),
871        help("add clock port"),
872        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
873    )]
874    #[error("clock signal is required for always_ff statement")]
875    MissingClockSignal {
876        #[source_code]
877        input: MultiSources,
878        #[label("Error location")]
879        error_location: SourceSpan,
880        token_source: TokenSource,
881    },
882
883    #[diagnostic(
884        severity(Error),
885        code(missing_default_argument),
886        help("give default argument"),
887        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
888    )]
889    #[error("missing default argument for parameter \"{identifier}\"")]
890    MissingDefaultArgument {
891        identifier: String,
892        #[source_code]
893        input: MultiSources,
894        #[label("Error location")]
895        error_location: SourceSpan,
896        token_source: TokenSource,
897    },
898
899    #[diagnostic(
900        severity(Error),
901        code(generic_inference_failed),
902        help("provide explicit generic arguments like `{identifier}::<…>(…)`, or pass an argument whose width can be determined from a variable declaration"),
903        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
904    )]
905    #[error("failed to infer generic arguments for `{identifier}`")]
906    GenericInferenceFailed {
907        identifier: String,
908        #[source_code]
909        input: MultiSources,
910        #[label("Error location")]
911        error_location: SourceSpan,
912        token_source: TokenSource,
913    },
914
915    #[diagnostic(
916        severity(Error),
917        code(type_inference_not_supported),
918        help("use a simple variable reference, sized literal, or function call; otherwise provide an explicit type annotation"),
919        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
920    )]
921    #[error("type inference is not supported for this expression")]
922    TypeInferenceNotSupported {
923        #[source_code]
924        input: MultiSources,
925        #[label("Error location")]
926        error_location: SourceSpan,
927        token_source: TokenSource,
928    },
929
930    #[diagnostic(
931        severity(Error),
932        code(type_inference_conflict),
933        help("all assignments to an untyped variable must agree on the same type"),
934        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
935    )]
936    #[error("conflicting types in inference for `{identifier}`")]
937    TypeInferenceConflict {
938        identifier: String,
939        #[source_code]
940        input: MultiSources,
941        #[label("Error location")]
942        error_location: SourceSpan,
943        token_source: TokenSource,
944    },
945
946    #[diagnostic(
947        severity(Error),
948        code(missing_if_reset),
949        help("add if_reset statement"),
950        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
951    )]
952    #[error("if_reset statement is required for always_ff with reset signal")]
953    MissingIfReset {
954        #[source_code]
955        input: MultiSources,
956        #[label("Error location")]
957        error_location: SourceSpan,
958        token_source: TokenSource,
959    },
960
961    #[diagnostic(
962        severity(Warning),
963        code(missing_port),
964        help("add \"{port}\" port"),
965        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
966    )]
967    #[error("module \"{name}\" has \"{port}\", but it is not connected")]
968    MissingPort {
969        name: String,
970        port: String,
971        #[source_code]
972        input: MultiSources,
973        #[label("Error location")]
974        error_location: SourceSpan,
975        token_source: TokenSource,
976    },
977
978    #[diagnostic(
979        severity(Error),
980        code(missing_reset_signal),
981        help("add reset port"),
982        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
983    )]
984    #[error("reset signal is required for always_ff with if_reset statement")]
985    MissingResetSignal {
986        #[source_code]
987        input: MultiSources,
988        #[label("Error location")]
989        error_location: SourceSpan,
990        token_source: TokenSource,
991    },
992
993    #[diagnostic(
994        severity(Warning),
995        code(missing_reset_statement),
996        help("add reset statement"),
997        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
998    )]
999    #[error("\"{name}\" is not reset in if_reset statement")]
1000    MissingResetStatement {
1001        name: String,
1002        #[source_code]
1003        input: MultiSources,
1004        #[label(collection, "Not reset")]
1005        error_locations: Vec<SourceSpan>,
1006        token_source: TokenSource,
1007    },
1008
1009    #[diagnostic(
1010        severity(Error),
1011        code(missing_tri),
1012        help("add tri type modifier"),
1013        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1014    )]
1015    #[error("tri type modifier is required at inout port")]
1016    MissingTri {
1017        #[source_code]
1018        input: MultiSources,
1019        #[label("Error location")]
1020        error_location: SourceSpan,
1021        token_source: TokenSource,
1022    },
1023
1024    #[diagnostic(
1025        severity(Error),
1026        code(mixed_function_argument),
1027        help("fix function arguments"),
1028        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1029    )]
1030    #[error(
1031        "positional arguments and named arguments are mixed. Both of them can't be used at the same time"
1032    )]
1033    MixedFunctionArgument {
1034        #[source_code]
1035        input: MultiSources,
1036        #[label("Error location")]
1037        error_location: SourceSpan,
1038        token_source: TokenSource,
1039    },
1040
1041    #[diagnostic(
1042        severity(Warning),
1043        code(mixed_struct_union_member),
1044        help("unify struct/union members to either 2-state member or 4-state member"),
1045        url("")
1046    )]
1047    #[error("2-state member and 4-state member are mixed in the same struct/union")]
1048    MixedStructUnionMember {
1049        #[source_code]
1050        input: MultiSources,
1051        #[label("Error location")]
1052        error_location: SourceSpan,
1053        token_source: TokenSource,
1054    },
1055
1056    #[diagnostic(
1057        severity(Error),
1058        code(multiple_assignment),
1059        help(""),
1060        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1061    )]
1062    #[error("\"{identifier}\" is assigned in multiple procedural blocks or assignment statements")]
1063    MultipleAssignment {
1064        identifier: String,
1065        #[source_code]
1066        input: MultiSources,
1067        #[label(collection, "Assigned")]
1068        error_locations: Vec<SourceSpan>,
1069        token_source: TokenSource,
1070    },
1071
1072    #[diagnostic(
1073        severity(Error),
1074        code(multiple_default),
1075        help(""),
1076        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1077    )]
1078    #[error(
1079        "\"{identifier}\" can't be used as the default {kind} because the default {kind} has already been specified."
1080    )]
1081    MultipleDefault {
1082        kind: MultipleDefaultKind,
1083        identifier: String,
1084        #[source_code]
1085        input: MultiSources,
1086        #[label("Error location")]
1087        error_location: SourceSpan,
1088        token_source: TokenSource,
1089    },
1090
1091    #[diagnostic(
1092        severity(Error),
1093        code(private_member),
1094        help(""),
1095        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1096    )]
1097    #[error("\"{name}\" is private member")]
1098    PrivateMember {
1099        name: String,
1100        #[source_code]
1101        input: MultiSources,
1102        #[label("Error location")]
1103        error_location: SourceSpan,
1104        token_source: TokenSource,
1105    },
1106
1107    #[diagnostic(
1108        severity(Error),
1109        code(private_namespace),
1110        help(""),
1111        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1112    )]
1113    #[error("\"{name}\" is private namespace")]
1114    PrivateNamespace {
1115        name: String,
1116        #[source_code]
1117        input: MultiSources,
1118        #[label("Error location")]
1119        error_location: SourceSpan,
1120        token_source: TokenSource,
1121    },
1122
1123    #[diagnostic(
1124        severity(Error),
1125        code(referring_before_definition),
1126        help("move definition before reference point"),
1127        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1128    )]
1129    #[error("\"{identifier}\" is referred before it is defined.")]
1130    ReferringBeforeDefinition {
1131        identifier: String,
1132        #[source_code]
1133        input: MultiSources,
1134        #[label("Error location")]
1135        error_location: SourceSpan,
1136        token_source: TokenSource,
1137    },
1138
1139    #[diagnostic(
1140        severity(Error),
1141        code(reserved_identifier),
1142        help("prefix `__` can't be used"),
1143        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1144    )]
1145    #[error("\"{identifier}\" is reverved for compiler usage")]
1146    ReservedIdentifier {
1147        identifier: String,
1148        #[source_code]
1149        input: MultiSources,
1150        #[label("Error location")]
1151        error_location: SourceSpan,
1152        token_source: TokenSource,
1153    },
1154
1155    #[diagnostic(
1156        severity(Error),
1157        code(sv_keyword_usage),
1158        help("Change the identifier to a non-SystemVerilog keyword"),
1159        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1160    )]
1161    #[error("SystemVerilog keyword may not be used as identifier")]
1162    SvKeywordUsage {
1163        identifier: String,
1164        #[source_code]
1165        input: MultiSources,
1166        #[label("Error location")]
1167        error_location: SourceSpan,
1168        token_source: TokenSource,
1169    },
1170
1171    #[diagnostic(
1172        severity(Error),
1173        code(sv_with_implicit_reset),
1174        help("Use types with explicit synchronisity and polarity like `reset_async_low`"),
1175        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1176    )]
1177    #[error(
1178        "Reset type with implicit synchronisity and polarity can't be connected to SystemVerilog module"
1179    )]
1180    SvWithImplicitReset {
1181        #[source_code]
1182        input: MultiSources,
1183        #[label("Error location")]
1184        error_location: SourceSpan,
1185        token_source: TokenSource,
1186    },
1187
1188    #[diagnostic(
1189        severity(Error),
1190        code(too_large_enum_variant),
1191        help(""),
1192        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1193    )]
1194    #[error(
1195        "The value of enum variant \"{identifier}\" is {value}, it is can't be represented by {width} bits"
1196    )]
1197    TooLargeEnumVariant {
1198        identifier: String,
1199        value: isize,
1200        width: usize,
1201        #[source_code]
1202        input: MultiSources,
1203        #[label("Error location")]
1204        error_location: SourceSpan,
1205        token_source: TokenSource,
1206    },
1207
1208    #[diagnostic(
1209        severity(Error),
1210        code(too_large_number),
1211        help("increase bit width"),
1212        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1213    )]
1214    #[error("number is over the maximum size of {width} bits")]
1215    TooLargeNumber {
1216        width: usize,
1217        #[source_code]
1218        input: MultiSources,
1219        #[label("Error location")]
1220        error_location: SourceSpan,
1221        token_source: TokenSource,
1222    },
1223
1224    #[diagnostic(
1225        severity(Error),
1226        code(too_much_enum_variant),
1227        help(""),
1228        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1229    )]
1230    #[error(
1231        "enum \"{identifier}\" has {number} variants, they are can't be represented by {width} bits"
1232    )]
1233    TooMuchEnumVariant {
1234        identifier: String,
1235        number: usize,
1236        width: usize,
1237        #[source_code]
1238        input: MultiSources,
1239        #[label("Error location")]
1240        error_location: SourceSpan,
1241        token_source: TokenSource,
1242    },
1243
1244    #[diagnostic(
1245        severity(Warning),
1246        code(unassign_variable),
1247        help(""),
1248        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1249    )]
1250    #[error("\"{identifier}\" is unassigned")]
1251    UnassignVariable {
1252        identifier: String,
1253        #[source_code]
1254        input: MultiSources,
1255        #[label("Error location")]
1256        error_location: SourceSpan,
1257        token_source: TokenSource,
1258    },
1259
1260    #[diagnostic(
1261        severity(Error),
1262        code(unassignable_output),
1263        help(""),
1264        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1265    )]
1266    #[error("unassignable type is connected to output port")]
1267    UnassignableOutput {
1268        #[source_code]
1269        input: MultiSources,
1270        #[label("Error location")]
1271        error_location: SourceSpan,
1272        token_source: TokenSource,
1273    },
1274
1275    #[diagnostic(
1276        severity(Warning),
1277        code(uncovered_branch),
1278        help(""),
1279        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1280    )]
1281    #[error("\"{identifier}\" is not covered by all branches, it causes latch generation")]
1282    UncoveredBranch {
1283        identifier: String,
1284        #[source_code]
1285        input: MultiSources,
1286        #[label(collection, "Covered")]
1287        error_locations: Vec<SourceSpan>,
1288        token_source: TokenSource,
1289    },
1290
1291    #[diagnostic(
1292        severity(Error),
1293        code(undefined_identifier),
1294        help(""),
1295        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1296    )]
1297    #[error("\"{identifier}\" is undefined")]
1298    UndefinedIdentifier {
1299        identifier: String,
1300        #[source_code]
1301        input: MultiSources,
1302        #[label("Error location")]
1303        error_location: SourceSpan,
1304        token_source: TokenSource,
1305    },
1306
1307    #[diagnostic(
1308        severity(Warning),
1309        code(unenclosed_inner_if_expression),
1310        help("enclose the inner if expression in parenthesis"),
1311        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1312    )]
1313    #[error("inner if expression should be enclosed in parenthesis, but is not")]
1314    UnenclosedInnerIfExpression {
1315        #[source_code]
1316        input: MultiSources,
1317        #[label("Error location")]
1318        error_location: SourceSpan,
1319        token_source: TokenSource,
1320    },
1321
1322    #[diagnostic(
1323        severity(Error),
1324        code(unevaluatable_value),
1325        help(""),
1326        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1327    )]
1328    #[error("Value, which is not evaluable at elaboration, can't be used as {kind}")]
1329    UnevaluableValue {
1330        kind: UnevaluableValueKind,
1331        #[source_code]
1332        input: MultiSources,
1333        #[label("Error location")]
1334        error_location: SourceSpan,
1335        token_source: TokenSource,
1336    },
1337
1338    #[diagnostic(
1339        severity(Error),
1340        code(unexpandable_modport),
1341        help(""),
1342        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1343    )]
1344    #[error("\"{identifier}\" can't be expanded")]
1345    UnexpandableModport {
1346        identifier: String,
1347        #[source_code]
1348        input: MultiSources,
1349        #[label("Error location")]
1350        error_location: SourceSpan,
1351        token_source: TokenSource,
1352    },
1353
1354    #[diagnostic(
1355        severity(Error),
1356        code(unknown_attribute),
1357        help(""),
1358        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1359    )]
1360    #[error("\"{name}\" is not valid attribute")]
1361    UnknownAttribute {
1362        name: String,
1363        #[source_code]
1364        input: MultiSources,
1365        #[label("Error location")]
1366        error_location: SourceSpan,
1367        token_source: TokenSource,
1368    },
1369
1370    #[diagnostic(
1371        severity(Error),
1372        code(unknown_embed_lang),
1373        help(""),
1374        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1375    )]
1376    #[error("\"{name}\" is not valid embed language")]
1377    UnknownEmbedLang {
1378        name: String,
1379        #[source_code]
1380        input: MultiSources,
1381        #[label("Error location")]
1382        error_location: SourceSpan,
1383        token_source: TokenSource,
1384    },
1385
1386    #[diagnostic(
1387        severity(Error),
1388        code(unknown_embed_way),
1389        help(""),
1390        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1391    )]
1392    #[error("\"{name}\" is not valid embed way")]
1393    UnknownEmbedWay {
1394        name: String,
1395        #[source_code]
1396        input: MultiSources,
1397        #[label("Error location")]
1398        error_location: SourceSpan,
1399        token_source: TokenSource,
1400    },
1401
1402    #[diagnostic(
1403        severity(Error),
1404        code(unknown_include_way),
1405        help(""),
1406        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1407    )]
1408    #[error("\"{name}\" is not valid include way")]
1409    UnknownIncludeWay {
1410        name: String,
1411        #[source_code]
1412        input: MultiSources,
1413        #[label("Error location")]
1414        error_location: SourceSpan,
1415        token_source: TokenSource,
1416    },
1417
1418    #[diagnostic(
1419        severity(Error),
1420        code(unknown_member),
1421        help(""),
1422        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1423    )]
1424    #[error("\"{name}\" doesn't have member \"{member}\"")]
1425    UnknownMember {
1426        name: String,
1427        member: String,
1428        #[source_code]
1429        input: MultiSources,
1430        #[label("Error location")]
1431        error_location: SourceSpan,
1432        token_source: TokenSource,
1433    },
1434
1435    #[diagnostic(
1436        severity(Error),
1437        code(unknown_msb),
1438        help(""),
1439        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1440    )]
1441    #[error("resolving msb is failed")]
1442    UnknownMsb {
1443        #[source_code]
1444        input: MultiSources,
1445        #[label("Error location")]
1446        error_location: SourceSpan,
1447        token_source: TokenSource,
1448    },
1449
1450    #[diagnostic(
1451        severity(Error),
1452        code(unknown_param),
1453        help("remove \"{param}\" param"),
1454        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1455    )]
1456    #[error("module \"{name}\" doesn't have param \"{param}\", but it is overrided")]
1457    UnknownParam {
1458        name: String,
1459        param: String,
1460        #[source_code]
1461        input: MultiSources,
1462        #[label("Error location")]
1463        error_location: SourceSpan,
1464        token_source: TokenSource,
1465    },
1466
1467    #[diagnostic(
1468        severity(Error),
1469        code(unknown_port),
1470        help("remove \"{port}\" port"),
1471        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1472    )]
1473    #[error("module \"{name}\" doesn't have port \"{port}\", but it is connected")]
1474    UnknownPort {
1475        name: String,
1476        port: String,
1477        #[source_code]
1478        input: MultiSources,
1479        #[label("Error location")]
1480        error_location: SourceSpan,
1481        token_source: TokenSource,
1482    },
1483
1484    #[diagnostic(
1485        severity(Error),
1486        code(unknown_unsafe),
1487        help(""),
1488        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1489    )]
1490    #[error("\"{name}\" is not valid unsafe identifier")]
1491    UnknownUnsafe {
1492        name: String,
1493        #[source_code]
1494        input: MultiSources,
1495        #[label("Error location")]
1496        error_location: SourceSpan,
1497        token_source: TokenSource,
1498    },
1499
1500    #[diagnostic(
1501        severity(Error),
1502        code(unresolvable_generic_expression),
1503        help(""),
1504        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1505    )]
1506    #[error("\"{identifier}\" can't be resolved from the definition of generics")]
1507    UnresolvableGenericExpression {
1508        identifier: String,
1509        #[source_code]
1510        input: MultiSources,
1511        #[label("Error location")]
1512        error_location: SourceSpan,
1513        #[label("Definition")]
1514        definition_location: SourceSpan,
1515        token_source: TokenSource,
1516    },
1517
1518    #[diagnostic(
1519        severity(Warning),
1520        code(unused_return),
1521        help("add variable assignment for function return"),
1522        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1523    )]
1524    #[error("return value of \"{identifier}\" is unused")]
1525    UnusedReturn {
1526        identifier: String,
1527        #[source_code]
1528        input: MultiSources,
1529        #[label("Error location")]
1530        error_location: SourceSpan,
1531        token_source: TokenSource,
1532    },
1533
1534    #[diagnostic(
1535        severity(Warning),
1536        code(unused_variable),
1537        help("add prefix `_` to unused variable name"),
1538        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1539    )]
1540    #[error("\"{identifier}\" is unused")]
1541    UnusedVariable {
1542        identifier: String,
1543        #[source_code]
1544        input: MultiSources,
1545        #[label("Error location")]
1546        error_location: SourceSpan,
1547        token_source: TokenSource,
1548    },
1549
1550    #[diagnostic(
1551        severity(Error),
1552        code(wrong_seperator),
1553        help("replace valid separator \"{valid_separator}\""),
1554        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1555    )]
1556    #[error("separator \"{separator}\" can't be used at here")]
1557    WrongSeparator {
1558        separator: String,
1559        valid_separator: String,
1560        #[source_code]
1561        input: MultiSources,
1562        #[label("Error location")]
1563        error_location: SourceSpan,
1564        token_source: TokenSource,
1565    },
1566
1567    #[diagnostic(
1568        severity(Error),
1569        code(invalid_wavedrom),
1570        help(""),
1571        url("https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#{}", self.code().unwrap())
1572    )]
1573    #[error("{cause}")]
1574    InvalidWavedrom {
1575        cause: InvalidWavedromKind,
1576        #[source_code]
1577        input: MultiSources,
1578        #[label("Error location")]
1579        error_location: SourceSpan,
1580        token_source: TokenSource,
1581    },
1582}
1583
1584fn source(token: &TokenRange) -> MultiSources {
1585    let path = token.beg.source.to_string();
1586    let text = token.beg.source.get_text();
1587    MultiSources {
1588        sources: vec![Source { path, text }],
1589    }
1590}
1591
1592fn source_with_context(
1593    token: &TokenRange,
1594    context: &[TokenRange],
1595) -> (MultiSources, Vec<SourceSpan>) {
1596    let path = token.beg.source.to_string();
1597    let text = token.beg.source.get_text();
1598
1599    let mut base = text.len();
1600    let mut ranges = Vec::new();
1601    let mut sources = Vec::new();
1602
1603    sources.push(Source { path, text });
1604
1605    for x in context.iter().rev() {
1606        let path = x.beg.source.to_string();
1607        let text = x.beg.source.get_text();
1608
1609        let mut range = *x;
1610        range.offset(base as u32);
1611        ranges.push(range.into());
1612
1613        base += text.len();
1614
1615        sources.push(Source { path, text });
1616    }
1617
1618    let sources = MultiSources { sources };
1619    (sources, ranges)
1620}
1621
1622impl AnalyzerError {
1623    pub fn is_error(&self) -> bool {
1624        matches!(self.severity(), Some(Severity::Error) | None)
1625    }
1626
1627    pub fn token_source(&self) -> TokenSource {
1628        match self {
1629            AnalyzerError::AmbiguousElsif { token_source, .. } => *token_source,
1630            AnalyzerError::AnonymousIdentifierUsage { token_source, .. } => *token_source,
1631            AnalyzerError::CallNonFunction { token_source, .. } => *token_source,
1632            AnalyzerError::CyclicTypeDependency { token_source, .. } => *token_source,
1633            AnalyzerError::DuplicatedIdentifier { token_source, .. } => *token_source,
1634            AnalyzerError::ExceedLimit { token_source, .. } => *token_source,
1635            AnalyzerError::FixedTypeWithSignedModifier { token_source, .. } => *token_source,
1636            AnalyzerError::IncludeFailure { token_source, .. } => *token_source,
1637            AnalyzerError::IncompatProto { token_source, .. } => *token_source,
1638            AnalyzerError::InfiniteRecursion { token_source, .. } => *token_source,
1639            AnalyzerError::InvalidAssignment { token_source, .. } => *token_source,
1640            AnalyzerError::InvalidCast { token_source, .. } => *token_source,
1641            AnalyzerError::InvalidClock { token_source, .. } => *token_source,
1642            AnalyzerError::InvalidClockDomain { token_source, .. } => *token_source,
1643            AnalyzerError::InvalidConnectOperand { token_source, .. } => *token_source,
1644            AnalyzerError::InvalidDirection { token_source, .. } => *token_source,
1645            AnalyzerError::InvalidEmbed { token_source, .. } => *token_source,
1646            AnalyzerError::InvalidEmbedIdentifier { token_source, .. } => *token_source,
1647            AnalyzerError::InvalidEnumVariant { token_source, .. } => *token_source,
1648            AnalyzerError::InvalidFactor { token_source, .. } => *token_source,
1649            AnalyzerError::InvalidIdentifier { token_source, .. } => *token_source,
1650            AnalyzerError::InvalidImport { token_source, .. } => *token_source,
1651            AnalyzerError::InvalidLogicalOperand { token_source, .. } => *token_source,
1652            AnalyzerError::UnsignedArithShift { token_source, .. } => *token_source,
1653            AnalyzerError::InvalidLsb { token_source, .. } => *token_source,
1654            AnalyzerError::InvalidModifier { token_source, .. } => *token_source,
1655            AnalyzerError::InvalidModportItem { token_source, .. } => *token_source,
1656            AnalyzerError::InvalidMsb { token_source, .. } => *token_source,
1657            AnalyzerError::InvalidNumberCharacter { token_source, .. } => *token_source,
1658            AnalyzerError::InvalidOperand { token_source, .. } => *token_source,
1659            AnalyzerError::InvalidPortDefaultValue { token_source, .. } => *token_source,
1660            AnalyzerError::InvalidReset { token_source, .. } => *token_source,
1661            AnalyzerError::InvalidSelect { token_source, .. } => *token_source,
1662            AnalyzerError::InvalidStatement { token_source, .. } => *token_source,
1663            AnalyzerError::InvalidTbUsage { token_source, .. } => *token_source,
1664            AnalyzerError::MissingTbPort { token_source, .. } => *token_source,
1665            AnalyzerError::UnknownTbPort { token_source, .. } => *token_source,
1666            AnalyzerError::InvalidTest { token_source, .. } => *token_source,
1667            AnalyzerError::InvalidTypeDeclaration { token_source, .. } => *token_source,
1668            AnalyzerError::InvisibleIndentifier { token_source, .. } => *token_source,
1669            AnalyzerError::LastItemWithDefine { token_source, .. } => *token_source,
1670            AnalyzerError::MemberAccessOnArray { token_source, .. } => *token_source,
1671            AnalyzerError::MismatchAssignment { token_source, .. } => *token_source,
1672            AnalyzerError::NonPositiveValue { token_source, .. } => *token_source,
1673            AnalyzerError::MismatchAttributeArgs { token_source, .. } => *token_source,
1674            AnalyzerError::MismatchClockDomain { token_source, .. } => *token_source,
1675            AnalyzerError::MismatchFunctionArg { token_source, .. } => *token_source,
1676            AnalyzerError::MismatchFunctionArity { token_source, .. } => *token_source,
1677            AnalyzerError::MismatchGenericsArity { token_source, .. } => *token_source,
1678            AnalyzerError::MismatchType { token_source, .. } => *token_source,
1679            AnalyzerError::MissingClockDomain { token_source, .. } => *token_source,
1680            AnalyzerError::MissingClockSignal { token_source, .. } => *token_source,
1681            AnalyzerError::MissingDefaultArgument { token_source, .. } => *token_source,
1682            AnalyzerError::MissingIfReset { token_source, .. } => *token_source,
1683            AnalyzerError::GenericInferenceFailed { token_source, .. } => *token_source,
1684            AnalyzerError::TypeInferenceConflict { token_source, .. } => *token_source,
1685            AnalyzerError::TypeInferenceNotSupported { token_source, .. } => *token_source,
1686            AnalyzerError::MissingPort { token_source, .. } => *token_source,
1687            AnalyzerError::MissingResetSignal { token_source, .. } => *token_source,
1688            AnalyzerError::MissingResetStatement { token_source, .. } => *token_source,
1689            AnalyzerError::MissingTri { token_source, .. } => *token_source,
1690            AnalyzerError::MixedFunctionArgument { token_source, .. } => *token_source,
1691            AnalyzerError::MixedStructUnionMember { token_source, .. } => *token_source,
1692            AnalyzerError::MultipleAssignment { token_source, .. } => *token_source,
1693            AnalyzerError::MultipleDefault { token_source, .. } => *token_source,
1694            AnalyzerError::PrivateMember { token_source, .. } => *token_source,
1695            AnalyzerError::PrivateNamespace { token_source, .. } => *token_source,
1696            AnalyzerError::ReferringBeforeDefinition { token_source, .. } => *token_source,
1697            AnalyzerError::ReservedIdentifier { token_source, .. } => *token_source,
1698            AnalyzerError::SvKeywordUsage { token_source, .. } => *token_source,
1699            AnalyzerError::SvWithImplicitReset { token_source, .. } => *token_source,
1700            AnalyzerError::TooLargeEnumVariant { token_source, .. } => *token_source,
1701            AnalyzerError::TooLargeNumber { token_source, .. } => *token_source,
1702            AnalyzerError::TooMuchEnumVariant { token_source, .. } => *token_source,
1703            AnalyzerError::UnassignVariable { token_source, .. } => *token_source,
1704            AnalyzerError::UnassignableOutput { token_source, .. } => *token_source,
1705            AnalyzerError::UncoveredBranch { token_source, .. } => *token_source,
1706            AnalyzerError::UndefinedIdentifier { token_source, .. } => *token_source,
1707            AnalyzerError::UnenclosedInnerIfExpression { token_source, .. } => *token_source,
1708            AnalyzerError::UnevaluableValue { token_source, .. } => *token_source,
1709            AnalyzerError::UnexpandableModport { token_source, .. } => *token_source,
1710            AnalyzerError::UnknownAttribute { token_source, .. } => *token_source,
1711            AnalyzerError::UnknownEmbedLang { token_source, .. } => *token_source,
1712            AnalyzerError::UnknownEmbedWay { token_source, .. } => *token_source,
1713            AnalyzerError::UnknownIncludeWay { token_source, .. } => *token_source,
1714            AnalyzerError::UnknownMember { token_source, .. } => *token_source,
1715            AnalyzerError::UnknownMsb { token_source, .. } => *token_source,
1716            AnalyzerError::UnknownParam { token_source, .. } => *token_source,
1717            AnalyzerError::UnknownPort { token_source, .. } => *token_source,
1718            AnalyzerError::UnknownUnsafe { token_source, .. } => *token_source,
1719            AnalyzerError::UnresolvableGenericExpression { token_source, .. } => *token_source,
1720            AnalyzerError::UnusedReturn { token_source, .. } => *token_source,
1721            AnalyzerError::UnusedVariable { token_source, .. } => *token_source,
1722            AnalyzerError::WrongSeparator { token_source, .. } => *token_source,
1723            AnalyzerError::InvalidWavedrom { token_source, .. } => *token_source,
1724        }
1725    }
1726
1727    pub fn ambiguous_elsif(cause: &str, token: &TokenRange) -> Self {
1728        AnalyzerError::AmbiguousElsif {
1729            cause: cause.to_string(),
1730            input: source(token),
1731            error_location: token.into(),
1732            token_source: token.source(),
1733        }
1734    }
1735    pub fn anonymous_identifier_usage(token: &TokenRange) -> Self {
1736        AnalyzerError::AnonymousIdentifierUsage {
1737            input: source(token),
1738            error_location: token.into(),
1739            token_source: token.source(),
1740        }
1741    }
1742    pub fn call_non_function(identifier: &str, kind: &str, token: &TokenRange) -> Self {
1743        AnalyzerError::CallNonFunction {
1744            identifier: identifier.to_string(),
1745            kind: kind.to_string(),
1746            input: source(token),
1747            error_location: token.into(),
1748            inst_context: vec![],
1749            token_source: token.source(),
1750        }
1751    }
1752    pub fn cyclic_type_dependency(start: &str, end: &str, token: &TokenRange) -> Self {
1753        AnalyzerError::CyclicTypeDependency {
1754            start: start.into(),
1755            end: end.into(),
1756            input: source(token),
1757            error_location: token.into(),
1758            token_source: token.source(),
1759        }
1760    }
1761    pub fn duplicated_identifier(
1762        identifier: &str,
1763        kind: DuplicatedIdentifierKind,
1764        token: &TokenRange,
1765    ) -> Self {
1766        AnalyzerError::DuplicatedIdentifier {
1767            identifier: identifier.to_string(),
1768            kind,
1769            input: source(token),
1770            error_location: token.into(),
1771            token_source: token.source(),
1772        }
1773    }
1774    pub fn exceed_limit(kind: ExceedLimitKind, value: usize, token: &TokenRange) -> Self {
1775        AnalyzerError::ExceedLimit {
1776            kind,
1777            value,
1778            input: source(token),
1779            error_location: token.into(),
1780            token_source: token.source(),
1781        }
1782    }
1783    pub fn fixed_type_with_signed_modifier(token: &TokenRange) -> Self {
1784        AnalyzerError::FixedTypeWithSignedModifier {
1785            input: source(token),
1786            error_location: token.into(),
1787            token_source: token.source(),
1788        }
1789    }
1790    pub fn include_failure(name: &str, cause: &str, token: &TokenRange) -> Self {
1791        AnalyzerError::IncludeFailure {
1792            name: name.to_string(),
1793            cause: cause.to_string(),
1794            input: source(token),
1795            error_location: token.into(),
1796            token_source: token.source(),
1797        }
1798    }
1799    pub fn incompat_proto(
1800        identifier: &str,
1801        proto: &str,
1802        cause: IncompatProtoKind,
1803        token: &TokenRange,
1804    ) -> Self {
1805        AnalyzerError::IncompatProto {
1806            identifier: identifier.into(),
1807            proto: proto.into(),
1808            cause,
1809            input: source(token),
1810            error_location: token.into(),
1811            token_source: token.source(),
1812        }
1813    }
1814    pub fn infinite_recursion(token: &TokenRange) -> Self {
1815        AnalyzerError::InfiniteRecursion {
1816            input: source(token),
1817            error_location: token.into(),
1818            token_source: token.source(),
1819        }
1820    }
1821    pub fn invalid_assignment(identifier: &str, kind: &str, token: &TokenRange) -> Self {
1822        AnalyzerError::InvalidAssignment {
1823            identifier: identifier.into(),
1824            kind: kind.into(),
1825            input: source(token),
1826            error_location: token.into(),
1827            token_source: token.source(),
1828        }
1829    }
1830    pub fn invalid_cast(from: &str, to: &str, token: &TokenRange) -> Self {
1831        AnalyzerError::InvalidCast {
1832            from: from.into(),
1833            to: to.into(),
1834            input: source(token),
1835            error_location: token.into(),
1836            token_source: token.source(),
1837        }
1838    }
1839    pub fn invalid_clock(identifier: &str, token: &TokenRange) -> Self {
1840        AnalyzerError::InvalidClock {
1841            identifier: identifier.into(),
1842            input: source(token),
1843            error_location: token.into(),
1844            token_source: token.source(),
1845        }
1846    }
1847    pub fn invalid_clock_domain(token: &TokenRange) -> Self {
1848        AnalyzerError::InvalidClockDomain {
1849            input: source(token),
1850            error_location: token.into(),
1851            token_source: token.source(),
1852        }
1853    }
1854    pub fn invalid_connect_operand(
1855        identifier: &str,
1856        reason: InvalidConnectOperandKind,
1857        token: &TokenRange,
1858    ) -> Self {
1859        AnalyzerError::InvalidConnectOperand {
1860            identifier: identifier.into(),
1861            reason,
1862            input: source(token),
1863            error_location: token.into(),
1864            token_source: token.source(),
1865        }
1866    }
1867    pub fn invalid_direction(kind: &str, token: &TokenRange) -> Self {
1868        AnalyzerError::InvalidDirection {
1869            kind: kind.to_string(),
1870            input: source(token),
1871            error_location: token.into(),
1872            token_source: token.source(),
1873        }
1874    }
1875    pub fn invalid_embed(way: &str, lang: &str, token: &TokenRange) -> Self {
1876        AnalyzerError::InvalidEmbed {
1877            way: way.to_string(),
1878            lang: lang.to_string(),
1879            input: source(token),
1880            error_location: token.into(),
1881            token_source: token.source(),
1882        }
1883    }
1884    pub fn invalid_embed_identifier(token: &TokenRange) -> Self {
1885        AnalyzerError::InvalidEmbedIdentifier {
1886            input: source(token),
1887            error_location: token.into(),
1888            token_source: token.source(),
1889        }
1890    }
1891    pub fn invalid_enum_variant(identifier: &str, encoding: &str, token: &TokenRange) -> Self {
1892        AnalyzerError::InvalidEnumVariant {
1893            identifier: identifier.to_string(),
1894            encoding: encoding.to_string(),
1895            input: source(token),
1896            error_location: token.into(),
1897            token_source: token.source(),
1898        }
1899    }
1900    pub fn invalid_factor(
1901        identifier: Option<&str>,
1902        kind: &str,
1903        token: &TokenRange,
1904        inst_context: &[TokenRange],
1905    ) -> Self {
1906        let (input, inst_context) = source_with_context(token, inst_context);
1907        AnalyzerError::InvalidFactor {
1908            identifier: identifier.map(|x| x.to_string()),
1909            kind: kind.to_string(),
1910            input,
1911            error_location: token.into(),
1912            inst_context,
1913            token_source: token.source(),
1914        }
1915    }
1916    pub fn invalid_identifier(identifier: &str, rule: &str, token: &TokenRange) -> Self {
1917        AnalyzerError::InvalidIdentifier {
1918            identifier: identifier.to_string(),
1919            rule: rule.to_string(),
1920            input: source(token),
1921            error_location: token.into(),
1922            token_source: token.source(),
1923        }
1924    }
1925    pub fn invalid_import(token: &TokenRange) -> Self {
1926        AnalyzerError::InvalidImport {
1927            input: source(token),
1928            error_location: token.into(),
1929            token_source: token.source(),
1930        }
1931    }
1932    pub fn invalid_logical_operand(op: bool, token: &TokenRange) -> Self {
1933        let kind = if op {
1934            "Operand of logical operator"
1935        } else {
1936            "Conditional expression"
1937        };
1938        AnalyzerError::InvalidLogicalOperand {
1939            kind: kind.to_string(),
1940            input: source(token),
1941            error_location: token.into(),
1942            token_source: token.source(),
1943        }
1944    }
1945    pub fn unsigned_arith_shift(token: &TokenRange) -> Self {
1946        AnalyzerError::UnsignedArithShift {
1947            input: source(token),
1948            error_location: token.into(),
1949            token_source: token.source(),
1950        }
1951    }
1952    pub fn invalid_lsb(token: &TokenRange) -> Self {
1953        AnalyzerError::InvalidLsb {
1954            input: source(token),
1955            error_location: token.into(),
1956            token_source: token.source(),
1957        }
1958    }
1959    pub fn invalid_modifier(kind: &str, reason: InvalidModifierKind, token: &TokenRange) -> Self {
1960        AnalyzerError::InvalidModifier {
1961            kind: kind.to_string(),
1962            reason,
1963            input: source(token),
1964            error_location: token.into(),
1965            token_source: token.source(),
1966        }
1967    }
1968    pub fn invalid_modport_item(
1969        kind: InvalidModportItemKind,
1970        identifier: &str,
1971        token: &TokenRange,
1972    ) -> Self {
1973        AnalyzerError::InvalidModportItem {
1974            kind,
1975            identifier: identifier.into(),
1976            input: source(token),
1977            error_location: token.into(),
1978            token_source: token.source(),
1979        }
1980    }
1981    pub fn invalid_msb(token: &TokenRange) -> Self {
1982        AnalyzerError::InvalidMsb {
1983            input: source(token),
1984            error_location: token.into(),
1985            token_source: token.source(),
1986        }
1987    }
1988    pub fn invalid_number_character(cause: char, kind: &str, token: &TokenRange) -> Self {
1989        AnalyzerError::InvalidNumberCharacter {
1990            cause,
1991            kind: kind.to_string(),
1992            input: source(token),
1993            error_location: token.into(),
1994            token_source: token.source(),
1995        }
1996    }
1997    pub fn invalid_operand(kind: &str, op: &str, token: &TokenRange) -> Self {
1998        AnalyzerError::InvalidOperand {
1999            kind: kind.to_string(),
2000            op: op.to_string(),
2001            input: source(token),
2002            error_location: token.into(),
2003            token_source: token.source(),
2004        }
2005    }
2006    pub fn invalid_port_default_value(
2007        kind: InvalidPortDefaultValueKind,
2008        token: &TokenRange,
2009    ) -> Self {
2010        AnalyzerError::InvalidPortDefaultValue {
2011            kind,
2012            input: source(token),
2013            error_location: token.into(),
2014            token_source: token.source(),
2015        }
2016    }
2017    pub fn invalid_reset(identifier: &str, token: &TokenRange) -> Self {
2018        AnalyzerError::InvalidReset {
2019            identifier: identifier.into(),
2020            input: source(token),
2021            error_location: token.into(),
2022            token_source: token.source(),
2023        }
2024    }
2025    pub fn invalid_select(
2026        kind: &InvalidSelectKind,
2027        token: &TokenRange,
2028        inst_context: &[TokenRange],
2029    ) -> Self {
2030        let (input, inst_context) = source_with_context(token, inst_context);
2031        AnalyzerError::InvalidSelect {
2032            kind: kind.clone(),
2033            input,
2034            error_location: token.into(),
2035            inst_context,
2036            token_source: token.source(),
2037        }
2038    }
2039    pub fn invalid_statement(kind: &str, token: &TokenRange) -> Self {
2040        AnalyzerError::InvalidStatement {
2041            kind: kind.to_string(),
2042            input: source(token),
2043            error_location: token.into(),
2044            token_source: token.source(),
2045        }
2046    }
2047    pub fn invalid_test(cause: InvalidTestKind, token: &TokenRange) -> Self {
2048        AnalyzerError::InvalidTest {
2049            cause,
2050            input: source(token),
2051            error_location: token.into(),
2052            token_source: token.source(),
2053        }
2054    }
2055    pub fn invalid_tb_usage(token: &TokenRange) -> Self {
2056        AnalyzerError::InvalidTbUsage {
2057            input: source(token),
2058            error_location: token.into(),
2059            token_source: token.source(),
2060        }
2061    }
2062    pub fn missing_tb_port(name: &str, port: &str, token: &TokenRange) -> Self {
2063        AnalyzerError::MissingTbPort {
2064            name: name.into(),
2065            port: port.into(),
2066            input: source(token),
2067            error_location: token.into(),
2068            token_source: token.source(),
2069        }
2070    }
2071    pub fn unknown_tb_port(name: &str, port: &str, token: &TokenRange) -> Self {
2072        AnalyzerError::UnknownTbPort {
2073            name: name.into(),
2074            port: port.into(),
2075            input: source(token),
2076            error_location: token.into(),
2077            token_source: token.source(),
2078        }
2079    }
2080    pub fn invalid_type_declaration(kind: &str, token: &TokenRange) -> Self {
2081        AnalyzerError::InvalidTypeDeclaration {
2082            kind: kind.into(),
2083            input: source(token),
2084            error_location: token.into(),
2085            token_source: token.source(),
2086        }
2087    }
2088    pub fn invisible_identifier(identifier: &str, token: &TokenRange) -> Self {
2089        AnalyzerError::InvisibleIndentifier {
2090            identifier: identifier.to_string(),
2091            input: source(token),
2092            error_location: token.into(),
2093            token_source: token.source(),
2094        }
2095    }
2096    pub fn last_item_with_define(token: &TokenRange) -> Self {
2097        AnalyzerError::LastItemWithDefine {
2098            input: source(token),
2099            error_location: token.into(),
2100            token_source: token.source(),
2101        }
2102    }
2103    pub fn member_access_on_array(
2104        name: &str,
2105        member: &str,
2106        array_dims: usize,
2107        token: &TokenRange,
2108    ) -> Self {
2109        AnalyzerError::MemberAccessOnArray {
2110            name: name.to_string(),
2111            member: member.to_string(),
2112            array_dims,
2113            input: source(token),
2114            error_location: token.into(),
2115            token_source: token.source(),
2116        }
2117    }
2118    pub fn mismatch_assignment(
2119        src: &str,
2120        dst: &str,
2121        token: &TokenRange,
2122        inst_context: &[TokenRange],
2123    ) -> Self {
2124        let (input, inst_context) = source_with_context(token, inst_context);
2125        AnalyzerError::MismatchAssignment {
2126            src: src.to_string(),
2127            dst: dst.to_string(),
2128            input,
2129            error_location: token.into(),
2130            inst_context,
2131            token_source: token.source(),
2132        }
2133    }
2134    pub fn non_positive_value(value: &str, typ: &str, token: &TokenRange) -> Self {
2135        AnalyzerError::NonPositiveValue {
2136            value: value.to_string(),
2137            typ: typ.to_string(),
2138            input: source(token),
2139            error_location: token.into(),
2140            token_source: token.source(),
2141        }
2142    }
2143    pub fn mismatch_attribute_args(name: &str, expected: String, token: &TokenRange) -> Self {
2144        AnalyzerError::MismatchAttributeArgs {
2145            name: name.to_string(),
2146            expected,
2147            input: source(token),
2148            error_location: token.into(),
2149            token_source: token.source(),
2150        }
2151    }
2152    pub fn mismatch_clock_domain(
2153        clock_domain: &str,
2154        other_domain: &str,
2155        token: &TokenRange,
2156        other_token: &TokenRange,
2157    ) -> Self {
2158        AnalyzerError::MismatchClockDomain {
2159            clock_domain: clock_domain.to_string(),
2160            other_domain: other_domain.to_string(),
2161            input: source(token),
2162            error_location: token.into(),
2163            other_location: other_token.into(),
2164            token_source: token.source(),
2165        }
2166    }
2167    pub fn mismatch_function_arg(name: &str, src: &str, token: &TokenRange) -> Self {
2168        AnalyzerError::MismatchFunctionArg {
2169            name: name.to_string(),
2170            src: src.to_string(),
2171            input: source(token),
2172            error_location: token.into(),
2173            token_source: token.source(),
2174        }
2175    }
2176    pub fn mismatch_function_arity(
2177        name: &str,
2178        arity: usize,
2179        args: usize,
2180        token: &TokenRange,
2181    ) -> Self {
2182        AnalyzerError::MismatchFunctionArity {
2183            name: name.to_string(),
2184            arity,
2185            args,
2186            input: source(token),
2187            error_location: token.into(),
2188            token_source: token.source(),
2189        }
2190    }
2191    pub fn mismatch_generics_arity(
2192        name: &str,
2193        arity: usize,
2194        args: usize,
2195        token: &TokenRange,
2196    ) -> Self {
2197        AnalyzerError::MismatchGenericsArity {
2198            name: name.to_string(),
2199            arity,
2200            args,
2201            input: source(token),
2202            error_location: token.into(),
2203            token_source: token.source(),
2204        }
2205    }
2206    pub fn mismatch_type(kind: MismatchTypeKind, token: &TokenRange) -> Self {
2207        AnalyzerError::MismatchType {
2208            kind,
2209            input: source(token),
2210            error_location: token.into(),
2211            token_source: token.source(),
2212        }
2213    }
2214    pub fn missing_clock_domain(token: &TokenRange) -> Self {
2215        AnalyzerError::MissingClockDomain {
2216            input: source(token),
2217            error_location: token.into(),
2218            token_source: token.source(),
2219        }
2220    }
2221    pub fn missing_clock_signal(token: &TokenRange) -> Self {
2222        AnalyzerError::MissingClockSignal {
2223            input: source(token),
2224            error_location: token.into(),
2225            token_source: token.source(),
2226        }
2227    }
2228    pub fn missing_default_argument(identifier: &str, token: &TokenRange) -> Self {
2229        AnalyzerError::MissingDefaultArgument {
2230            identifier: identifier.into(),
2231            input: source(token),
2232            error_location: token.into(),
2233            token_source: token.source(),
2234        }
2235    }
2236    pub fn generic_inference_failed(identifier: &str, token: &TokenRange) -> Self {
2237        AnalyzerError::GenericInferenceFailed {
2238            identifier: identifier.into(),
2239            input: source(token),
2240            error_location: token.into(),
2241            token_source: token.source(),
2242        }
2243    }
2244    pub fn type_inference_conflict(identifier: &str, token: &TokenRange) -> Self {
2245        AnalyzerError::TypeInferenceConflict {
2246            identifier: identifier.into(),
2247            input: source(token),
2248            error_location: token.into(),
2249            token_source: token.source(),
2250        }
2251    }
2252    pub fn type_inference_not_supported(token: &TokenRange) -> Self {
2253        AnalyzerError::TypeInferenceNotSupported {
2254            input: source(token),
2255            error_location: token.into(),
2256            token_source: token.source(),
2257        }
2258    }
2259    pub fn missing_if_reset(token: &TokenRange) -> Self {
2260        AnalyzerError::MissingIfReset {
2261            input: source(token),
2262            error_location: token.into(),
2263            token_source: token.source(),
2264        }
2265    }
2266    pub fn missing_port(name: &str, port: &str, token: &TokenRange) -> Self {
2267        AnalyzerError::MissingPort {
2268            name: name.to_string(),
2269            port: port.to_string(),
2270            input: source(token),
2271            error_location: token.into(),
2272            token_source: token.source(),
2273        }
2274    }
2275    pub fn missing_reset_signal(token: &TokenRange) -> Self {
2276        AnalyzerError::MissingResetSignal {
2277            input: source(token),
2278            error_location: token.into(),
2279            token_source: token.source(),
2280        }
2281    }
2282    pub fn missing_reset_statement(name: &str, token: &TokenRange, tokens: &[TokenRange]) -> Self {
2283        AnalyzerError::MissingResetStatement {
2284            name: name.to_string(),
2285            input: source(token),
2286            error_locations: tokens.iter().map(|x| x.into()).collect(),
2287            token_source: token.source(),
2288        }
2289    }
2290    pub fn missing_tri(token: &TokenRange) -> Self {
2291        AnalyzerError::MissingTri {
2292            input: source(token),
2293            error_location: token.into(),
2294            token_source: token.source(),
2295        }
2296    }
2297    pub fn mixed_function_argument(token: &TokenRange) -> Self {
2298        AnalyzerError::MixedFunctionArgument {
2299            input: source(token),
2300            error_location: token.into(),
2301            token_source: token.source(),
2302        }
2303    }
2304    pub fn mixed_struct_union_member(token: &TokenRange) -> Self {
2305        AnalyzerError::MixedStructUnionMember {
2306            input: source(token),
2307            error_location: token.into(),
2308            token_source: token.source(),
2309        }
2310    }
2311    pub fn multiple_assignment(
2312        identifier: &str,
2313        token: &TokenRange,
2314        assigned: &[TokenRange],
2315    ) -> Self {
2316        AnalyzerError::MultipleAssignment {
2317            identifier: identifier.to_string(),
2318            input: source(token),
2319            error_locations: assigned.iter().map(|x| x.into()).collect(),
2320            token_source: token.source(),
2321        }
2322    }
2323    pub fn multiple_default(
2324        kind: MultipleDefaultKind,
2325        identifier: &str,
2326        token: &TokenRange,
2327    ) -> Self {
2328        AnalyzerError::MultipleDefault {
2329            kind,
2330            identifier: identifier.into(),
2331            input: source(token),
2332            error_location: token.into(),
2333            token_source: token.source(),
2334        }
2335    }
2336    pub fn private_member(name: &str, token: &TokenRange) -> Self {
2337        AnalyzerError::PrivateMember {
2338            name: name.to_string(),
2339            input: source(token),
2340            error_location: token.into(),
2341            token_source: token.source(),
2342        }
2343    }
2344    pub fn private_namespace(name: &str, token: &TokenRange) -> Self {
2345        AnalyzerError::PrivateNamespace {
2346            name: name.to_string(),
2347            input: source(token),
2348            error_location: token.into(),
2349            token_source: token.source(),
2350        }
2351    }
2352    pub fn referring_before_definition(identifier: &str, token: &TokenRange) -> Self {
2353        AnalyzerError::ReferringBeforeDefinition {
2354            identifier: identifier.to_string(),
2355            input: source(token),
2356            error_location: token.into(),
2357            token_source: token.source(),
2358        }
2359    }
2360    pub fn reserved_identifier(identifier: &str, token: &TokenRange) -> Self {
2361        AnalyzerError::ReservedIdentifier {
2362            identifier: identifier.to_string(),
2363            input: source(token),
2364            error_location: token.into(),
2365            token_source: token.source(),
2366        }
2367    }
2368    pub fn sv_keyword_usage(identifier: &str, token: &TokenRange) -> Self {
2369        AnalyzerError::SvKeywordUsage {
2370            identifier: identifier.to_string(),
2371            input: source(token),
2372            error_location: token.into(),
2373            token_source: token.source(),
2374        }
2375    }
2376    pub fn sv_with_implicit_reset(token: &TokenRange) -> Self {
2377        AnalyzerError::SvWithImplicitReset {
2378            input: source(token),
2379            error_location: token.into(),
2380            token_source: token.source(),
2381        }
2382    }
2383    pub fn too_large_enum_variant(
2384        identifier: &str,
2385        value: isize,
2386        width: usize,
2387        token: &TokenRange,
2388    ) -> Self {
2389        AnalyzerError::TooLargeEnumVariant {
2390            identifier: identifier.to_string(),
2391            value,
2392            width,
2393            input: source(token),
2394            error_location: token.into(),
2395            token_source: token.source(),
2396        }
2397    }
2398    pub fn too_large_number(width: usize, token: &TokenRange) -> Self {
2399        AnalyzerError::TooLargeNumber {
2400            width,
2401            input: source(token),
2402            error_location: token.into(),
2403            token_source: token.source(),
2404        }
2405    }
2406    pub fn too_much_enum_variant(
2407        identifier: &str,
2408        number: usize,
2409        width: usize,
2410        token: &TokenRange,
2411    ) -> Self {
2412        AnalyzerError::TooMuchEnumVariant {
2413            identifier: identifier.to_string(),
2414            number,
2415            width,
2416            input: source(token),
2417            error_location: token.into(),
2418            token_source: token.source(),
2419        }
2420    }
2421    pub fn unassign_variable(identifier: &str, token: &TokenRange) -> Self {
2422        AnalyzerError::UnassignVariable {
2423            identifier: identifier.to_string(),
2424            input: source(token),
2425            error_location: token.into(),
2426            token_source: token.source(),
2427        }
2428    }
2429    pub fn unassignable_output(token: &TokenRange) -> Self {
2430        AnalyzerError::UnassignableOutput {
2431            input: source(token),
2432            error_location: token.into(),
2433            token_source: token.source(),
2434        }
2435    }
2436    pub fn uncovered_branch(identifier: &str, token: &TokenRange, covered: &[TokenRange]) -> Self {
2437        AnalyzerError::UncoveredBranch {
2438            identifier: identifier.to_string(),
2439            input: source(token),
2440            error_locations: covered.iter().map(|x| x.into()).collect(),
2441            token_source: token.source(),
2442        }
2443    }
2444    pub fn undefined_identifier(identifier: &str, token: &TokenRange) -> Self {
2445        AnalyzerError::UndefinedIdentifier {
2446            identifier: identifier.to_string(),
2447            input: source(token),
2448            error_location: token.into(),
2449            token_source: token.source(),
2450        }
2451    }
2452    pub fn unenclosed_inner_if_expression(token: &TokenRange) -> Self {
2453        AnalyzerError::UnenclosedInnerIfExpression {
2454            input: source(token),
2455            error_location: token.into(),
2456            token_source: token.source(),
2457        }
2458    }
2459    pub fn unevaluable_value(kind: UnevaluableValueKind, token: &TokenRange) -> Self {
2460        AnalyzerError::UnevaluableValue {
2461            kind,
2462            input: source(token),
2463            error_location: token.into(),
2464            token_source: token.source(),
2465        }
2466    }
2467    pub fn unexpandable_modport(identifier: &str, token: &TokenRange) -> Self {
2468        AnalyzerError::UnexpandableModport {
2469            identifier: identifier.into(),
2470            input: source(token),
2471            error_location: token.into(),
2472            token_source: token.source(),
2473        }
2474    }
2475    pub fn unknown_attribute(name: &str, token: &TokenRange) -> Self {
2476        AnalyzerError::UnknownAttribute {
2477            name: name.to_string(),
2478            input: source(token),
2479            error_location: token.into(),
2480            token_source: token.source(),
2481        }
2482    }
2483    pub fn unknown_embed_lang(name: &str, token: &TokenRange) -> Self {
2484        AnalyzerError::UnknownEmbedLang {
2485            name: name.to_string(),
2486            input: source(token),
2487            error_location: token.into(),
2488            token_source: token.source(),
2489        }
2490    }
2491    pub fn unknown_embed_way(name: &str, token: &TokenRange) -> Self {
2492        AnalyzerError::UnknownEmbedWay {
2493            name: name.to_string(),
2494            input: source(token),
2495            error_location: token.into(),
2496            token_source: token.source(),
2497        }
2498    }
2499    pub fn unknown_include_way(name: &str, token: &TokenRange) -> Self {
2500        AnalyzerError::UnknownIncludeWay {
2501            name: name.to_string(),
2502            input: source(token),
2503            error_location: token.into(),
2504            token_source: token.source(),
2505        }
2506    }
2507    pub fn unknown_member(name: &str, member: &str, token: &TokenRange) -> Self {
2508        AnalyzerError::UnknownMember {
2509            name: name.to_string(),
2510            member: member.to_string(),
2511            input: source(token),
2512            error_location: token.into(),
2513            token_source: token.source(),
2514        }
2515    }
2516    pub fn unknown_msb(token: &TokenRange) -> Self {
2517        AnalyzerError::UnknownMsb {
2518            input: source(token),
2519            error_location: token.into(),
2520            token_source: token.source(),
2521        }
2522    }
2523    pub fn unknown_param(name: &str, param: &str, token: &TokenRange) -> Self {
2524        AnalyzerError::UnknownParam {
2525            name: name.to_string(),
2526            param: param.to_string(),
2527            input: source(token),
2528            error_location: token.into(),
2529            token_source: token.source(),
2530        }
2531    }
2532    pub fn unknown_port(name: &str, port: &str, token: &TokenRange) -> Self {
2533        AnalyzerError::UnknownPort {
2534            name: name.to_string(),
2535            port: port.to_string(),
2536            input: source(token),
2537            error_location: token.into(),
2538            token_source: token.source(),
2539        }
2540    }
2541    pub fn unknown_unsafe(name: &str, token: &TokenRange) -> Self {
2542        AnalyzerError::UnknownUnsafe {
2543            name: name.to_string(),
2544            input: source(token),
2545            error_location: token.into(),
2546            token_source: token.source(),
2547        }
2548    }
2549    pub fn unresolvable_generic_expression(
2550        identifier: &str,
2551        token: &TokenRange,
2552        definition_token: &TokenRange,
2553    ) -> Self {
2554        AnalyzerError::UnresolvableGenericExpression {
2555            identifier: identifier.to_string(),
2556            input: source(token),
2557            error_location: token.into(),
2558            definition_location: definition_token.into(),
2559            token_source: token.source(),
2560        }
2561    }
2562    pub fn unused_return(identifier: &str, token: &TokenRange) -> Self {
2563        AnalyzerError::UnusedReturn {
2564            identifier: identifier.to_string(),
2565            input: source(token),
2566            error_location: token.into(),
2567            token_source: token.source(),
2568        }
2569    }
2570    pub fn unused_variable(identifier: &str, token: &TokenRange) -> Self {
2571        AnalyzerError::UnusedVariable {
2572            identifier: identifier.to_string(),
2573            input: source(token),
2574            error_location: token.into(),
2575            token_source: token.source(),
2576        }
2577    }
2578    pub fn invalid_wavedrom(cause: InvalidWavedromKind, token: &TokenRange) -> Self {
2579        AnalyzerError::InvalidWavedrom {
2580            cause,
2581            input: source(token),
2582            error_location: token.into(),
2583            token_source: token.source(),
2584        }
2585    }
2586    pub fn wrong_seperator(separator: &str, token: &TokenRange) -> Self {
2587        let valid_separator = if separator == "." { "::" } else { "." };
2588        AnalyzerError::WrongSeparator {
2589            separator: separator.to_string(),
2590            valid_separator: valid_separator.to_string(),
2591            input: source(token),
2592            error_location: token.into(),
2593            token_source: token.source(),
2594        }
2595    }
2596}
2597
2598#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2599pub enum ExceedLimitKind {
2600    EvaluateSize,
2601    HierarchyDepth,
2602    TotalInstance,
2603}
2604
2605impl fmt::Display for ExceedLimitKind {
2606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2607        match self {
2608            ExceedLimitKind::EvaluateSize => "evaluate size".fmt(f),
2609            ExceedLimitKind::HierarchyDepth => "hierarchy depth".fmt(f),
2610            ExceedLimitKind::TotalInstance => "total instance".fmt(f),
2611        }
2612    }
2613}
2614
2615#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2616pub enum IncompatProtoKind {
2617    IncompatibleAlias(StrId),
2618    IncompatibleFunction(StrId),
2619    IncompatibleGenericParam(StrId),
2620    IncompatibleMember(StrId),
2621    IncompatibleModport(StrId),
2622    IncompatibleParam(StrId),
2623    IncompatiblePort(StrId),
2624    IncompatibleType,
2625    IncompatibleTypedef(StrId),
2626    IncompatibleVar(StrId),
2627    MissignMember(StrId),
2628    MissingAlias(StrId),
2629    MissingFunction(StrId),
2630    MissingGenericParam(StrId),
2631    MissingModport(StrId),
2632    MissingParam(StrId),
2633    MissingPort(StrId),
2634    MissingType,
2635    MissingTypedef(StrId),
2636    MissingVar(StrId),
2637    UnnecessaryGenericParam(StrId),
2638    UnnecessaryMember(StrId),
2639    UnnecessaryParam(StrId),
2640    UnnecessaryPort(StrId),
2641    UnnecessaryType,
2642}
2643
2644impl fmt::Display for IncompatProtoKind {
2645    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2646        match self {
2647            IncompatProtoKind::IncompatibleAlias(x) => {
2648                format!("alias \"{x}\" is incompatible").fmt(f)
2649            }
2650            IncompatProtoKind::IncompatibleFunction(x) => {
2651                format!("function \"{x}\" is incompatible").fmt(f)
2652            }
2653            IncompatProtoKind::IncompatibleGenericParam(x) => {
2654                format!("generic parameter \"{x}\" is incompatible").fmt(f)
2655            }
2656            IncompatProtoKind::IncompatibleMember(x) => {
2657                format!("member \"{x}\" is incompatible").fmt(f)
2658            }
2659            IncompatProtoKind::IncompatibleModport(x) => {
2660                format!("modport \"{x}\" is incompatible").fmt(f)
2661            }
2662            IncompatProtoKind::IncompatibleParam(x) => {
2663                format!("parameter \"{x}\" has incompatible type").fmt(f)
2664            }
2665            IncompatProtoKind::IncompatiblePort(x) => {
2666                format!("port \"{x}\" has incompatible type").fmt(f)
2667            }
2668            IncompatProtoKind::IncompatibleType => "type specification is incompatible".fmt(f),
2669            IncompatProtoKind::IncompatibleTypedef(x) => {
2670                format!("type definition \"{x}\" is incompatible").fmt(f)
2671            }
2672            IncompatProtoKind::IncompatibleVar(x) => {
2673                format!("variable \"{x}\" is incompatible").fmt(f)
2674            }
2675            IncompatProtoKind::MissignMember(x) => format!("member \"{x}\" is missing").fmt(f),
2676            IncompatProtoKind::MissingAlias(x) => format!("alias \"{x}\" is missing").fmt(f),
2677            IncompatProtoKind::MissingFunction(x) => format!("function \"{x}\" is missing").fmt(f),
2678            IncompatProtoKind::MissingGenericParam(x) => {
2679                format!("generic parameter \"{x}\" is missing").fmt(f)
2680            }
2681            IncompatProtoKind::MissingModport(x) => format!("modport \"{x}\" is missing").fmt(f),
2682            IncompatProtoKind::MissingParam(x) => format!("parameter \"{x}\" is missing").fmt(f),
2683            IncompatProtoKind::MissingPort(x) => format!("port \"{x}\" is missing").fmt(f),
2684            IncompatProtoKind::MissingType => "type specification is missing".fmt(f),
2685            IncompatProtoKind::MissingTypedef(x) => {
2686                format!("type definition \"{x}\" is missing").fmt(f)
2687            }
2688            IncompatProtoKind::MissingVar(x) => format!("variable \"{x}\" is missing").fmt(f),
2689            IncompatProtoKind::UnnecessaryGenericParam(x) => {
2690                format!("generic parameter \"{x}\" is unnecessary").fmt(f)
2691            }
2692            IncompatProtoKind::UnnecessaryMember(x) => {
2693                format!("member \"{x}\" is unnecessary").fmt(f)
2694            }
2695            IncompatProtoKind::UnnecessaryParam(x) => {
2696                format!("parameter \"{x}\" is unnecessary").fmt(f)
2697            }
2698            IncompatProtoKind::UnnecessaryPort(x) => format!("port \"{x}\" is unnecessary").fmt(f),
2699            IncompatProtoKind::UnnecessaryType => "type specification is unnecessary".fmt(f),
2700        }
2701    }
2702}
2703
2704#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2705pub enum InvalidConnectOperandKind {
2706    IncludeInout,
2707    InstanceArray,
2708    ModportArray,
2709    UnemittableCast,
2710}
2711
2712impl fmt::Display for InvalidConnectOperandKind {
2713    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2714        match self {
2715            InvalidConnectOperandKind::IncludeInout => {
2716                "modport including inout ports can't be used at here".fmt(f)
2717            }
2718            InvalidConnectOperandKind::InstanceArray => "it is an array interface instance".fmt(f),
2719            InvalidConnectOperandKind::ModportArray => "it is an array modport".fmt(f),
2720            InvalidConnectOperandKind::UnemittableCast => "modport including variables of which type is defined in the interface can't be used for a connect operand".fmt(f),
2721        }
2722    }
2723}
2724
2725#[derive(Clone, Debug, PartialEq, Eq)]
2726pub enum InvalidWavedromKind {
2727    InvalidJson(String),
2728    MissingSignalArray,
2729    UnknownWaveChar { signal: String, ch: char },
2730    JavaScriptInTestBlock,
2731    PipeSeparatorInTest { signal: String },
2732    NoMatchingPorts,
2733}
2734
2735impl fmt::Display for InvalidWavedromKind {
2736    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2737        match self {
2738            InvalidWavedromKind::InvalidJson(e) => write!(f, "invalid WaveDrom JSON: {e}"),
2739            InvalidWavedromKind::MissingSignalArray => {
2740                write!(f, "WaveDrom JSON missing 'signal' array")
2741            }
2742            InvalidWavedromKind::UnknownWaveChar { signal, ch } => {
2743                write!(
2744                    f,
2745                    "WaveDrom signal '{signal}' contains unknown wave character '{ch}'"
2746                )
2747            }
2748            InvalidWavedromKind::JavaScriptInTestBlock => {
2749                write!(
2750                    f,
2751                    "WaveDrom test blocks must use JSON, not JavaScript expressions"
2752                )
2753            }
2754            InvalidWavedromKind::PipeSeparatorInTest { signal } => {
2755                write!(
2756                    f,
2757                    "WaveDrom signal '{signal}' contains '|' separator (indeterminate timing, not testable)"
2758                )
2759            }
2760            InvalidWavedromKind::NoMatchingPorts => {
2761                write!(f, "WaveDrom test has no signals matching module ports")
2762            }
2763        }
2764    }
2765}
2766
2767#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2768pub enum InvalidModifierKind {
2769    NotTopModule,
2770    NotClockReset,
2771}
2772
2773impl fmt::Display for InvalidModifierKind {
2774    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2775        match self {
2776            InvalidModifierKind::NotTopModule => "here is not the module top layer".fmt(f),
2777            InvalidModifierKind::NotClockReset => {
2778                "the given type is not a single bit clock nor a single bit reset".fmt(f)
2779            }
2780        }
2781    }
2782}
2783
2784#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2785pub enum InvalidModportItemKind {
2786    Function,
2787    Variable,
2788}
2789
2790impl fmt::Display for InvalidModportItemKind {
2791    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2792        match self {
2793            InvalidModportItemKind::Function => "function".fmt(f),
2794            InvalidModportItemKind::Variable => "variable".fmt(f),
2795        }
2796    }
2797}
2798
2799#[derive(Clone, Debug, PartialEq, Eq)]
2800pub enum InvalidPortDefaultValueKind {
2801    NotGlobal,
2802    InFunction,
2803    NonAnonymousInOutput,
2804    InvalidDirection(String),
2805}
2806
2807impl fmt::Display for InvalidPortDefaultValueKind {
2808    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2809        match self {
2810            InvalidPortDefaultValueKind::NotGlobal => {
2811                "port default value should be accessable globally".fmt(f)
2812            }
2813            InvalidPortDefaultValueKind::InFunction => {
2814                "port default value in function is not supported".fmt(f)
2815            }
2816            InvalidPortDefaultValueKind::NonAnonymousInOutput => {
2817                "Only '_' is supported for output default value".fmt(f)
2818            }
2819            InvalidPortDefaultValueKind::InvalidDirection(x) => {
2820                format!("Port default value for {x} is not supported").fmt(f)
2821            }
2822        }
2823    }
2824}
2825
2826#[derive(Clone, Debug, PartialEq, Eq)]
2827pub enum MismatchTypeKind {
2828    SymbolKind {
2829        name: String,
2830        expected: String,
2831        actual: String,
2832    },
2833    GenericArgument {
2834        name: String,
2835        expected: String,
2836        actual: String,
2837    },
2838    ArrayDimension {
2839        expected: usize,
2840        actual: usize,
2841    },
2842    ConnectMultipleExpression,
2843    NonStructUnionType {
2844        actual: String,
2845    },
2846}
2847
2848impl fmt::Display for MismatchTypeKind {
2849    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2850        match self {
2851            MismatchTypeKind::SymbolKind {
2852                name,
2853                expected,
2854                actual,
2855            } => {
2856                write!(
2857                    f,
2858                    "\"{name}\" is expected to \"{expected}\", but it is \"{actual}\""
2859                )
2860            }
2861            MismatchTypeKind::GenericArgument {
2862                name,
2863                expected,
2864                actual,
2865            } => {
2866                write!(
2867                    f,
2868                    "\"{name}\" is expected to \"{expected}\", but it is \"{actual}\""
2869                )
2870            }
2871            MismatchTypeKind::ArrayDimension { expected, actual } => {
2872                write!(
2873                    f,
2874                    "array literal is expected to {expected} elements, but it has {actual} elements"
2875                )
2876            }
2877            MismatchTypeKind::ConnectMultipleExpression => {
2878                "connect requires a single expression, but multiple expressions are provided".fmt(f)
2879            }
2880            MismatchTypeKind::NonStructUnionType { actual } => {
2881                write!(
2882                    f,
2883                    "struct constructor is expected to \"struct or union\", but it is \"{actual}\""
2884                )
2885            }
2886        }
2887    }
2888}
2889
2890#[derive(Clone, Debug, PartialEq, Eq)]
2891pub enum InvalidSelectKind {
2892    WrongOrder { beg: usize, end: usize },
2893    OutOfRange { beg: usize, end: usize, size: usize },
2894    OutOfDimension { dim: usize, size: usize },
2895    SelectAfterRange,
2896}
2897
2898impl fmt::Display for InvalidSelectKind {
2899    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2900        match self {
2901            InvalidSelectKind::WrongOrder { beg, end } => {
2902                format!("wrong index order [{beg}:{end}]").fmt(f)
2903            }
2904            InvalidSelectKind::OutOfRange { beg, end, size } => {
2905                if beg == end {
2906                    format!("out of range [{beg}] > {size}").fmt(f)
2907                } else {
2908                    format!("out of range [{beg}:{end}] > {size}").fmt(f)
2909                }
2910            }
2911            InvalidSelectKind::OutOfDimension { .. } => "out of dimension".fmt(f),
2912            InvalidSelectKind::SelectAfterRange => "select after range is not allowed".fmt(f),
2913        }
2914    }
2915}
2916
2917#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2918pub enum InvalidTestKind {
2919    NoTopModuleCocotb,
2920}
2921
2922impl fmt::Display for InvalidTestKind {
2923    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2924        match self {
2925            InvalidTestKind::NoTopModuleCocotb => "`cocotb` test requires top module name at the second argument of `#[test]` attribute".fmt(f),
2926        }
2927    }
2928}
2929
2930#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2931pub enum MultipleDefaultKind {
2932    Clock,
2933    Reset,
2934    ArrayLiteral,
2935}
2936
2937impl fmt::Display for MultipleDefaultKind {
2938    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2939        match self {
2940            MultipleDefaultKind::Clock => "clock".fmt(f),
2941            MultipleDefaultKind::Reset => "reset".fmt(f),
2942            MultipleDefaultKind::ArrayLiteral => "value in array literal".fmt(f),
2943        }
2944    }
2945}
2946
2947#[derive(Clone, Debug, PartialEq, Eq)]
2948pub enum DuplicatedIdentifierKind {
2949    Normal,
2950    RawIdentifier { raw: String },
2951}
2952
2953impl fmt::Display for DuplicatedIdentifierKind {
2954    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2955        match self {
2956            DuplicatedIdentifierKind::Normal => "".fmt(f),
2957            DuplicatedIdentifierKind::RawIdentifier { raw } => {
2958                write!(
2959                    f,
2960                    "r#-prefixed identifier \"{raw}\" is treated as the same identifier without the prefix"
2961                )
2962            }
2963        }
2964    }
2965}
2966
2967#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2968pub enum UnevaluableValueKind {
2969    CaseCondition,
2970    ConstValue,
2971    EnumVariant,
2972    ForRange,
2973    ParameterValue,
2974    ResetValue,
2975}
2976
2977impl fmt::Display for UnevaluableValueKind {
2978    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2979        match self {
2980            UnevaluableValueKind::CaseCondition => "case condition".fmt(f),
2981            UnevaluableValueKind::ConstValue => "const value".fmt(f),
2982            UnevaluableValueKind::EnumVariant => "enum variant".fmt(f),
2983            UnevaluableValueKind::ForRange => "for range".fmt(f),
2984            UnevaluableValueKind::ParameterValue => "parameter value".fmt(f),
2985            UnevaluableValueKind::ResetValue => "reset value".fmt(f),
2986        }
2987    }
2988}