Skip to content

Commit da1d738

Browse files
authored
Rollup merge of #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 9af618b + 4fdf43f commit da1d738

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

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ macro_rules! early_lint_passes {
133133
UnusedBraces: UnusedBraces,
134134
UnusedImportBraces: UnusedImportBraces,
135135
UnsafeCode: UnsafeCode,
136+
SpecialModuleName: SpecialModuleName,
136137
AnonymousParameters: AnonymousParameters,
137138
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
138139
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)