add special_module_name
lint
This commit is contained in:
parent
4b043faba3
commit
4dded23925
@ -3248,3 +3248,77 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ macro_rules! early_lint_passes {
|
||||
UnusedBraces: UnusedBraces,
|
||||
UnusedImportBraces: UnusedImportBraces,
|
||||
UnsafeCode: UnsafeCode,
|
||||
SpecialModuleName: SpecialModuleName,
|
||||
AnonymousParameters: AnonymousParameters,
|
||||
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
|
||||
NonCamelCaseTypes: NonCamelCaseTypes,
|
||||
|
0
src/test/ui/modules/dummy.rs
Normal file
0
src/test/ui/modules/dummy.rs
Normal file
8
src/test/ui/modules/special_module_name.rs
Normal file
8
src/test/ui/modules/special_module_name.rs
Normal file
@ -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
src/test/ui/modules/special_module_name.stderr
Normal file
37
src/test/ui/modules/special_module_name.stderr
Normal file
@ -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
src/test/ui/modules/special_module_name_ignore.rs
Normal file
9
src/test/ui/modules/special_module_name_ignore.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// run-pass
|
||||
|
||||
#[path = "dummy.rs"]
|
||||
mod lib;
|
||||
|
||||
#[path = "dummy.rs"]
|
||||
mod main;
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user