miden_assembly_syntax/ast/item/resolver/
error.rs1#![allow(unused_assignments)]
3
4use alloc::sync::Arc;
5
6use miden_debug_types::{SourceFile, SourceManager, SourceSpan};
7
8use crate::{
9 ast::ItemIndex,
10 diagnostics::{Diagnostic, RelatedLabel, miette},
11};
12
13#[derive(Debug, Clone, thiserror::Error, Diagnostic)]
15pub enum SymbolResolutionError {
16 #[error("undefined symbol reference")]
17 #[diagnostic(help("maybe you are missing an import?"))]
18 UndefinedSymbol {
19 #[label("this symbol path could not be resolved")]
20 span: SourceSpan,
21 #[source_code]
22 source_file: Option<Arc<SourceFile>>,
23 },
24 #[error("invalid symbol reference")]
25 #[diagnostic(help(
26 "references to a subpath of an imported symbol require the imported item to be a module"
27 ))]
28 InvalidAliasTarget {
29 #[label("this reference specifies a subpath relative to an import")]
30 span: SourceSpan,
31 #[source_code]
32 source_file: Option<Arc<SourceFile>>,
33 #[related]
34 relative_to: Option<RelatedLabel>,
35 },
36 #[error("invalid symbol path")]
37 #[diagnostic(help("all ancestors of a path must be modules"))]
38 InvalidSubPath {
39 #[label("this path specifies a subpath relative to another item")]
40 span: SourceSpan,
41 #[source_code]
42 source_file: Option<Arc<SourceFile>>,
43 #[related]
44 relative_to: Option<RelatedLabel>,
45 },
46 #[error("invalid symbol reference: wrong type")]
47 #[diagnostic()]
48 InvalidSymbolType {
49 expected: &'static str,
50 #[label("expected this symbol to reference a {expected} item")]
51 span: SourceSpan,
52 #[source_code]
53 source_file: Option<Arc<SourceFile>>,
54 #[related]
55 actual: Option<RelatedLabel>,
56 },
57 #[error("private symbol reference")]
58 #[diagnostic(help("only public items can be referenced from another module"))]
59 PrivateSymbol {
60 #[label("this symbol is private to another module")]
61 span: SourceSpan,
62 #[source_code]
63 source_file: Option<Arc<SourceFile>>,
64 #[related]
65 defined: Option<RelatedLabel>,
66 },
67 #[error("type expression nesting depth exceeded")]
68 #[diagnostic(help("type expression nesting exceeded the maximum depth of {max_depth}"))]
69 TypeExpressionDepthExceeded {
70 #[label("type expression nesting exceeded the configured depth limit")]
71 span: SourceSpan,
72 #[source_code]
73 source_file: Option<Arc<SourceFile>>,
74 max_depth: usize,
75 },
76 #[error("alias expansion cycle detected")]
77 #[diagnostic(help("alias expansion encountered a cycle"))]
78 AliasExpansionCycle {
79 #[label("this alias expansion is part of a cycle")]
80 span: SourceSpan,
81 #[source_code]
82 source_file: Option<Arc<SourceFile>>,
83 },
84 #[error("alias expansion depth exceeded")]
85 #[diagnostic(help("alias expansion exceeded the maximum depth of {max_depth}"))]
86 AliasExpansionDepthExceeded {
87 #[label("alias expansion exceeded the configured depth limit")]
88 span: SourceSpan,
89 #[source_code]
90 source_file: Option<Arc<SourceFile>>,
91 max_depth: usize,
92 },
93 #[error("too many items in module")]
94 #[diagnostic(help("break this module up into smaller modules"))]
95 TooManyItemsInModule {
96 #[label("module item count exceeds the supported limit of {max_items}")]
97 span: SourceSpan,
98 #[source_code]
99 source_file: Option<Arc<SourceFile>>,
100 max_items: usize,
101 },
102}
103
104impl SymbolResolutionError {
105 pub fn undefined(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
106 Self::UndefinedSymbol {
107 span,
108 source_file: source_manager.get(span.source_id()).ok(),
109 }
110 }
111
112 pub fn invalid_alias_target(
113 span: SourceSpan,
114 referrer: SourceSpan,
115 source_manager: &dyn SourceManager,
116 ) -> Self {
117 let referer_source_file = source_manager.get(referrer.source_id()).ok();
118 let source_file = source_manager.get(span.source_id()).ok();
119 Self::InvalidAliasTarget {
120 span,
121 source_file,
122 relative_to: Some(
123 RelatedLabel::advice("this reference specifies a subpath relative to an import")
124 .with_labeled_span(
125 referrer,
126 "this reference specifies a subpath relative to an import",
127 )
128 .with_source_file(referer_source_file),
129 ),
130 }
131 }
132
133 pub fn invalid_sub_path(
134 span: SourceSpan,
135 relative_to: SourceSpan,
136 source_manager: &dyn SourceManager,
137 ) -> Self {
138 let relative_to_source_file = source_manager.get(relative_to.source_id()).ok();
139 let source_file = source_manager.get(span.source_id()).ok();
140 Self::InvalidSubPath {
141 span,
142 source_file,
143 relative_to: Some(
144 RelatedLabel::advice("but this item is not a module")
145 .with_labeled_span(relative_to, "but this item is not a module")
146 .with_source_file(relative_to_source_file),
147 ),
148 }
149 }
150
151 pub fn invalid_symbol_type(
152 span: SourceSpan,
153 expected: &'static str,
154 actual: SourceSpan,
155 source_manager: &dyn SourceManager,
156 ) -> Self {
157 let actual_source_file = source_manager.get(actual.source_id()).ok();
158 let source_file = source_manager.get(span.source_id()).ok();
159 Self::InvalidSymbolType {
160 expected,
161 span,
162 source_file,
163 actual: Some(
164 RelatedLabel::advice("but the symbol resolved to this item")
165 .with_labeled_span(actual, "but the symbol resolved to this item")
166 .with_source_file(actual_source_file),
167 ),
168 }
169 }
170
171 pub fn private_symbol(
172 span: SourceSpan,
173 defined: SourceSpan,
174 source_manager: &dyn SourceManager,
175 ) -> Self {
176 let defined_source_file = source_manager.get(defined.source_id()).ok();
177 let source_file = source_manager.get(span.source_id()).ok();
178 Self::PrivateSymbol {
179 span,
180 source_file,
181 defined: Some(
182 RelatedLabel::advice("the referenced item is private")
183 .with_labeled_span(defined, "the referenced item is private")
184 .with_source_file(defined_source_file),
185 ),
186 }
187 }
188
189 pub fn type_expression_depth_exceeded(
190 span: SourceSpan,
191 max_depth: usize,
192 source_manager: &dyn SourceManager,
193 ) -> Self {
194 Self::TypeExpressionDepthExceeded {
195 span,
196 source_file: source_manager.get(span.source_id()).ok(),
197 max_depth,
198 }
199 }
200
201 pub fn alias_expansion_cycle(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
202 Self::AliasExpansionCycle {
203 span,
204 source_file: source_manager.get(span.source_id()).ok(),
205 }
206 }
207
208 pub fn alias_expansion_depth_exceeded(
209 span: SourceSpan,
210 max_depth: usize,
211 source_manager: &dyn SourceManager,
212 ) -> Self {
213 Self::AliasExpansionDepthExceeded {
214 span,
215 source_file: source_manager.get(span.source_id()).ok(),
216 max_depth,
217 }
218 }
219
220 pub fn too_many_items_in_module(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
221 Self::TooManyItemsInModule {
222 span,
223 source_file: source_manager.get(span.source_id()).ok(),
224 max_items: ItemIndex::MAX_ITEMS,
225 }
226 }
227}