hir_def/nameres/
diagnostics.rs

1//! Diagnostics emitted during DefMap construction.
2
3use std::ops::Not;
4
5use cfg::{CfgExpr, CfgOptions};
6use hir_expand::{ErasedAstId, ExpandErrorKind, MacroCallKind, attrs::AttrId, mod_path::ModPath};
7use la_arena::Idx;
8use syntax::ast;
9
10use crate::{AstId, nameres::LocalModuleId};
11
12#[derive(Debug, PartialEq, Eq)]
13pub enum DefDiagnosticKind {
14    UnresolvedModule { ast: AstId<ast::Module>, candidates: Box<[String]> },
15    UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
16    UnresolvedImport { id: AstId<ast::Use>, index: Idx<ast::UseTree> },
17    UnconfiguredCode { ast_id: ErasedAstId, cfg: CfgExpr, opts: CfgOptions },
18    UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
19    UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
20    InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
21    MalformedDerive { ast: AstId<ast::Adt>, id: usize },
22    MacroDefError { ast: AstId<ast::Macro>, message: String },
23    MacroError { ast: AstId<ast::Item>, path: ModPath, err: ExpandErrorKind },
24}
25
26#[derive(Clone, Debug, PartialEq, Eq)]
27pub struct DefDiagnostics(Option<triomphe::ThinArc<(), DefDiagnostic>>);
28
29impl DefDiagnostics {
30    pub fn new(diagnostics: Vec<DefDiagnostic>) -> Self {
31        Self(
32            diagnostics
33                .is_empty()
34                .not()
35                .then(|| triomphe::ThinArc::from_header_and_iter((), diagnostics.into_iter())),
36        )
37    }
38
39    pub fn iter(&self) -> impl Iterator<Item = &DefDiagnostic> {
40        self.0.as_ref().into_iter().flat_map(|it| &it.slice)
41    }
42}
43
44#[derive(Debug, PartialEq, Eq)]
45pub struct DefDiagnostic {
46    pub in_module: LocalModuleId,
47    pub kind: DefDiagnosticKind,
48}
49
50impl DefDiagnostic {
51    pub(super) fn unresolved_module(
52        container: LocalModuleId,
53        declaration: AstId<ast::Module>,
54        candidates: Box<[String]>,
55    ) -> Self {
56        Self {
57            in_module: container,
58            kind: DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates },
59        }
60    }
61
62    pub(super) fn unresolved_extern_crate(
63        container: LocalModuleId,
64        declaration: AstId<ast::ExternCrate>,
65    ) -> Self {
66        Self {
67            in_module: container,
68            kind: DefDiagnosticKind::UnresolvedExternCrate { ast: declaration },
69        }
70    }
71
72    pub(super) fn unresolved_import(
73        container: LocalModuleId,
74        id: AstId<ast::Use>,
75        index: Idx<ast::UseTree>,
76    ) -> Self {
77        Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } }
78    }
79
80    pub fn macro_error(
81        container: LocalModuleId,
82        ast: AstId<ast::Item>,
83        path: ModPath,
84        err: ExpandErrorKind,
85    ) -> Self {
86        Self { in_module: container, kind: DefDiagnosticKind::MacroError { ast, path, err } }
87    }
88
89    pub fn unconfigured_code(
90        container: LocalModuleId,
91        ast_id: ErasedAstId,
92        cfg: CfgExpr,
93        opts: CfgOptions,
94    ) -> Self {
95        Self {
96            in_module: container,
97            kind: DefDiagnosticKind::UnconfiguredCode { ast_id, cfg, opts },
98        }
99    }
100
101    // FIXME: Whats the difference between this and unresolved_proc_macro
102    pub(crate) fn unresolved_macro_call(
103        container: LocalModuleId,
104        ast: MacroCallKind,
105        path: ModPath,
106    ) -> Self {
107        Self { in_module: container, kind: DefDiagnosticKind::UnresolvedMacroCall { ast, path } }
108    }
109
110    pub(super) fn unimplemented_builtin_macro(
111        container: LocalModuleId,
112        ast: AstId<ast::Macro>,
113    ) -> Self {
114        Self { in_module: container, kind: DefDiagnosticKind::UnimplementedBuiltinMacro { ast } }
115    }
116
117    pub(super) fn invalid_derive_target(
118        container: LocalModuleId,
119        ast: AstId<ast::Item>,
120        id: AttrId,
121    ) -> Self {
122        Self {
123            in_module: container,
124            kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id: id.ast_index() },
125        }
126    }
127
128    pub(super) fn malformed_derive(
129        container: LocalModuleId,
130        ast: AstId<ast::Adt>,
131        id: AttrId,
132    ) -> Self {
133        Self {
134            in_module: container,
135            kind: DefDiagnosticKind::MalformedDerive { ast, id: id.ast_index() },
136        }
137    }
138}