#![allow(unused_assignments)]
use alloc::sync::Arc;
use miden_debug_types::{SourceFile, SourceManager, SourceSpan};
use crate::diagnostics::{Diagnostic, RelatedLabel, miette};
#[derive(Debug, Clone, thiserror::Error, Diagnostic)]
pub enum SymbolResolutionError {
#[error("undefined symbol reference")]
#[diagnostic(help("maybe you are missing an import?"))]
UndefinedSymbol {
#[label("this symbol path could not be resolved")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
},
#[error("invalid symbol reference")]
#[diagnostic(help(
"references to a subpath of an imported symbol require the imported item to be a module"
))]
InvalidAliasTarget {
#[label("this reference specifies a subpath relative to an import")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
#[related]
relative_to: Option<RelatedLabel>,
},
#[error("invalid symbol path")]
#[diagnostic(help("all ancestors of a path must be modules"))]
InvalidSubPath {
#[label("this path specifies a subpath relative to another item")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
#[related]
relative_to: Option<RelatedLabel>,
},
#[error("invalid symbol reference: wrong type")]
#[diagnostic()]
InvalidSymbolType {
expected: &'static str,
#[label("expected this symbol to reference a {expected} item")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
#[related]
actual: Option<RelatedLabel>,
},
#[error("type expression nesting depth exceeded")]
#[diagnostic(help("type expression nesting exceeded the maximum depth of {max_depth}"))]
TypeExpressionDepthExceeded {
#[label("type expression nesting exceeded the configured depth limit")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
max_depth: usize,
},
#[error("alias expansion cycle detected")]
#[diagnostic(help("alias expansion encountered a cycle"))]
AliasExpansionCycle {
#[label("this alias expansion is part of a cycle")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
},
#[error("alias expansion depth exceeded")]
#[diagnostic(help("alias expansion exceeded the maximum depth of {max_depth}"))]
AliasExpansionDepthExceeded {
#[label("alias expansion exceeded the configured depth limit")]
span: SourceSpan,
#[source_code]
source_file: Option<Arc<SourceFile>>,
max_depth: usize,
},
}
impl SymbolResolutionError {
pub fn undefined(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
Self::UndefinedSymbol {
span,
source_file: source_manager.get(span.source_id()).ok(),
}
}
pub fn invalid_alias_target(
span: SourceSpan,
referrer: SourceSpan,
source_manager: &dyn SourceManager,
) -> Self {
let referer_source_file = source_manager.get(referrer.source_id()).ok();
let source_file = source_manager.get(span.source_id()).ok();
Self::InvalidAliasTarget {
span,
source_file,
relative_to: Some(
RelatedLabel::advice("this reference specifies a subpath relative to an import")
.with_labeled_span(
referrer,
"this reference specifies a subpath relative to an import",
)
.with_source_file(referer_source_file),
),
}
}
pub fn invalid_sub_path(
span: SourceSpan,
relative_to: SourceSpan,
source_manager: &dyn SourceManager,
) -> Self {
let relative_to_source_file = source_manager.get(relative_to.source_id()).ok();
let source_file = source_manager.get(span.source_id()).ok();
Self::InvalidSubPath {
span,
source_file,
relative_to: Some(
RelatedLabel::advice("but this item is not a module")
.with_labeled_span(relative_to, "but this item is not a module")
.with_source_file(relative_to_source_file),
),
}
}
pub fn invalid_symbol_type(
span: SourceSpan,
expected: &'static str,
actual: SourceSpan,
source_manager: &dyn SourceManager,
) -> Self {
let actual_source_file = source_manager.get(actual.source_id()).ok();
let source_file = source_manager.get(span.source_id()).ok();
Self::InvalidSymbolType {
expected,
span,
source_file,
actual: Some(
RelatedLabel::advice("but the symbol resolved to this item")
.with_labeled_span(actual, "but the symbol resolved to this item")
.with_source_file(actual_source_file),
),
}
}
pub fn type_expression_depth_exceeded(
span: SourceSpan,
max_depth: usize,
source_manager: &dyn SourceManager,
) -> Self {
Self::TypeExpressionDepthExceeded {
span,
source_file: source_manager.get(span.source_id()).ok(),
max_depth,
}
}
pub fn alias_expansion_cycle(span: SourceSpan, source_manager: &dyn SourceManager) -> Self {
Self::AliasExpansionCycle {
span,
source_file: source_manager.get(span.source_id()).ok(),
}
}
pub fn alias_expansion_depth_exceeded(
span: SourceSpan,
max_depth: usize,
source_manager: &dyn SourceManager,
) -> Self {
Self::AliasExpansionDepthExceeded {
span,
source_file: source_manager.get(span.source_id()).ok(),
max_depth,
}
}
}