miden_assembly/linker/
errors.rs1#![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#[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("ambiguous module path resolution for '{path}'")]
48 #[diagnostic(help("matching module prefixes: {}", matches.join(", ")))]
49 AmbiguousModulePath {
50 #[label]
51 span: SourceSpan,
52 #[source_code]
53 source_file: Option<Arc<SourceFile>>,
54 path: Arc<Path>,
55 matches: Box<[String]>,
56 },
57 #[error("undefined module '{path}'")]
58 #[diagnostic()]
59 UndefinedModule {
60 #[label]
61 span: SourceSpan,
62 #[source_code]
63 source_file: Option<Arc<SourceFile>>,
64 path: Arc<Path>,
65 },
66 #[error("undefined item '{path}'")]
67 #[diagnostic(help(
68 "you might be missing an import, or the containing library has not been linked"
69 ))]
70 UndefinedSymbol {
71 #[label]
72 span: SourceSpan,
73 #[source_code]
74 source_file: Option<Arc<SourceFile>>,
75 path: Arc<Path>,
76 },
77 #[error("invalid syscall: '{callee}' is not an exported kernel procedure")]
78 #[diagnostic()]
79 InvalidSysCallTarget {
80 #[label("call occurs here")]
81 span: SourceSpan,
82 #[source_code]
83 source_file: Option<Arc<SourceFile>>,
84 callee: Arc<Path>,
85 },
86 #[error("kernel procedure '{callee}' can only be invoked via syscall")]
87 #[diagnostic()]
88 KernelProcNotSyscall {
89 #[label("non-syscall reference to kernel procedure")]
90 span: SourceSpan,
91 #[source_code]
92 source_file: Option<Arc<SourceFile>>,
93 callee: Arc<Path>,
94 },
95 #[error("invalid procedure reference: path refers to a non-procedure item")]
96 #[diagnostic()]
97 InvalidInvokeTarget {
98 #[label("this path resolves to {path}, which is not a procedure")]
99 span: SourceSpan,
100 #[source_code]
101 source_file: Option<Arc<SourceFile>>,
102 path: Arc<Path>,
103 },
104 #[error("value for key {key} already present in the advice map")]
105 #[diagnostic(help(
106 "previous values at key were '{prev_values:?}'. Operation would have replaced them with '{new_values:?}'",
107 ))]
108 AdviceMapKeyAlreadyPresent {
109 key: Word,
110 prev_values: Vec<Felt>,
111 new_values: Vec<Felt>,
112 },
113 #[error("undefined type alias")]
114 #[diagnostic()]
115 UndefinedType {
116 #[label]
117 span: SourceSpan,
118 #[source_code]
119 source_file: Option<Arc<SourceFile>>,
120 },
121 #[error("invalid type reference")]
122 #[diagnostic(help("the item this path resolves to is not a type definition"))]
123 InvalidTypeRef {
124 #[label]
125 span: SourceSpan,
126 #[source_code]
127 source_file: Option<Arc<SourceFile>>,
128 },
129 #[error("invalid constant reference")]
130 #[diagnostic(help("the item this path resolves to is not a constant definition"))]
131 InvalidConstantRef {
132 #[label]
133 span: SourceSpan,
134 #[source_code]
135 source_file: Option<Arc<SourceFile>>,
136 },
137}
138
139impl From<SymbolResolutionError> for LinkerError {
140 #[inline]
141 fn from(value: SymbolResolutionError) -> Self {
142 Self::SymbolResolution(Box::new(value))
143 }
144}
145
146impl From<ConstEvalError> for LinkerError {
147 #[inline]
148 fn from(value: ConstEvalError) -> Self {
149 Self::ConstEval(Box::new(value))
150 }
151}