about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIbraheem Ahmed <ibraheem@ibraheem.ca>2022-02-28 19:59:21 -0500
committerIbraheem Ahmed <ibraheem@ibraheem.ca>2022-02-28 20:10:17 -0500
commit4dded23925994103e3e793d5edbe0d30222cdaa4 (patch)
treeb20627167e9dda33ebc4582078b6faac73b40184
parent4b043faba34ccc053a4d0110634c323f6c03765e (diff)
downloadrust-4dded23925994103e3e793d5edbe0d30222cdaa4.tar.gz
rust-4dded23925994103e3e793d5edbe0d30222cdaa4.zip
add `special_module_name` lint
-rw-r--r--compiler/rustc_lint/src/builtin.rs74
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--src/test/ui/modules/dummy.rs0
-rw-r--r--src/test/ui/modules/special_module_name.rs8
-rw-r--r--src/test/ui/modules/special_module_name.stderr37
-rw-r--r--src/test/ui/modules/special_module_name_ignore.rs9
6 files changed, 129 insertions, 0 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 30b5f9b34d0..961e1e9507b 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -3248,3 +3248,77 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
         }
     }
 }
+
+declare_lint! {
+    /// The `special_module_name` lint detects module
+    /// declarations for files that have a special meaning.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// mod lib;
+    ///
+    /// fn main() {
+    ///     lib::run();
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Cargo recognizes `lib.rs` and `main.rs` as the root of a
+    /// library or binary crate, so declaring them as modules
+    /// will lead to miscompilation of the crate unless configured
+    /// explicitly.
+    ///
+    /// To access a library from a binary target within the same crate,
+    /// use `your_crate_name::` as the path path instead of `lib::`:
+    ///
+    /// ```rust,compile_fail
+    /// // bar/src/lib.rs
+    /// fn run() {
+    ///     // ...
+    /// }
+    ///
+    /// // bar/src/main.rs
+    /// fn main() {
+    ///     bar::run();
+    /// }
+    /// ```
+    ///
+    /// Binary targets cannot be used as libraries and so declaring
+    /// one as a module is not allowed.
+    pub SPECIAL_MODULE_NAME,
+    Warn,
+    "module declarations for files with a special meaning",
+}
+
+declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
+
+impl EarlyLintPass for SpecialModuleName {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
+        for item in &krate.items {
+            if let ast::ItemKind::Mod(..) = item.kind {
+                if item.attrs.iter().any(|a| a.has_name(sym::path)) {
+                    continue;
+                }
+
+                match item.ident.name.as_str() {
+                    "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+                        lint.build("found module declaration for lib.rs")
+                            .note("lib.rs is the root of this crate's library target")
+                            .help("to refer to it from other targets, use the library's name as the path")
+                            .emit()
+                    }),
+                    "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+                        lint.build("found module declaration for main.rs")
+                            .note("a binary crate cannot be used as library")
+                            .emit()
+                    }),
+                    _ => continue
+                }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 69863b5ff82..107df79c380 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -129,6 +129,7 @@ macro_rules! early_lint_passes {
                 UnusedBraces: UnusedBraces,
                 UnusedImportBraces: UnusedImportBraces,
                 UnsafeCode: UnsafeCode,
+                SpecialModuleName: SpecialModuleName,
                 AnonymousParameters: AnonymousParameters,
                 EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
                 NonCamelCaseTypes: NonCamelCaseTypes,
diff --git a/src/test/ui/modules/dummy.rs b/src/test/ui/modules/dummy.rs
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/modules/dummy.rs
diff --git a/src/test/ui/modules/special_module_name.rs b/src/test/ui/modules/special_module_name.rs
new file mode 100644
index 00000000000..15c59b2da82
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.rs
@@ -0,0 +1,8 @@
+mod lib;
+//~^ WARN found module declaration for lib.rs
+//~| ERROR file not found for module `lib`
+mod main;
+//~^ WARN found module declaration for main.rs
+//~| ERROR file not found for module `main`
+
+fn main() {}
diff --git a/src/test/ui/modules/special_module_name.stderr b/src/test/ui/modules/special_module_name.stderr
new file mode 100644
index 00000000000..8b3da29386d
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.stderr
@@ -0,0 +1,37 @@
+error[E0583]: file not found for module `lib`
+  --> $DIR/special_module_name.rs:1:1
+   |
+LL | mod lib;
+   | ^^^^^^^^
+   |
+   = help: to create the module `lib`, create file "$DIR/lib.rs" or "$DIR/lib/mod.rs"
+
+error[E0583]: file not found for module `main`
+  --> $DIR/special_module_name.rs:4:1
+   |
+LL | mod main;
+   | ^^^^^^^^^
+   |
+   = help: to create the module `main`, create file "$DIR/main.rs" or "$DIR/main/mod.rs"
+
+warning: found module declaration for lib.rs
+  --> $DIR/special_module_name.rs:1:1
+   |
+LL | mod lib;
+   | ^^^^^^^^
+   |
+   = note: `#[warn(special_module_name)]` on by default
+   = note: lib.rs is the root of this crate's library target
+   = help: to refer to it from other targets, use the library's name as the path
+
+warning: found module declaration for main.rs
+  --> $DIR/special_module_name.rs:4:1
+   |
+LL | mod main;
+   | ^^^^^^^^^
+   |
+   = note: a binary crate cannot be used as library
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/modules/special_module_name_ignore.rs b/src/test/ui/modules/special_module_name_ignore.rs
new file mode 100644
index 00000000000..cae06b49ee0
--- /dev/null
+++ b/src/test/ui/modules/special_module_name_ignore.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+#[path = "dummy.rs"]
+mod lib;
+
+#[path = "dummy.rs"]
+mod main;
+
+fn main() {}