Skip to content

Commit

Permalink
add special_module_name lint
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed Mar 1, 2022
1 parent 4b043fa commit 4dded23
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 0 deletions.
74 changes: 74 additions & 0 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ macro_rules! early_lint_passes {
UnusedBraces: UnusedBraces,
UnusedImportBraces: UnusedImportBraces,
UnsafeCode: UnsafeCode,
SpecialModuleName: SpecialModuleName,
AnonymousParameters: AnonymousParameters,
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
NonCamelCaseTypes: NonCamelCaseTypes,
Expand Down
Empty file added src/test/ui/modules/dummy.rs
Empty file.
8 changes: 8 additions & 0 deletions src/test/ui/modules/special_module_name.rs
Original file line number Diff line number Diff line change
@@ -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() {}
37 changes: 37 additions & 0 deletions src/test/ui/modules/special_module_name.stderr
Original file line number Diff line number Diff line change
@@ -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`.
9 changes: 9 additions & 0 deletions src/test/ui/modules/special_module_name_ignore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-pass

#[path = "dummy.rs"]
mod lib;

#[path = "dummy.rs"]
mod main;

fn main() {}

0 comments on commit 4dded23

Please sign in to comment.