Skip to content

Commit 4dded23

Browse files
committed
add special_module_name lint
1 parent 4b043fa commit 4dded23

File tree

6 files changed

+129
-0
lines changed

6 files changed

+129
-0
lines changed

compiler/rustc_lint/src/builtin.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,3 +3248,77 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
32483248
}
32493249
}
32503250
}
3251+
3252+
declare_lint! {
3253+
/// The `special_module_name` lint detects module
3254+
/// declarations for files that have a special meaning.
3255+
///
3256+
/// ### Example
3257+
///
3258+
/// ```rust,compile_fail
3259+
/// mod lib;
3260+
///
3261+
/// fn main() {
3262+
/// lib::run();
3263+
/// }
3264+
/// ```
3265+
///
3266+
/// {{produces}}
3267+
///
3268+
/// ### Explanation
3269+
///
3270+
/// Cargo recognizes `lib.rs` and `main.rs` as the root of a
3271+
/// library or binary crate, so declaring them as modules
3272+
/// will lead to miscompilation of the crate unless configured
3273+
/// explicitly.
3274+
///
3275+
/// To access a library from a binary target within the same crate,
3276+
/// use `your_crate_name::` as the path path instead of `lib::`:
3277+
///
3278+
/// ```rust,compile_fail
3279+
/// // bar/src/lib.rs
3280+
/// fn run() {
3281+
/// // ...
3282+
/// }
3283+
///
3284+
/// // bar/src/main.rs
3285+
/// fn main() {
3286+
/// bar::run();
3287+
/// }
3288+
/// ```
3289+
///
3290+
/// Binary targets cannot be used as libraries and so declaring
3291+
/// one as a module is not allowed.
3292+
pub SPECIAL_MODULE_NAME,
3293+
Warn,
3294+
"module declarations for files with a special meaning",
3295+
}
3296+
3297+
declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
3298+
3299+
impl EarlyLintPass for SpecialModuleName {
3300+
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
3301+
for item in &krate.items {
3302+
if let ast::ItemKind::Mod(..) = item.kind {
3303+
if item.attrs.iter().any(|a| a.has_name(sym::path)) {
3304+
continue;
3305+
}
3306+
3307+
match item.ident.name.as_str() {
3308+
"lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
3309+
lint.build("found module declaration for lib.rs")
3310+
.note("lib.rs is the root of this crate's library target")
3311+
.help("to refer to it from other targets, use the library's name as the path")
3312+
.emit()
3313+
}),
3314+
"main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
3315+
lint.build("found module declaration for main.rs")
3316+
.note("a binary crate cannot be used as library")
3317+
.emit()
3318+
}),
3319+
_ => continue
3320+
}
3321+
}
3322+
}
3323+
}
3324+
}

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ macro_rules! early_lint_passes {
129129
UnusedBraces: UnusedBraces,
130130
UnusedImportBraces: UnusedImportBraces,
131131
UnsafeCode: UnsafeCode,
132+
SpecialModuleName: SpecialModuleName,
132133
AnonymousParameters: AnonymousParameters,
133134
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
134135
NonCamelCaseTypes: NonCamelCaseTypes,

src/test/ui/modules/dummy.rs

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mod lib;
2+
//~^ WARN found module declaration for lib.rs
3+
//~| ERROR file not found for module `lib`
4+
mod main;
5+
//~^ WARN found module declaration for main.rs
6+
//~| ERROR file not found for module `main`
7+
8+
fn main() {}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error[E0583]: file not found for module `lib`
2+
--> $DIR/special_module_name.rs:1:1
3+
|
4+
LL | mod lib;
5+
| ^^^^^^^^
6+
|
7+
= help: to create the module `lib`, create file "$DIR/lib.rs" or "$DIR/lib/mod.rs"
8+
9+
error[E0583]: file not found for module `main`
10+
--> $DIR/special_module_name.rs:4:1
11+
|
12+
LL | mod main;
13+
| ^^^^^^^^^
14+
|
15+
= help: to create the module `main`, create file "$DIR/main.rs" or "$DIR/main/mod.rs"
16+
17+
warning: found module declaration for lib.rs
18+
--> $DIR/special_module_name.rs:1:1
19+
|
20+
LL | mod lib;
21+
| ^^^^^^^^
22+
|
23+
= note: `#[warn(special_module_name)]` on by default
24+
= note: lib.rs is the root of this crate's library target
25+
= help: to refer to it from other targets, use the library's name as the path
26+
27+
warning: found module declaration for main.rs
28+
--> $DIR/special_module_name.rs:4:1
29+
|
30+
LL | mod main;
31+
| ^^^^^^^^^
32+
|
33+
= note: a binary crate cannot be used as library
34+
35+
error: aborting due to 2 previous errors; 2 warnings emitted
36+
37+
For more information about this error, try `rustc --explain E0583`.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-pass
2+
3+
#[path = "dummy.rs"]
4+
mod lib;
5+
6+
#[path = "dummy.rs"]
7+
mod main;
8+
9+
fn main() {}

0 commit comments

Comments
 (0)