Skip to main content

miden_assembly/linker/
errors.rs

1// Allow unused assignments - required by miette::Diagnostic derive macro
2#![allow(unused_assignments)]
3
4use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
5
6use miden_assembly_syntax::{
7    Felt, Path, Word,
8    ast::{SymbolResolutionError, constants::ConstEvalError},
9    debuginfo::{SourceFile, SourceSpan},
10    diagnostics::{Diagnostic, RelatedError, RelatedLabel, miette},
11};
12
13// LINKER ERROR
14// ================================================================================================
15
16/// An error which can be generated while linking modules and resolving procedure references.
17#[derive(Debug, thiserror::Error, Diagnostic)]
18#[non_exhaustive]
19pub enum LinkerError {
20    #[error("there are no modules to analyze")]
21    #[diagnostic()]
22    Empty,
23    #[error(transparent)]
24    #[diagnostic(transparent)]
25    SymbolResolution(#[from] Box<SymbolResolutionError>),
26    #[error(transparent)]
27    #[diagnostic(transparent)]
28    ConstEval(#[from] Box<ConstEvalError>),
29    #[error("linking failed")]
30    #[diagnostic(help("see diagnostics for details"))]
31    Related {
32        #[related]
33        errors: Box<[RelatedError]>,
34    },
35    #[error("linking failed")]
36    #[diagnostic(help("see diagnostics for details"))]
37    Failed {
38        #[related]
39        labels: Box<[RelatedLabel]>,
40    },
41    #[error("found a cycle in the call graph, involving these procedures: {}", nodes.join(", "))]
42    #[diagnostic()]
43    Cycle { nodes: Box<[String]> },
44    #[error("duplicate definition found for module '{path}'")]
45    #[diagnostic()]
46    DuplicateModule { path: Arc<Path> },
47    #[error("undefined module '{path}'")]
48    #[diagnostic()]
49    UndefinedModule {
50        #[label]
51        span: SourceSpan,
52        #[source_code]
53        source_file: Option<Arc<SourceFile>>,
54        path: Arc<Path>,
55    },
56    #[error("undefined item '{path}'")]
57    #[diagnostic(help(
58        "you might be missing an import, or the containing library has not been linked"
59    ))]
60    UndefinedSymbol {
61        #[label]
62        span: SourceSpan,
63        #[source_code]
64        source_file: Option<Arc<SourceFile>>,
65        path: Arc<Path>,
66    },
67    #[error("invalid syscall: '{callee}' is not an exported kernel procedure")]
68    #[diagnostic()]
69    InvalidSysCallTarget {
70        #[label("call occurs here")]
71        span: SourceSpan,
72        #[source_code]
73        source_file: Option<Arc<SourceFile>>,
74        callee: Arc<Path>,
75    },
76    #[error("invalid procedure reference: path refers to a non-procedure item")]
77    #[diagnostic()]
78    InvalidInvokeTarget {
79        #[label("this path resolves to {path}, which is not a procedure")]
80        span: SourceSpan,
81        #[source_code]
82        source_file: Option<Arc<SourceFile>>,
83        path: Arc<Path>,
84    },
85    #[error("value for key {key} already present in the advice map")]
86    #[diagnostic(help(
87        "previous values at key were '{prev_values:?}'. Operation would have replaced them with '{new_values:?}'",
88    ))]
89    AdviceMapKeyAlreadyPresent {
90        key: Word,
91        prev_values: Vec<Felt>,
92        new_values: Vec<Felt>,
93    },
94    #[error("undefined type alias")]
95    #[diagnostic()]
96    UndefinedType {
97        #[label]
98        span: SourceSpan,
99        #[source_code]
100        source_file: Option<Arc<SourceFile>>,
101    },
102    #[error("invalid type reference")]
103    #[diagnostic(help("the item this path resolves to is not a type definition"))]
104    InvalidTypeRef {
105        #[label]
106        span: SourceSpan,
107        #[source_code]
108        source_file: Option<Arc<SourceFile>>,
109    },
110    #[error("invalid constant reference")]
111    #[diagnostic(help("the item this path resolves to is not a constant definition"))]
112    InvalidConstantRef {
113        #[label]
114        span: SourceSpan,
115        #[source_code]
116        source_file: Option<Arc<SourceFile>>,
117    },
118}
119
120impl From<SymbolResolutionError> for LinkerError {
121    #[inline]
122    fn from(value: SymbolResolutionError) -> Self {
123        Self::SymbolResolution(Box::new(value))
124    }
125}
126
127impl From<ConstEvalError> for LinkerError {
128    #[inline]
129    fn from(value: ConstEvalError) -> Self {
130        Self::ConstEval(Box::new(value))
131    }
132}