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}
55
56impl SymbolResolutionError {
57 pub fn undefined(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
58 Self::UndefinedSymbol {
59 span,
60 source_file: source_manager.get(span.source_id()).ok(),
61 }
62 }
63
64 pub fn invalid_alias_target(
65 span: SourceSpan,
66 referrer: SourceSpan,
67 source_manager: &dyn SourceManager,
68 ) -> Self {
69 let referer_source_file = source_manager.get(referrer.source_id()).ok();
70 let source_file = source_manager.get(span.source_id()).ok();
71 Self::InvalidAliasTarget {
72 span,
73 source_file,
74 relative_to: Some(
75 RelatedLabel::advice("this reference specifies a subpath relative to an import")
76 .with_labeled_span(
77 referrer,
78 "this reference specifies a subpath relative to an import",
79 )
80 .with_source_file(referer_source_file),
81 ),
82 }
83 }
84
85 pub fn invalid_sub_path(
86 span: SourceSpan,
87 relative_to: SourceSpan,
88 source_manager: &dyn SourceManager,
89 ) -> Self {
90 let relative_to_source_file = source_manager.get(relative_to.source_id()).ok();
91 let source_file = source_manager.get(span.source_id()).ok();
92 Self::InvalidSubPath {
93 span,
94 source_file,
95 relative_to: Some(
96 RelatedLabel::advice("but this item is not a module")
97 .with_labeled_span(relative_to, "but this item is not a module")
98 .with_source_file(relative_to_source_file),
99 ),
100 }
101 }
102
103 pub fn invalid_symbol_type(
104 span: SourceSpan,
105 expected: &'static str,
106 actual: SourceSpan,
107 source_manager: &dyn SourceManager,
108 ) -> Self {
109 let actual_source_file = source_manager.get(actual.source_id()).ok();
110 let source_file = source_manager.get(span.source_id()).ok();
111 Self::InvalidSymbolType {
112 expected,
113 span,
114 source_file,
115 actual: Some(
116 RelatedLabel::advice("but the symbol resolved to this item")
117 .with_labeled_span(actual, "but the symbol resolved to this item")
118 .with_source_file(actual_source_file),
119 ),
120 }
121 }
122}