]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs
bump version to 1.74.1+dfsg1-1~bpo12+pve1
[rustc.git] / src / tools / rust-analyzer / crates / ide-diagnostics / src / handlers / unresolved_module.rs
CommitLineData
353b0b11 1use hir::db::ExpandDatabase;
064997fb
FG
2use ide_db::{assists::Assist, base_db::AnchoredPathBuf, source_change::FileSystemEdit};
3use itertools::Itertools;
4use syntax::AstNode;
5
add651ee 6use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext};
064997fb
FG
7
8// Diagnostic: unresolved-module
9//
10// This diagnostic is triggered if rust-analyzer is unable to discover referred module.
11pub(crate) fn unresolved_module(
12 ctx: &DiagnosticsContext<'_>,
13 d: &hir::UnresolvedModule,
14) -> Diagnostic {
add651ee
FG
15 Diagnostic::new_with_syntax_node_ptr(
16 ctx,
17 DiagnosticCode::RustcHardError("E0583"),
064997fb
FG
18 match &*d.candidates {
19 [] => "unresolved module".to_string(),
9c376795 20 [candidate] => format!("unresolved module, can't find module file: {candidate}"),
064997fb
FG
21 [candidates @ .., last] => {
22 format!(
23 "unresolved module, can't find module file: {}, or {}",
24 candidates.iter().format(", "),
25 last
26 )
27 }
28 },
add651ee 29 d.decl.clone().map(|it| it.into()),
064997fb
FG
30 )
31 .with_fixes(fixes(ctx, d))
32}
33
34fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedModule) -> Option<Vec<Assist>> {
fe692bf9 35 let root = ctx.sema.db.parse_or_expand(d.decl.file_id);
064997fb
FG
36 let unresolved_module = d.decl.value.to_node(&root);
37 Some(
38 d.candidates
39 .iter()
40 .map(|candidate| {
41 fix(
42 "create_module",
43 &format!("Create module at `{candidate}`"),
44 FileSystemEdit::CreateFile {
45 dst: AnchoredPathBuf {
46 anchor: d.decl.file_id.original_file(ctx.sema.db),
47 path: candidate.clone(),
48 },
49 initial_contents: "".to_string(),
50 }
51 .into(),
52 unresolved_module.syntax().text_range(),
53 )
54 })
55 .collect(),
56 )
57}
58
59#[cfg(test)]
60mod tests {
61 use expect_test::expect;
62
63 use crate::tests::{check_diagnostics, check_expect};
64
65 #[test]
66 fn unresolved_module() {
67 check_diagnostics(
68 r#"
69//- /lib.rs
70mod foo;
71 mod bar;
72//^^^^^^^^ 💡 error: unresolved module, can't find module file: bar.rs, or bar/mod.rs
73mod baz {}
74//- /foo.rs
75"#,
76 );
77 }
78
79 #[test]
80 fn test_unresolved_module_diagnostic() {
81 check_expect(
82 r#"mod foo;"#,
83 expect![[r#"
84 [
85 Diagnostic {
add651ee
FG
86 code: RustcHardError(
87 "E0583",
064997fb
FG
88 ),
89 message: "unresolved module, can't find module file: foo.rs, or foo/mod.rs",
90 range: 0..8,
91 severity: Error,
92 unused: false,
93 experimental: false,
94 fixes: Some(
95 [
96 Assist {
97 id: AssistId(
98 "create_module",
99 QuickFix,
100 ),
101 label: "Create module at `foo.rs`",
102 group: None,
103 target: 0..8,
104 source_change: Some(
105 SourceChange {
106 source_file_edits: {},
107 file_system_edits: [
108 CreateFile {
109 dst: AnchoredPathBuf {
110 anchor: FileId(
111 0,
112 ),
113 path: "foo.rs",
114 },
115 initial_contents: "",
116 },
117 ],
118 is_snippet: false,
119 },
120 ),
121 trigger_signature_help: false,
122 },
123 Assist {
124 id: AssistId(
125 "create_module",
126 QuickFix,
127 ),
128 label: "Create module at `foo/mod.rs`",
129 group: None,
130 target: 0..8,
131 source_change: Some(
132 SourceChange {
133 source_file_edits: {},
134 file_system_edits: [
135 CreateFile {
136 dst: AnchoredPathBuf {
137 anchor: FileId(
138 0,
139 ),
140 path: "foo/mod.rs",
141 },
142 initial_contents: "",
143 },
144 ],
145 is_snippet: false,
146 },
147 ),
148 trigger_signature_help: false,
149 },
150 ],
151 ),
add651ee
FG
152 main_node: Some(
153 InFile {
154 file_id: FileId(
155 FileId(
156 0,
157 ),
158 ),
159 value: MODULE@0..8
160 MOD_KW@0..3 "mod"
161 WHITESPACE@3..4 " "
162 NAME@4..7
163 IDENT@4..7 "foo"
164 SEMICOLON@7..8 ";"
165 ,
166 },
167 ),
064997fb
FG
168 },
169 ]
170 "#]],
171 );
172 }
173}