Skip to content

Commit 96ae006

Browse files
authored
Rollup merge of rust-lang#94467 - ibraheemdev:master, r=pnkfelix
Add `special_module_name` lint Declaring `lib` as a module is one of the most common beginner mistakes when trying to setup a binary and library target in the same crate. `special_module_name` lints against it, as well as `mod main;` ``` 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 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 ``` Note that the help message is not the best in that it doesn't provide an example of an import path (`the_actual_crate_name::`), and doesn't check whether the current file is part of a library/binary target to provide more specific error messages. I'm not sure where this lint would have to be run to access that information.
2 parents fb88811 + 4fdf43f commit 96ae006

File tree

6 files changed

+135
-0
lines changed

6 files changed

+135
-0
lines changed

compiler/rustc_lint/src/builtin.rs

+78
Original file line numberDiff line numberDiff line change
@@ -3173,3 +3173,81 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
31733173
}
31743174
}
31753175
}
3176+
3177+
declare_lint! {
3178+
/// The `special_module_name` lint detects module
3179+
/// declarations for files that have a special meaning.
3180+
///
3181+
/// ### Example
3182+
///
3183+
/// ```rust,compile_fail
3184+
/// mod lib;
3185+
///
3186+
/// fn main() {
3187+
/// lib::run();
3188+
/// }
3189+
/// ```
3190+
///
3191+
/// {{produces}}
3192+
///
3193+
/// ### Explanation
3194+
///
3195+
/// Cargo recognizes `lib.rs` and `main.rs` as the root of a
3196+
/// library or binary crate, so declaring them as modules
3197+
/// will lead to miscompilation of the crate unless configured
3198+
/// explicitly.
3199+
///
3200+
/// To access a library from a binary target within the same crate,
3201+
/// use `your_crate_name::` as the path path instead of `lib::`:
3202+
///
3203+
/// ```rust,compile_fail
3204+
/// // bar/src/lib.rs
3205+
/// fn run() {
3206+
/// // ...
3207+
/// }
3208+
///
3209+
/// // bar/src/main.rs
3210+
/// fn main() {
3211+
/// bar::run();
3212+
/// }
3213+
/// ```
3214+
///
3215+
/// Binary targets cannot be used as libraries and so declaring
3216+
/// one as a module is not allowed.
3217+
pub SPECIAL_MODULE_NAME,
3218+
Warn,
3219+
"module declarations for files with a special meaning",
3220+
}
3221+
3222+
declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
3223+
3224+
impl EarlyLintPass for SpecialModuleName {
3225+
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
3226+
for item in &krate.items {
3227+
if let ast::ItemKind::Mod(
3228+
_,
3229+
ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _),
3230+
) = item.kind
3231+
{
3232+
if item.attrs.iter().any(|a| a.has_name(sym::path)) {
3233+
continue;
3234+
}
3235+
3236+
match item.ident.name.as_str() {
3237+
"lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
3238+
lint.build("found module declaration for lib.rs")
3239+
.note("lib.rs is the root of this crate's library target")
3240+
.help("to refer to it from other targets, use the library's name as the path")
3241+
.emit()
3242+
}),
3243+
"main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
3244+
lint.build("found module declaration for main.rs")
3245+
.note("a binary crate cannot be used as library")
3246+
.emit()
3247+
}),
3248+
_ => continue
3249+
}
3250+
}
3251+
}
3252+
}
3253+
}

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ macro_rules! early_lint_passes {
131131
UnusedBraces: UnusedBraces,
132132
UnusedImportBraces: UnusedImportBraces,
133133
UnsafeCode: UnsafeCode,
134+
SpecialModuleName: SpecialModuleName,
134135
AnonymousParameters: AnonymousParameters,
135136
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
136137
NonCamelCaseTypes: NonCamelCaseTypes,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#[allow(dead_code)]
2+
pub struct Dummy;
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() {}
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`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-pass
2+
3+
#[path = "auxiliary/dummy_lib.rs"]
4+
mod lib;
5+
6+
#[path = "auxiliary/dummy_lib.rs"]
7+
mod main;
8+
9+
fn main() {}

0 commit comments

Comments
 (0)