diff options
| author | bendn <bend.n@outlook.com> | 2025-06-20 00:01:06 +0700 |
|---|---|---|
| committer | bendn <bend.n@outlook.com> | 2025-06-25 01:12:15 +0700 |
| commit | 3583423536a3140680613927db10293dc4cd2f02 (patch) | |
| tree | 1075dceb0142739f7ce4d986d382702d67340a5f /compiler/rustc_resolve | |
| parent | 36b21637e93b038453924d3c66821089e71d8baa (diff) | |
| download | rust-3583423536a3140680613927db10293dc4cd2f02.tar.gz rust-3583423536a3140680613927db10293dc4cd2f02.zip | |
suggest declaring modules when file found but module not defined
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9149974a617..101d6b0be26 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2423,6 +2423,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else { let suggestion = if suggestion.is_some() { suggestion + } else if let Some(m) = self.undeclared_module_exists(ident) { + self.undeclared_module_suggest_declare(ident, m) } else if was_invoked_from_cargo() { Some(( vec![], @@ -2444,6 +2446,55 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } + fn undeclared_module_suggest_declare( + &mut self, + ident: Ident, + path: std::path::PathBuf, + ) -> Option<(Vec<(Span, String)>, String, Applicability)> { + Some(( + vec![(self.current_crate_outer_attr_insert_span, format!("mod {ident};\n"))], + format!( + "to make use of source file {}, use `mod {ident}` \ + in this file to declare the module", + path.display() + ), + Applicability::MaybeIncorrect, + )) + } + + fn undeclared_module_exists(&mut self, ident: Ident) -> Option<std::path::PathBuf> { + let map = self.tcx.sess.source_map(); + + let src = map.span_to_filename(ident.span).into_local_path()?; + let i = ident.as_str(); + // FIXME: add case where non parent using undeclared module (hard?) + let dir = src.parent()?; + let src = src.file_stem()?.to_str()?; + for file in [ + // …/x.rs + dir.join(i).with_extension("rs"), + // …/x/mod.rs + dir.join(i).join("mod.rs"), + ] { + if file.exists() { + return Some(file); + } + } + if !matches!(src, "main" | "lib" | "mod") { + for file in [ + // …/x/y.rs + dir.join(src).join(i).with_extension("rs"), + // …/x/y/mod.rs + dir.join(src).join(i).join("mod.rs"), + ] { + if file.exists() { + return Some(file); + } + } + } + None + } + /// Adds suggestions for a path that cannot be resolved. #[instrument(level = "debug", skip(self, parent_scope))] pub(crate) fn make_path_suggestion( |
