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_sub_path(
113 span: SourceSpan,
114 relative_to: SourceSpan,
115 source_manager: &dyn SourceManager,
116 ) -> Self {
117 let relative_to_source_file = source_manager.get(relative_to.source_id()).ok();
118 let source_file = source_manager.get(span.source_id()).ok();
119 Self::InvalidSubPath {
120 span,
121 source_file,
122 relative_to: Some(
123 RelatedLabel::advice("but this item is not a module")
124 .with_labeled_span(relative_to, "but this item is not a module")
125 .with_source_file(relative_to_source_file),
126 ),
127 }
128 }
129
130 pub fn invalid_symbol_type(
131 span: SourceSpan,
132 expected: &'static str,
133 actual: SourceSpan,
134 source_manager: &dyn SourceManager,
135 ) -> Self {
136 let actual_source_file = source_manager.get(actual.source_id()).ok();
137 let source_file = source_manager.get(span.source_id()).ok();
138 Self::InvalidSymbolType {
139 expected,
140 span,
141 source_file,
142 actual: Some(
143 RelatedLabel::advice("but the symbol resolved to this item")
144 .with_labeled_span(actual, "but the symbol resolved to this item")
145 .with_source_file(actual_source_file),
146 ),
147 }
148 }
149
150 pub fn private_symbol(
151 span: SourceSpan,
152 defined: SourceSpan,
153 source_manager: &dyn SourceManager,
154 ) -> Self {
155 let defined_source_file = source_manager.get(defined.source_id()).ok();
156 let source_file = source_manager.get(span.source_id()).ok();
157 Self::PrivateSymbol {
158 span,
159 source_file,
160 defined: Some(
161 RelatedLabel::advice("the referenced item is private")
162 .with_labeled_span(defined, "the referenced item is private")
163 .with_source_file(defined_source_file),
164 ),
165 }
166 }
167
168 pub fn type_expression_depth_exceeded(
169 span: SourceSpan,
170 max_depth: usize,
171 source_manager: &dyn SourceManager,
172 ) -> Self {
173 Self::TypeExpressionDepthExceeded {
174 span,
175 source_file: source_manager.get(span.source_id()).ok(),
176 max_depth,
177 }
178 }
179
180 pub fn alias_expansion_depth_exceeded(
181 span: SourceSpan,
182 max_depth: usize,
183 source_manager: &dyn SourceManager,
184 ) -> Self {
185 Self::AliasExpansionDepthExceeded {
186 span,
187 source_file: source_manager.get(span.source_id()).ok(),
188 max_depth,
189 }
190 }
191
192 pub fn too_many_items_in_module(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
193 Self::TooManyItemsInModule {
194 span,
195 source_file: source_manager.get(span.source_id()).ok(),
196 max_items: ItemIndex::MAX_ITEMS,
197 }
198 }
199}