//! Diagnostics emitted during DefMap construction. use std::ops::Not; use cfg::{CfgExpr, CfgOptions}; use hir_expand::{ErasedAstId, ExpandErrorKind, MacroCallKind, attrs::AttrId, mod_path::ModPath}; use la_arena::Idx; use syntax::ast; use crate::{AstId, nameres::ModuleId}; #[derive(Debug, PartialEq, Eq)] pub enum DefDiagnosticKind { UnresolvedModule { ast: AstId, candidates: Box<[String]> }, UnresolvedExternCrate { ast: AstId }, UnresolvedImport { id: AstId, index: Idx }, UnconfiguredCode { ast_id: ErasedAstId, cfg: CfgExpr, opts: CfgOptions }, UnresolvedMacroCall { ast: MacroCallKind, path: ModPath }, UnimplementedBuiltinMacro { ast: AstId }, InvalidDeriveTarget { ast: AstId, id: AttrId }, MalformedDerive { ast: AstId, id: AttrId }, MacroDefError { ast: AstId, message: String }, MacroError { ast: AstId, path: ModPath, err: ExpandErrorKind }, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct DefDiagnostics(Option>); impl DefDiagnostics { pub fn new(diagnostics: Vec) -> Self { Self( diagnostics .is_empty() .not() .then(|| triomphe::ThinArc::from_header_and_iter((), diagnostics.into_iter())), ) } pub fn iter(&self) -> impl Iterator { self.0.as_ref().into_iter().flat_map(|it| &it.slice) } } #[derive(Debug, PartialEq, Eq)] pub struct DefDiagnostic { pub in_module: ModuleId, pub kind: DefDiagnosticKind, } impl DefDiagnostic { pub(super) fn unresolved_module( container: ModuleId, declaration: AstId, candidates: Box<[String]>, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates }, } } pub(super) fn unresolved_extern_crate( container: ModuleId, declaration: AstId, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedExternCrate { ast: declaration }, } } pub(super) fn unresolved_import( container: ModuleId, id: AstId, index: Idx, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } } } pub fn macro_error( container: ModuleId, ast: AstId, path: ModPath, err: ExpandErrorKind, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::MacroError { ast, path, err } } } pub fn unconfigured_code( container: ModuleId, ast_id: ErasedAstId, cfg: CfgExpr, opts: CfgOptions, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnconfiguredCode { ast_id, cfg, opts }, } } // FIXME: Whats the difference between this and unresolved_proc_macro pub(crate) fn unresolved_macro_call( container: ModuleId, ast: MacroCallKind, path: ModPath, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedMacroCall { ast, path } } } pub(super) fn unimplemented_builtin_macro(container: ModuleId, ast: AstId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnimplementedBuiltinMacro { ast } } } pub(super) fn invalid_derive_target( container: ModuleId, ast: AstId, id: AttrId, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id } } } pub(super) fn malformed_derive(container: ModuleId, ast: AstId, id: AttrId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::MalformedDerive { ast, id } } } }