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::diagnostics::{Diagnostic, RelatedLabel, miette};
9
10#[derive(Debug, Clone, thiserror::Error, Diagnostic)]
12pub enum SymbolResolutionError {
13 #[error("undefined symbol reference")]
14 #[diagnostic(help("maybe you are missing an import?"))]
15 UndefinedSymbol {
16 #[label("this symbol path could not be resolved")]
17 span: SourceSpan,
18 #[source_code]
19 source_file: Option<Arc<SourceFile>>,
20 },
21 #[error("invalid symbol reference")]
22 #[diagnostic(help(
23 "references to a subpath of an imported symbol require the imported item to be a module"
24 ))]
25 InvalidAliasTarget {
26 #[label("this reference specifies a subpath relative to an import")]
27 span: SourceSpan,
28 #[source_code]
29 source_file: Option<Arc<SourceFile>>,
30 #[related]
31 relative_to: Option<RelatedLabel>,
32 },
33 #[error("invalid symbol path")]
34 #[diagnostic(help("all ancestors of a path must be modules"))]
35 InvalidSubPath {
36 #[label("this path specifies a subpath relative to another item")]
37 span: SourceSpan,
38 #[source_code]
39 source_file: Option<Arc<SourceFile>>,
40 #[related]
41 relative_to: Option<RelatedLabel>,
42 },
43 #[error("invalid symbol reference: wrong type")]
44 #[diagnostic()]
45 InvalidSymbolType {
46 expected: &'static str,
47 #[label("expected this symbol to reference a {expected} item")]
48 span: SourceSpan,
49 #[source_code]
50 source_file: Option<Arc<SourceFile>>,
51 #[related]
52 actual: Option<RelatedLabel>,
53 },
54 #[error("type expression nesting depth exceeded")]
55 #[diagnostic(help("type expression nesting exceeded the maximum depth of {max_depth}"))]
56 TypeExpressionDepthExceeded {
57 #[label("type expression nesting exceeded the configured depth limit")]
58 span: SourceSpan,
59 #[source_code]
60 source_file: Option<Arc<SourceFile>>,
61 max_depth: usize,
62 },
63 #[error("alias expansion cycle detected")]
64 #[diagnostic(help("alias expansion encountered a cycle"))]
65 AliasExpansionCycle {
66 #[label("this alias expansion is part of a cycle")]
67 span: SourceSpan,
68 #[source_code]
69 source_file: Option<Arc<SourceFile>>,
70 },
71 #[error("alias expansion depth exceeded")]
72 #[diagnostic(help("alias expansion exceeded the maximum depth of {max_depth}"))]
73 AliasExpansionDepthExceeded {
74 #[label("alias expansion exceeded the configured depth limit")]
75 span: SourceSpan,
76 #[source_code]
77 source_file: Option<Arc<SourceFile>>,
78 max_depth: usize,
79 },
80}
81
82impl SymbolResolutionError {
83 pub fn undefined(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
84 Self::UndefinedSymbol {
85 span,
86 source_file: source_manager.get(span.source_id()).ok(),
87 }
88 }
89
90 pub fn invalid_alias_target(
91 span: SourceSpan,
92 referrer: SourceSpan,
93 source_manager: &dyn SourceManager,
94 ) -> Self {
95 let referer_source_file = source_manager.get(referrer.source_id()).ok();
96 let source_file = source_manager.get(span.source_id()).ok();
97 Self::InvalidAliasTarget {
98 span,
99 source_file,
100 relative_to: Some(
101 RelatedLabel::advice("this reference specifies a subpath relative to an import")
102 .with_labeled_span(
103 referrer,
104 "this reference specifies a subpath relative to an import",
105 )
106 .with_source_file(referer_source_file),
107 ),
108 }
109 }
110
111 pub fn invalid_sub_path(
112 span: SourceSpan,
113 relative_to: SourceSpan,
114 source_manager: &dyn SourceManager,
115 ) -> Self {
116 let relative_to_source_file = source_manager.get(relative_to.source_id()).ok();
117 let source_file = source_manager.get(span.source_id()).ok();
118 Self::InvalidSubPath {
119 span,
120 source_file,
121 relative_to: Some(
122 RelatedLabel::advice("but this item is not a module")
123 .with_labeled_span(relative_to, "but this item is not a module")
124 .with_source_file(relative_to_source_file),
125 ),
126 }
127 }
128
129 pub fn invalid_symbol_type(
130 span: SourceSpan,
131 expected: &'static str,
132 actual: SourceSpan,
133 source_manager: &dyn SourceManager,
134 ) -> Self {
135 let actual_source_file = source_manager.get(actual.source_id()).ok();
136 let source_file = source_manager.get(span.source_id()).ok();
137 Self::InvalidSymbolType {
138 expected,
139 span,
140 source_file,
141 actual: Some(
142 RelatedLabel::advice("but the symbol resolved to this item")
143 .with_labeled_span(actual, "but the symbol resolved to this item")
144 .with_source_file(actual_source_file),
145 ),
146 }
147 }
148
149 pub fn type_expression_depth_exceeded(
150 span: SourceSpan,
151 max_depth: usize,
152 source_manager: &dyn SourceManager,
153 ) -> Self {
154 Self::TypeExpressionDepthExceeded {
155 span,
156 source_file: source_manager.get(span.source_id()).ok(),
157 max_depth,
158 }
159 }
160
161 pub fn alias_expansion_cycle(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
162 Self::AliasExpansionCycle {
163 span,
164 source_file: source_manager.get(span.source_id()).ok(),
165 }
166 }
167
168 pub fn alias_expansion_depth_exceeded(
169 span: SourceSpan,
170 max_depth: usize,
171 source_manager: &dyn SourceManager,
172 ) -> Self {
173 Self::AliasExpansionDepthExceeded {
174 span,
175 source_file: source_manager.get(span.source_id()).ok(),
176 max_depth,
177 }
178 }
179}