If a use statement is only used during the documentation, I get an warning during cargo run . For example, the following shell script
#! /usr/bin/env bash
set -e -u
if [ -e cargo_test ]
then
rm -r cargo_test
fi
cargo new cargo_test --bin
cd cargo_test
#
cat << EOF > src/main.rs
pub mod one;
pub mod two;
fn main() {
one::fun_1();
two::fun_2();
}
EOF
cat << EOF > src/one.rs
use crate::two;
/// See [fun_2](two::fun_2)
pub fn fun_1() {
println!( "fun_1" );
}
EOF
cat << EOF > src/two.rs
use crate::one;
/// See [fun_1](one::fun_1)
pub fn fun_2() {
println!( "fun_2" );
}
EOF
# The documentation builds fine without warning
echo 'cargo doc'
cargo doc
# The program warns that the imports are not used
echo 'cargo run'
cargo run
Generates the output
Creating binary (application) `cargo_test` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
cargo doc
Documenting cargo_test v0.1.0 (/Users/bradbell/trash/rust/cargo_test)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s
Generated /Users/bradbell/trash/rust/cargo_test/target/doc/cargo_test/index.html
cargo run
Compiling cargo_test v0.1.0 (/Users/bradbell/trash/rust/cargo_test)
warning: unused import: `crate::two`
--> src/one.rs:1:5
|
1 | use crate::two;
| ^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `crate::one`
--> src/two.rs:1:5
|
1 | use crate::one;
| ^^^^^^^^^^
warning: `cargo_test` (bin "cargo_test") generated 2 warnings (run `cargo fix --bin "cargo_test"` to apply 2 suggestions)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/cargo_test`
fun_1
fun_2
The warning is from the compiling process, for unused imports. It is for each of the modules:one.rs and two.rs it is not for the main.rs.
Within one.rs the use crate::two is unused so it complains. Same happens for the other case.
Edit: My bad! I am unsure why when one runs cargo doc it compiles it without warnings. I interpreted that it was not compiling it but only doc'ing it, at a glance.
Trying with one or many --verbose, and changing Config.toml didn't add anything.
The documentation builds fine and uses the imports. It seems to me that during the compile it does not analyze the documentation to see if it is using the imports.
cargo run just calls cargo build before executing the binary. Documentation is not part of the compiled code, so unused_imports correctly gets triggered. You can either disable that lint or configure the use declaration such that it only happens for documentation (i.e., #[cfg(doc)]).
It seems that cargo run warns if a use statement is not used but cargo doc does not. It seems to me that cargo doc should check that all the use statements below #[cfg(doc)] are used by the documentation.
If the code below is main.rs and your run cargo doc , you do not get a warning that add_two is not used.
If you remove the line #[cfg(doc)] and then run cargo run , you do get a warning that add_two is not used.
pub mod sub_module {
pub fn add_two(x : usize) -> usize
{ x + 2 }
}
//
#[cfg(doc)]
use sub_module::add_two;
//
fn main() {
println!( "Hello World" );
}
Lints that aren't used by rustdoc don't affect it, and unused_imports is not one of the lints supported by rustdoc. Note that link does not contain an exhaustive list of lints supported by rustdoc (e.g., rustdoc::unused_unit is a valid lint). rust-analyzer as used by Helix shows a bunch of rustdoc lints, however it doesn't show any unused_imports lint. A PR that causes rustdoc to be affected by unused_imports may be accepted by the rustdoc team.
I'll add that not only is rustdoc not affected by certain lints, but even a subset of invalid Rust doesn't affect rustdoc. For example, the following code won't compile; but rustdoc has no problem generating the documentation:
#![deny(single_use_lifetimes, reason = "illustrative example")]
/// Hi.
pub struct Foo;
impl Foo {
/// Documentation for this method will be built even
/// though `cargo check` will fail due to the
/// `single_use_lifetimes` lint.
pub const fn bar<'a>(&'a self) {}
/// Read [`Self::bar`].
///
/// Documentation for this function will be built even
/// though we reference the method `bar` which violates
/// the `single_use_lifetimes` lint.
pub const fn fizz() {}
/// Documentation for this will be built despite this
/// not being valid Rust.
///
/// # Examples
///
/// ```
/// _ = Foo::buzz();
/// Not valid Rust
/// ```
pub const fn buzz() {
notValidRust
}
// Uncommenting the below will cause `rustdoc` to fail
// since not only is this not valid Rust, but invalid
// tokens are used.
// /// Testing.
// pub const fn wuzz() {
// Not valid Rust
// }
}
// If you uncomment below, `rustdoc` will fail since
// `non_camel_case_types` is used by `rustdoc`.
// /// Hi.
// #[deny(non_camel_case_types, reason = "illustrative example")]
// pub struct bar;