1use crate::ast::span::AstSpan;
2use crate::file::span::{Span, Spanned};
3use crate::file::unpack_files::UnpackError;
4use crate::lexer_context::Context;
5use crate::{
6 prelude::{Opcode, parse_extension},
7 report::{Report, Reporter},
8 token::TokenKind,
9};
10use std::{ffi::OsString, fmt, io::Write};
11
12#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
14pub struct ParserError {
15 pub kind: ParserErrorKind,
17 pub hint: Option<String>,
19 pub spans: AstSpan,
21 pub cursor: usize,
23}
24
25#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
27pub enum ParserErrorKind {
28 InvalidPush(Opcode),
30 InvalidStackImmediate(Opcode),
32 UnexpectedType(TokenKind),
34 InvalidTypeAsArgumentName(TokenKind),
36 InvalidDefinition(TokenKind),
38 InvalidConstantValue(TokenKind),
40 InvalidConstantName,
42 InvalidMacroName,
44 InvalidTokenInMacroBody(TokenKind),
46 InvalidTokenInLabelDefinition(TokenKind),
48 InvalidSingleArg(TokenKind),
50 InvalidTableBodyToken(TokenKind),
52 InvalidConstant(TokenKind),
54 InvalidArgCallIdent(TokenKind),
56 InvalidName(TokenKind),
58 InvalidArgs(TokenKind),
60 InvalidUint256(usize),
62 InvalidBytes(usize),
64 InvalidInt(usize),
66 InvalidMacroArgs(TokenKind),
68 InvalidReturnArgs,
70 InvalidImportPath(String),
72 InvalidDecoratorFlag(String),
74 InvalidDecoratorFlagArg(TokenKind),
76 DecoratorOnNonTest(String),
78 DuplicateLabel(String),
80 DuplicateMacro(String),
82 InvalidTableStatement(String),
84 InvalidExpression(TokenKind),
86}
87
88#[derive(Debug, PartialEq, Eq, Clone)]
90pub struct LexicalError {
91 pub kind: LexicalErrorKind,
93 pub span: Span,
95}
96
97impl LexicalError {
98 pub fn new(kind: LexicalErrorKind, span: Span) -> Self {
100 Self { kind, span }
101 }
102}
103
104#[derive(Debug, PartialEq, Eq, Clone)]
106pub enum LexicalErrorKind {
107 UnexpectedEof,
109 InvalidCharacter(char),
111 HexLiteralTooLong(String),
113 InvalidHexLiteral(String),
115 InvalidArraySize(String),
118 InvalidPrimitiveType(String),
120 StackUnderflow,
122 UnexpectedContext(Context),
124}
125
126impl Spanned for LexicalError {
127 fn span(&self) -> Span {
128 self.span.clone()
129 }
130}
131
132impl<W: Write> Report<W> for LexicalError {
133 fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> {
134 match &self.kind {
135 LexicalErrorKind::InvalidCharacter(ch) => write!(f.out, "Invalid character '{ch}'"),
136 LexicalErrorKind::UnexpectedEof => write!(f.out, "Found unexpected EOF"),
137 LexicalErrorKind::InvalidArraySize(str) => {
138 write!(f.out, "Invalid array size: '{str}'")
139 }
140 LexicalErrorKind::InvalidPrimitiveType(str) => {
141 write!(f.out, "Invalid Primitive EVM Type '{str}'")
142 }
143 LexicalErrorKind::HexLiteralTooLong(str) => {
144 write!(f.out, "Hex literal has more than 32 bytes '{str}'")
145 }
146 LexicalErrorKind::InvalidHexLiteral(str) => {
147 write!(f.out, "Invalid hex literal '{str}'")
148 }
149 LexicalErrorKind::StackUnderflow => write!(f.out, "Stack underflow"),
150 LexicalErrorKind::UnexpectedContext(context) => write!(f.out, "Unexpected context: {context:?}"),
151 }
152 }
153}
154
155#[derive(Debug, PartialEq, Eq, Clone)]
157pub struct CodegenError {
158 pub kind: CodegenErrorKind,
160 pub span: Box<AstSpan>,
162 pub token: Option<TokenKind>,
164}
165
166impl CodegenError {
167 pub fn new(kind: CodegenErrorKind, spans: AstSpan, token: Option<TokenKind>) -> Self {
169 Self { kind, span: Box::new(spans), token }
170 }
171}
172
173#[derive(Debug, PartialEq, Eq, Clone)]
175pub enum CodegenErrorKind {
176 LockingError,
178 StoragePointersNotDerived,
180 InvalidMacroStatement,
182 MissingArgumentDefinition(String),
184 MissingMacroDefinition(String),
186 MissingFunctionInterface(String),
188 MissingEventInterface(String),
190 MissingConstantDefinition(String),
192 StringConstantNotBytes(String),
194 MissingErrorDefinition(String),
196 AbiGenerationFailure,
198 UnmatchedJumpLabels(Vec<String>),
200 IOError(String),
202 UnkownArgcallType,
204 MissingMacroInvocation(String),
206 InvalidMacroInvocation(String),
208 InvalidArgumentCount(String, usize, usize),
210 UsizeConversion(String),
212 InvalidArguments(String),
214 InvalidMacroArgumentType(String),
216 InvalidHex(String),
218 InvalidTableStatement(String),
220 InvalidCodeLength(usize),
222 TestInvocation(String),
224 InvalidConstructorArgs(String),
226 ArgsStartOutsideConstructor,
228 MissingTableSize(String),
230 UnsupportedBuiltinFunction(String),
232 RuntimeSizeNotComputed,
235 CodesizeRuntimeInCodeTable,
238 CodesizeNotConverged(usize),
240 UnsupportedStatementType(String),
242 DuplicateLabelInScope(String),
244 DuplicateLabelAcrossSiblings(String),
247 DuplicateTableEmbedding(String),
249 JumpTargetTooLarge {
251 label: String,
253 target: usize,
255 opcode: String,
257 },
258 CircularMacroInvocation(String),
260 CircularConstantDependency(String),
262 RecursionDepthExceeded(usize),
264 UndefinedConstant(String),
266 InvalidConstantExpression,
268 ArithmeticOverflow,
270 ArithmeticUnderflow,
272 DivisionByZero,
274 ArgCallInConstantExpression(String),
276 InvalidOpcodeForEVMVersion(String, String, String),
278 InvalidLoopStep,
280 LoopIterationLimitExceeded(usize),
282 AssertPcFailed(usize, usize),
284 ArgResolutionLimitExceeded(String, usize),
287 BubbleArgLimitExceeded(String, usize),
290 ContractSizeLimitExceeded(usize, usize),
292 InitcodeSizeLimitExceeded(usize, usize),
294 InvalidOpcodeOperand(String),
296 OffsetExceedsTwoBytes(String, usize),
298}
299
300impl Spanned for CodegenError {
301 fn span(&self) -> Span {
302 self.span[0].clone()
303 }
304}
305
306impl<W: Write> Report<W> for CodegenError {
307 fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> {
308 match &self.kind {
309 CodegenErrorKind::LockingError => {
310 write!(f.out, "Synchronisation Error - Please execute again!")
311 }
312 CodegenErrorKind::StoragePointersNotDerived => {
313 write!(f.out, "Storage pointers not derived for AST!")
314 }
315 CodegenErrorKind::InvalidMacroStatement => write!(f.out, "Invalid Macro Statement!"),
316 CodegenErrorKind::InvalidMacroInvocation(str) => {
317 write!(f.out, "Missing Macro Definition for Invocation: \"{str}\"!")
318 }
319 CodegenErrorKind::InvalidArgumentCount(str, expected, actual) => {
320 write!(f.out, "Invalid Argument Count for \"{str}\", expected {expected}, got {actual}!")
321 }
322 CodegenErrorKind::MissingArgumentDefinition(str) => {
323 write!(f.out, "Missing Argument \"{str}\" Definition!")
324 }
325 CodegenErrorKind::MissingMacroDefinition(str) => {
326 write!(f.out, "Missing Macro \"{str}\" Definition!")
327 }
328 CodegenErrorKind::MissingFunctionInterface(str) => {
329 write!(f.out, "Missing Function Interface for \"{str}\"!")
330 }
331 CodegenErrorKind::MissingEventInterface(str) => {
332 write!(f.out, "Missing Event Interface for \"{str}\"!")
333 }
334 CodegenErrorKind::MissingConstantDefinition(cd) => {
335 write!(f.out, "Missing Constant Definition for \"{cd}\"!")
336 }
337 CodegenErrorKind::StringConstantNotBytes(msg) => {
338 write!(f.out, "String constant cannot be used directly: \"{msg}\"")
339 }
340 CodegenErrorKind::MissingErrorDefinition(ed) => {
341 write!(f.out, "Missing Error Definition for \"{ed}\"!")
342 }
343 CodegenErrorKind::AbiGenerationFailure => write!(f.out, "Abi generation failure!"),
344 CodegenErrorKind::UnmatchedJumpLabels(labels) => write!(f.out, "Unmatched jump labels: \"{}\"!", labels.join(", ")),
345 CodegenErrorKind::IOError(ioe) => write!(f.out, "IO ERROR: {ioe:?}"),
346 CodegenErrorKind::UnkownArgcallType => write!(f.out, "Unknown Argcall Type!"),
347 CodegenErrorKind::MissingMacroInvocation(str) => {
348 write!(f.out, "Missing Macro \"{str}\" Invocation!")
349 }
350 CodegenErrorKind::UsizeConversion(input) => {
351 write!(f.out, "Usize Conversion Failed for \"{input}\"")
352 }
353 CodegenErrorKind::InvalidArguments(msg) => {
354 write!(f.out, "Invalid arguments: \"{msg}\"")
355 }
356 CodegenErrorKind::InvalidMacroArgumentType(msg) => {
357 write!(f.out, "Invalid macro argument type: {msg}")
358 }
359 CodegenErrorKind::InvalidHex(msg) => {
360 write!(f.out, "Invalid hex string: \"{msg}\"")
361 }
362 CodegenErrorKind::InvalidTableStatement(msg) => {
363 write!(f.out, "Invalid table statement: \"{msg}\"")
364 }
365 CodegenErrorKind::InvalidCodeLength(len) => {
366 write!(f.out, "Invalid code length: {len}")
367 }
368 CodegenErrorKind::TestInvocation(msg) => {
369 write!(f.out, "Test cannot be invoked: \"{msg}\"")
370 }
371 CodegenErrorKind::InvalidConstructorArgs(msg) => {
372 write!(f.out, "Invalid constructor arguments: {msg}")
373 }
374 CodegenErrorKind::ArgsStartOutsideConstructor => {
375 write!(f.out, "__argsstart() can only be used in the constructor")
376 }
377 CodegenErrorKind::MissingTableSize(table_name) => {
378 write!(f.out, "Missing Table Size for table: \"{table_name}\"")
379 }
380 CodegenErrorKind::UnsupportedBuiltinFunction(bf) => {
381 write!(f.out, "Unsupported Builtin Function: \"{bf}\"")
382 }
383 CodegenErrorKind::RuntimeSizeNotComputed => {
384 write!(f.out, "__codesize(RUNTIME) cannot be resolved here: MAIN bytecode has not been generated yet")
385 }
386 CodegenErrorKind::CodesizeRuntimeInCodeTable => {
387 write!(f.out, "__codesize(RUNTIME) is not allowed inside a code table")
388 }
389 CodegenErrorKind::CodesizeNotConverged(iterations) => {
390 write!(f.out, "__codesize did not converge after {iterations} codegen passes")
391 }
392 CodegenErrorKind::UnsupportedStatementType(st) => {
393 write!(f.out, "Unsupported Statement Type: \"{st}\"")
394 }
395 CodegenErrorKind::DuplicateLabelInScope(label) => {
396 write!(f.out, "Duplicate label '{}' defined in the same scope", label)
397 }
398 CodegenErrorKind::DuplicateLabelAcrossSiblings(label) => {
399 write!(f.out, "Duplicate label '{}' defined across siblings in same scope", label)
400 }
401 CodegenErrorKind::DuplicateTableEmbedding(table) => {
402 write!(f.out, "Table \"{}\" has already been embedded. Each table can only be embedded once with __EMBED_TABLE.", table)
403 }
404 CodegenErrorKind::JumpTargetTooLarge { label, target, opcode } => {
405 write!(f.out, "Jump target {:#x} too large for {} in label \"{}\"", target, opcode, label)
406 }
407 CodegenErrorKind::CircularMacroInvocation(macro_name) => {
408 write!(f.out, "Circular macro invocation detected: '{}' is already in the call stack", macro_name)
409 }
410 CodegenErrorKind::CircularConstantDependency(constant_name) => {
411 write!(f.out, "Circular constant dependency detected: '{}' is already being evaluated", constant_name)
412 }
413 CodegenErrorKind::RecursionDepthExceeded(depth) => {
414 write!(f.out, "Recursion depth limit exceeded: maximum depth of {} reached", depth)
415 }
416 CodegenErrorKind::UndefinedConstant(name) => {
417 write!(f.out, "Undefined constant '{}' used in expression", name)
418 }
419 CodegenErrorKind::InvalidConstantExpression => {
420 write!(f.out, "Invalid constant expression - expression contains runtime elements")
421 }
422 CodegenErrorKind::ArithmeticOverflow => {
423 write!(f.out, "Arithmetic overflow in constant expression")
424 }
425 CodegenErrorKind::ArithmeticUnderflow => {
426 write!(f.out, "Arithmetic underflow in constant expression")
427 }
428 CodegenErrorKind::DivisionByZero => {
429 write!(f.out, "Division by zero in constant expression")
430 }
431 CodegenErrorKind::ArgCallInConstantExpression(name) => {
432 write!(f.out, "Macro argument <{}> cannot be used in global constant expression - requires macro invocation context", name)
433 }
434 CodegenErrorKind::InvalidOpcodeForEVMVersion(opcode, required_version, current_version) => {
435 write!(
436 f.out,
437 "Opcode '{}' requires EVM version '{}' or later (current version: '{}')",
438 opcode, required_version, current_version
439 )
440 }
441 CodegenErrorKind::InvalidLoopStep => {
442 write!(f.out, "Invalid loop step: step value cannot be zero")
443 }
444 CodegenErrorKind::LoopIterationLimitExceeded(max) => {
445 write!(f.out, "Loop iteration limit exceeded: maximum {} iterations allowed at compile-time", max)
446 }
447 CodegenErrorKind::AssertPcFailed(expected, actual) => {
448 write!(f.out, "PC assertion failed: expected position 0x{:x}, but current position is 0x{:x}", expected, actual)
449 }
450 CodegenErrorKind::ArgResolutionLimitExceeded(arg_name, max_iterations) => {
451 write!(
452 f.out,
453 "Exceeded maximum iterations ({}) while resolving argument reference '<{}>' through the scope chain - possible circular argument reference",
454 max_iterations, arg_name
455 )
456 }
457 CodegenErrorKind::BubbleArgLimitExceeded(arg_name, max_iterations) => {
458 write!(
459 f.out,
460 "Exceeded maximum iterations ({}) while bubbling argument '<{}>' up through nested macro calls",
461 max_iterations, arg_name
462 )
463 }
464 CodegenErrorKind::ContractSizeLimitExceeded(size, limit) => {
465 write!(f.out, "Contract bytecode size ({} bytes) exceeds the contract size limit ({} bytes)", size, limit)
466 }
467 CodegenErrorKind::InitcodeSizeLimitExceeded(size, limit) => {
468 write!(f.out, "Deployment bytecode size ({} bytes) exceeds the initcode size limit ({} bytes)", size, limit)
469 }
470 CodegenErrorKind::InvalidOpcodeOperand(msg) => {
471 write!(f.out, "Invalid opcode operand: {msg}")
472 }
473 CodegenErrorKind::OffsetExceedsTwoBytes(what, offset) => {
474 write!(f.out, "Offset {offset:#x} of {what} does not fit into 2 bytes")
475 }
476 }
477 }
478}
479
480#[derive(Debug, Clone, PartialEq, Eq)]
482pub enum CompilerError {
483 LexicalError(LexicalError),
485 FileUnpackError(UnpackError),
487 ParserError(ParserError),
489 PathBufRead(OsString),
491 EmptyImportPath(OsString),
493 CodegenError(CodegenError),
495 FailedCompiles(Vec<CompilerError>),
497 UnknownConstantOverride(String),
499}
500
501impl fmt::Display for CompilerError {
502 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503 match self {
504 CompilerError::LexicalError(le) => match &le.kind {
505 LexicalErrorKind::UnexpectedEof => {
506 write!(f, "\nError: Unexpected End Of File {}{}\n", le.span.identifier(), le.span.source_seg())
507 }
508 LexicalErrorKind::InvalidCharacter(c) => {
509 write!(f, "\nError: Invalid Character: \"{}\" {}{}\n", c, le.span.identifier(), le.span.source_seg())
510 }
511 LexicalErrorKind::InvalidArraySize(a) => {
512 write!(f, "\nError: Invalid Array Size: \"{}\" {}{}\n", a, le.span.identifier(), le.span.source_seg())
513 }
514 LexicalErrorKind::InvalidPrimitiveType(ty) => {
515 write!(f, "\nError: Invalid Primitive Type: \"{}\" {}{}\n", ty, le.span.identifier(), le.span.source_seg())
516 }
517 LexicalErrorKind::HexLiteralTooLong(h) => {
518 write!(f, "\nError: Hex literal has more than 32 bytes: \"{}\" {}{}\n", h, le.span.identifier(), le.span.source_seg())
519 }
520 LexicalErrorKind::InvalidHexLiteral(h) => {
521 write!(f, "\nError: Invalid Hex literal: \"{}\" {}{}\n", h, le.span.identifier(), le.span.source_seg())
522 }
523 LexicalErrorKind::StackUnderflow => {
524 write!(f, "\nError: Stack Underflow {}{}\n", le.span.identifier(), le.span.source_seg())
525 }
526 LexicalErrorKind::UnexpectedContext(context) => {
527 write!(f, "\nError: Unexpected Context: {:?} {}{}\n", context, le.span.identifier(), le.span.source_seg())
528 }
529 },
530 CompilerError::FileUnpackError(ue) => match ue {
531 UnpackError::InvalidDirectory(id) => {
532 write!(f, "\nError: Invalid File Directory {id}\n")
533 }
534 UnpackError::UnsupportedExtension(unsupported) => {
535 write!(
536 f,
537 "\nError: Unsupported File Extension \"{}\"\n--> {}\n",
538 parse_extension(unsupported).unwrap_or(""),
539 unsupported
540 )
541 }
542 UnpackError::MissingFile(file) => {
543 write!(f, "\nError: File Not Found \"{file}\"\n")
544 }
545 },
546 CompilerError::ParserError(pe) => match &pe.kind {
547 ParserErrorKind::InvalidPush(op) => {
548 write!(f, "\nError at token {}: Invalid use of \"{:?}\" \n{}\n", pe.cursor, op, pe.spans.error(pe.hint.as_ref()))
549 }
550 ParserErrorKind::InvalidStackImmediate(op) => {
551 write!(
552 f,
553 "\nError at token {}: Invalid stack operand for \"{:?}\" \n{}\n",
554 pe.cursor,
555 op,
556 pe.spans.error(pe.hint.as_ref())
557 )
558 }
559 ParserErrorKind::UnexpectedType(ut) => {
560 write!(f, "\nError at token {}: Unexpected Type: \"{}\" \n{}\n", pe.cursor, ut, pe.spans.error(pe.hint.as_ref()))
561 }
562 ParserErrorKind::InvalidTypeAsArgumentName(ut) => {
563 write!(
564 f,
565 "\nError at token {}: Unexpected Argument Name is an EVM Type: \"{}\" \n{}\n",
566 pe.cursor,
567 ut,
568 pe.spans.error(pe.hint.as_ref())
569 )
570 }
571 ParserErrorKind::InvalidDefinition(k) => {
572 write!(f, "\nError at token {}: Invalid Defintion \"{}\"\n{}\n", pe.cursor, k, pe.spans.error(pe.hint.as_ref()))
573 }
574 ParserErrorKind::InvalidConstantValue(cv) => {
575 write!(f, "\nError at token {}: Invalid Constant Value: \"{}\" \n{}\n", pe.cursor, cv, pe.spans.error(pe.hint.as_ref()))
576 }
577 ParserErrorKind::InvalidConstantName => {
578 write!(f, "\nError at token {}: Invalid Constant Name \n{}\n", pe.cursor, pe.spans.error(pe.hint.as_ref()))
579 }
580 ParserErrorKind::InvalidMacroName => {
581 write!(f, "\nError at token {}: Invalid Macro Name \n{}\n", pe.cursor, pe.spans.error(pe.hint.as_ref()))
582 }
583 ParserErrorKind::InvalidTokenInMacroBody(tmb) => {
584 write!(
585 f,
586 "\nError at token {}: Invalid Token In Macro Body: \"{}\" \n{}\n",
587 pe.cursor,
588 tmb,
589 pe.spans.error(pe.hint.as_ref())
590 )
591 }
592 ParserErrorKind::InvalidTokenInLabelDefinition(tlb) => {
593 write!(
594 f,
595 "\nError at token {}: Invalid Token In Label Definition: \"{}\" \n{}\n",
596 pe.cursor,
597 tlb,
598 pe.spans.error(pe.hint.as_ref())
599 )
600 }
601 ParserErrorKind::InvalidSingleArg(sa) => {
602 write!(f, "\nError at token {}: Invalid Argument: \"{}\" \n{}\n", pe.cursor, sa, pe.spans.error(pe.hint.as_ref()))
603 }
604 ParserErrorKind::InvalidTableBodyToken(tbt) => {
605 write!(
606 f,
607 "\nError at token {}: Invalid Token In Table Body: \"{}\" \n{}\n",
608 pe.cursor,
609 tbt,
610 pe.spans.error(pe.hint.as_ref())
611 )
612 }
613 ParserErrorKind::InvalidConstant(constant) => {
614 write!(f, "\nError at token {}: Invalid Constant: \"{}\" \n{}\n", pe.cursor, constant, pe.spans.error(pe.hint.as_ref()))
615 }
616 ParserErrorKind::InvalidArgCallIdent(aci) => {
617 write!(
618 f,
619 "\nError at token {}: Invalid Argument Call Identifier: \"{}\" \n{}\n",
620 pe.cursor,
621 aci,
622 pe.spans.error(pe.hint.as_ref())
623 )
624 }
625 ParserErrorKind::InvalidName(name) => {
626 write!(f, "\nError at token {}: Invalid Name: \"{}\" \n{}\n", pe.cursor, name, pe.spans.error(pe.hint.as_ref()))
627 }
628 ParserErrorKind::InvalidArgs(args) => {
629 write!(
630 f,
631 "\nError at token {}: Invalid Argument Type: \"{}\" \n{}\n",
632 pe.cursor,
633 args,
634 pe.spans.error(pe.hint.as_ref())
635 )
636 }
637 ParserErrorKind::InvalidUint256(v) => {
638 write!(f, "\nError at token {}: Invalid Uint256 Value: \"{}\" \n{}\n", pe.cursor, v, pe.spans.error(pe.hint.as_ref()))
639 }
640 ParserErrorKind::InvalidBytes(b) => {
641 write!(f, "\nError at token {}: Invalid Bytes Value: \"{}\" \n{}\n", pe.cursor, b, pe.spans.error(pe.hint.as_ref()))
642 }
643 ParserErrorKind::InvalidInt(i) => {
644 write!(f, "\nError at token {}: Invalid Int Value: \"{}\" \n{}\n", pe.cursor, i, pe.spans.error(pe.hint.as_ref()))
645 }
646 ParserErrorKind::InvalidMacroArgs(ma) => {
647 write!(
648 f,
649 "\nError at token {}: Invalid Macro Arguments: \"{}\" \n{}\n",
650 pe.cursor,
651 ma,
652 pe.spans.error(pe.hint.as_ref())
653 )
654 }
655 ParserErrorKind::InvalidReturnArgs => {
656 write!(f, "\nError at token {}: Invalid Return Arguments\n{}\n", pe.cursor, pe.spans.error(pe.hint.as_ref()))
657 }
658 ParserErrorKind::InvalidImportPath(ip) => {
659 write!(f, "\nError at token {}: Invalid Import Path: \"{}\" \n{}\n", pe.cursor, ip, pe.spans.error(pe.hint.as_ref()))
660 }
661 ParserErrorKind::InvalidDecoratorFlag(df) => {
662 write!(f, "\nError at token {}: Invalid Decorator Flag: \"{}\" \n{}\n", pe.cursor, df, pe.spans.error(pe.hint.as_ref()))
663 }
664 ParserErrorKind::InvalidDecoratorFlagArg(dfa) => {
665 write!(
666 f,
667 "\nError at token {}: Invalid Decorator Flag Argument: \"{}\" \n{}\n",
668 pe.cursor,
669 dfa,
670 pe.spans.error(pe.hint.as_ref())
671 )
672 }
673 ParserErrorKind::DecoratorOnNonTest(name) => {
674 write!(
675 f,
676 "\nError at token {}: Decorator on non-test macro: \"{}\" \n{}\n",
677 pe.cursor,
678 name,
679 pe.spans.error(pe.hint.as_ref())
680 )
681 }
682 ParserErrorKind::DuplicateLabel(label) => {
683 write!(f, "\nError: Duplicate label: \"{}\" \n{}\n", label, pe.spans.error(pe.hint.as_ref()))
684 }
685 ParserErrorKind::DuplicateMacro(mn) => {
686 write!(f, "\nError: Duplicate MACRO name found: \"{}\" \n{}\n", mn, pe.spans.error(pe.hint.as_ref()))
687 }
688 ParserErrorKind::InvalidTableStatement(statement_type) => {
689 write!(f, "\nError: Invalid Table Statement: \"{}\" \n{}\n", statement_type, pe.spans.error(pe.hint.as_ref()))
690 }
691 ParserErrorKind::InvalidExpression(token) => {
692 write!(
693 f,
694 "\nError at token {}: Invalid expression syntax: \"{}\" \n{}\n",
695 pe.cursor,
696 token,
697 pe.spans.error(pe.hint.as_ref())
698 )
699 }
700 },
701 CompilerError::PathBufRead(os_str) => {
702 write!(f, "\nError: Invalid Import Path: \"{}\"", os_str.as_os_str().to_str().unwrap_or("<unknown import>"))
703 }
704 CompilerError::CodegenError(ce) => match &ce.kind {
705 CodegenErrorKind::LockingError => {
706 write!(f, "\nError: Synchronisation Failure\n")
707 }
708 CodegenErrorKind::StoragePointersNotDerived => {
709 write!(f, "\nError: Storage Pointers Not Derived\n{}\n", ce.span.error(None))
710 }
711 CodegenErrorKind::InvalidMacroStatement => {
712 write!(f, "\nError: Invalid Macro Statement\n{}\n", ce.span.error(None))
713 }
714 CodegenErrorKind::InvalidArgumentCount(mn, expected, actual) => {
715 write!(
716 f,
717 "\nError: Invalid Argument Count for \"{}\", expected {}, got {}!\n{}",
718 mn,
719 expected,
720 actual,
721 ce.span.error(None)
722 )
723 }
724 CodegenErrorKind::MissingArgumentDefinition(ad) => {
725 write!(f, "\nError: Missing Argument Definition For \"{}\"\n{}", ad, ce.span.error(None))
726 }
727 CodegenErrorKind::MissingMacroDefinition(md) => {
728 write!(f, "\nError: Missing Macro Definition For \"{}\"\n{}", md, ce.span.file())
729 }
730 CodegenErrorKind::InvalidMacroInvocation(mmi) => {
731 write!(f, "\nError: Missing Macro Definition For Invocation: \"{}\"\n{}\n", mmi, ce.span.error(None))
732 }
733 CodegenErrorKind::MissingFunctionInterface(func) => {
734 write!(f, "\nError: Missing Function Interface: \"{}\"\n{}\n", func, ce.span.error(None))
735 }
736 CodegenErrorKind::MissingEventInterface(event) => {
737 write!(f, "\nError: Missing Event Interface: \"{}\"\n{}\n", event, ce.span.error(None))
738 }
739 CodegenErrorKind::MissingConstantDefinition(_) => {
740 write!(f, "\nError: Missing Constant Definition\n{}\n", ce.span.error(None))
741 }
742 CodegenErrorKind::StringConstantNotBytes(msg) => {
743 write!(f, "\nError: String constant cannot be used directly: {}\n{}\n", msg, ce.span.error(None))
744 }
745 CodegenErrorKind::MissingErrorDefinition(_) => {
746 write!(f, "\nError: Missing Error Definition\n{}\n", ce.span.error(None))
747 }
748 CodegenErrorKind::AbiGenerationFailure => {
749 write!(f, "\nError: ABI Generation Failed\n{}\n", ce.span.error(None))
750 }
751 CodegenErrorKind::IOError(ioe) => {
752 write!(f, "\nError: IO Error: {ioe}\n{}", ce.span.file())
753 }
754 CodegenErrorKind::UnkownArgcallType => {
755 write!(f, "\nError: Unknown Arg Call Type\n{}\n", ce.span.error(None))
756 }
757 CodegenErrorKind::MissingMacroInvocation(mmi) => {
758 write!(f, "\nError: Missing Macro Invocation: \"{}\"\n{}\n", mmi, ce.span.error(None))
759 }
760 CodegenErrorKind::UnmatchedJumpLabels(labels) => {
761 write!(f, "\nError: Unmatched Jump Labels: \"{}\"\n{}\n", labels.join(", "), ce.span.error(None))
762 }
763 CodegenErrorKind::UsizeConversion(_) => {
764 write!(f, "\nError: Usize Conversion\n{}\n", ce.span.error(None))
765 }
766 CodegenErrorKind::InvalidArguments(_) => {
767 write!(f, "\nError: Invalid Arguments\n{}\n", ce.span.error(None))
768 }
769 CodegenErrorKind::InvalidMacroArgumentType(msg) => {
770 write!(f, "\nError: Invalid Macro Argument Type\n{}\n{}\n", msg, ce.span.error(None))
771 }
772 CodegenErrorKind::InvalidHex(_) => {
773 write!(f, "\nError: Invalid Hex\n{}\n", ce.span.error(None))
774 }
775 CodegenErrorKind::InvalidTableStatement(_) => {
776 write!(f, "\nError: Invalid Table Statement\n{}\n", ce.span.error(None))
777 }
778 CodegenErrorKind::InvalidCodeLength(_) => {
779 write!(f, "\nError: Invalid Code Length\n{}\n", ce.span.error(None))
780 }
781 CodegenErrorKind::TestInvocation(_) => {
782 write!(f, "\nError: Test Invocation\n{}\n", ce.span.error(None))
783 }
784 CodegenErrorKind::InvalidConstructorArgs(msg) => {
785 write!(f, "\nError: Invalid constructor arguments: {msg}\n{}\n", ce.span.error(None))
786 }
787 CodegenErrorKind::ArgsStartOutsideConstructor => {
788 write!(
789 f,
790 "\nError: __argsstart() can only be used in the constructor, as constructor arguments are not part of the deployed code\n{}\n",
791 ce.span.error(None)
792 )
793 }
794 CodegenErrorKind::MissingTableSize(table_name) => {
795 write!(f, "\nError: Missing Table Size for table: \"{table_name}\"\n{}\n", ce.span.error(None))
796 }
797 CodegenErrorKind::UnsupportedBuiltinFunction(bf) => {
798 write!(f, "\nError: Unsupported Builtin Function: \"{bf}\"\n{}\n", ce.span.error(None))
799 }
800 CodegenErrorKind::RuntimeSizeNotComputed => {
801 write!(
802 f,
803 "\nError: __codesize(RUNTIME) cannot be resolved here: MAIN bytecode has not been generated yet\n{}\n",
804 ce.span.error(None)
805 )
806 }
807 CodegenErrorKind::CodesizeRuntimeInCodeTable => {
808 write!(f, "\nError: __codesize(RUNTIME) is not allowed inside a code table\n{}\n", ce.span.error(None))
809 }
810 CodegenErrorKind::CodesizeNotConverged(iterations) => {
811 write!(f, "\nError: __codesize did not converge after {iterations} codegen passes\n{}\n", ce.span.error(None))
812 }
813 CodegenErrorKind::UnsupportedStatementType(st) => {
814 write!(f, "\nError: Unsupported Statement Type: \"{st}\"\n{}\n", ce.span.error(None))
815 }
816 CodegenErrorKind::DuplicateLabelInScope(label) => {
817 write!(f, "\nError: Duplicate label '{}' defined in the same scope\n{}\n", label, ce.span.error(None))
818 }
819 CodegenErrorKind::DuplicateLabelAcrossSiblings(label) => {
820 write!(f, "\nError: Duplicate label '{}' defined across siblings in same scope\n{}\n", label, ce.span.error(None))
821 }
822 CodegenErrorKind::DuplicateTableEmbedding(table) => {
823 write!(f, "\nError: Table \"{}\" has already been embedded\n{}\n", table, ce.span.error(None))
824 }
825 CodegenErrorKind::JumpTargetTooLarge { label, target, opcode } => {
826 write!(
827 f,
828 "\nError: Jump target {:#x} too large for {} in label \"{}\"\n{}\n",
829 target,
830 opcode,
831 label,
832 ce.span.error(None)
833 )
834 }
835 CodegenErrorKind::CircularMacroInvocation(macro_name) => {
836 write!(
837 f,
838 "\nError: Circular macro invocation detected: '{}' is already in the call stack\n{}\n",
839 macro_name,
840 ce.span.error(None)
841 )
842 }
843 CodegenErrorKind::CircularConstantDependency(constant_name) => {
844 write!(
845 f,
846 "\nError: Circular constant dependency detected: '{}' is already being evaluated\n{}\n",
847 constant_name,
848 ce.span.error(None)
849 )
850 }
851 CodegenErrorKind::RecursionDepthExceeded(depth) => {
852 write!(f, "\nError: Recursion depth limit exceeded: maximum depth of {} reached\n{}\n", depth, ce.span.error(None))
853 }
854 CodegenErrorKind::UndefinedConstant(name) => {
855 write!(f, "\nError: Undefined constant '{}' used in expression\n{}\n", name, ce.span.error(None))
856 }
857 CodegenErrorKind::InvalidConstantExpression => {
858 write!(f, "\nError: Invalid constant expression - contains runtime elements\n{}\n", ce.span.error(None))
859 }
860 CodegenErrorKind::ArithmeticOverflow => {
861 write!(f, "\nError: Arithmetic overflow in constant expression\n{}\n", ce.span.error(None))
862 }
863 CodegenErrorKind::ArithmeticUnderflow => {
864 write!(f, "\nError: Arithmetic underflow in constant expression\n{}\n", ce.span.error(None))
865 }
866 CodegenErrorKind::DivisionByZero => {
867 write!(f, "\nError: Division by zero in constant expression\n{}\n", ce.span.error(None))
868 }
869 CodegenErrorKind::ArgCallInConstantExpression(name) => {
870 write!(
871 f,
872 "\nError: Macro argument <{}> cannot be used in global constant expression\nRequires macro invocation context\n{}\n",
873 name,
874 ce.span.error(None)
875 )
876 }
877 CodegenErrorKind::InvalidOpcodeForEVMVersion(opcode, required_version, current_version) => {
878 write!(
879 f,
880 "\nError: Opcode '{}' requires EVM version '{}' or later (current version: '{}')\n{}\n",
881 opcode,
882 required_version,
883 current_version,
884 ce.span.error(None)
885 )
886 }
887 CodegenErrorKind::InvalidLoopStep => {
888 write!(f, "\nError: Invalid loop step: step value cannot be zero\n{}\n", ce.span.error(None))
889 }
890 CodegenErrorKind::LoopIterationLimitExceeded(max) => {
891 write!(
892 f,
893 "\nError: Loop iteration limit exceeded\nMaximum {} iterations allowed at compile-time\n{}\n",
894 max,
895 ce.span.error(None)
896 )
897 }
898 CodegenErrorKind::AssertPcFailed(expected, actual) => {
899 write!(
900 f,
901 "\nError: PC assertion failed\nExpected position: 0x{:x}\nActual position: 0x{:x}\n{}\n",
902 expected,
903 actual,
904 ce.span.error(None)
905 )
906 }
907 CodegenErrorKind::ArgResolutionLimitExceeded(arg_name, max_iterations) => {
908 write!(
909 f,
910 "\nError: Exceeded maximum iterations ({}) while resolving argument reference '<{}>'\nPossible circular argument reference\n{}\n",
911 max_iterations,
912 arg_name,
913 ce.span.error(None)
914 )
915 }
916 CodegenErrorKind::BubbleArgLimitExceeded(arg_name, max_iterations) => {
917 write!(
918 f,
919 "\nError: Exceeded maximum iterations ({}) while bubbling argument '<{}>' up through nested macro calls\n{}\n",
920 max_iterations,
921 arg_name,
922 ce.span.error(None)
923 )
924 }
925 CodegenErrorKind::ContractSizeLimitExceeded(size, limit) => {
926 write!(
927 f,
928 "\nError: Contract bytecode size ({} bytes) exceeds the contract size limit ({} bytes)\nUse --no-size-limit to skip this check\n{}\n",
929 size,
930 limit,
931 ce.span.error(None)
932 )
933 }
934 CodegenErrorKind::InvalidOpcodeOperand(msg) => {
935 write!(f, "\nError: Invalid Opcode Operand\n{}\n{}\n", msg, ce.span.error(None))
936 }
937 CodegenErrorKind::OffsetExceedsTwoBytes(what, offset) => {
938 write!(f, "\nError: Offset {:#x} of {} does not fit into 2 bytes\n{}\n", offset, what, ce.span.error(None))
939 }
940 CodegenErrorKind::InitcodeSizeLimitExceeded(size, limit) => {
941 write!(
942 f,
943 "\nError: Deployment bytecode size ({} bytes) exceeds the initcode size limit ({} bytes)\nUse --no-size-limit to skip this check\n{}\n",
944 size,
945 limit,
946 ce.span.error(None)
947 )
948 }
949 },
950 CompilerError::FailedCompiles(v) => {
951 v.iter().for_each(|ce| {
952 let _ = write!(f, "{ce}");
953 });
954 Ok(())
955 }
956 CompilerError::EmptyImportPath(os_str) => {
957 write!(f, "\nError: Import path with empty string: \"{}\"", os_str.as_os_str().to_str().unwrap_or("<unknown import>"))
958 }
959 CompilerError::UnknownConstantOverride(name) => {
960 write!(f, "\nError: Constant override \"{name}\" does not match any constant in the source\n")
961 }
962 }
963 }
964}