4

I have a code that looks approximately like this:

// src/bitboard.rs
#[derive(Copy, Clone, Debug)]
pub struct Bitboard {
    value: u64
}

impl Bitboard {
    pub const fn new(value: u64) -> Self {
        Self { value }
    }

    pub const fn get_bit(&self, k: u64) -> u64 {
        ((1u64 << k) & self.value) >> k
    }
}

// src/main.rs
pub mod bitboard;

use crate::bitboard::Bitboard;

fn main() {
    let bitboard = Bitboard::new(0);
    dbg!(bitboard);
}

If I compile it exactly like this, it works without any errors or warnings.

However, if I change my pub mod bitboard to mod bitboard, then clippy starts giving me this warning:

warning: this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)

pub const fn get_bit(&self, k: u64) -> u64 {
                     ^^^^^ help: consider passing by value instead: `self`

= note: `-W clippy::trivially-copy-pass-by-ref` implied by `-W clippy::pedantic`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref

I understand what clippy is telling me to do. But I do not understand why it does not suggest this when my module is declared as public. Any ideas?

P.S.: I am using rustc 1.60.0, clippy 0.1.60.

Edit: I should also add that this is not the only extra lint that happens when I remove the pub from my modules. For instance, I also had 1 new clippy::upper_case_acronyms, and 1 new clippy::enum_variant_names.

Edit 2: As requested, I'm including more examples to show the same behaviour happening to clippy::upper-case_acronyms and clippy::enum_variant_names:

// src/fen.rs

pub struct FEN;  // upper case acronyms happens here

pub enum FENValidationError {  // enum variant names happens here
    InvalidFieldsCount,
    InvalidPiecePlacement,
    InvalidRankSize,
}

// src/main.rs
mod fen;  // same thing here. If this becomes `pub mod fen`, the two lint warnings above disappear.
Solens
  • 93
  • 2
  • 6
  • How do you invoke clippy? Any configuration file? – Chayim Friedman May 29 '22 at 01:41
  • I use the command `cargo clippy` to invoke it. I do have a configuration file, but I was able to reproduce a minimal example without it (it is required to use the pedantic flag, i.e. `cargo clippy -- -Wclippy::pedantic`) – Solens May 29 '22 at 01:45
  • I am able to reproduce, but unable for the other lints (`upper_case_acronyms` and `enum_variant_names`). Are they issued on the same code? – Chayim Friedman May 29 '22 at 01:50
  • Sorry, I should have clarified that these two other lints happen on other modules, not on this example I've posted. I just mentioned these other two to make it clear that my problem was not specifically `clippy::trivially_copy_pass_by_ref`. I can include these other examples too if you'd like. – Solens May 29 '22 at 01:54
  • 1
    It may help; I'm not sure what is the reason for that yet, but it may be either something common to all lints of something specific that happens to some lints and then an answer should explain case-by-case. Did it happen to you with another lints? – Chayim Friedman May 29 '22 at 01:56
  • I edited my post to include the examples with upper_case_acronyms and enum_variant_names. This problem has not happened to me with other lints, only these 3. – Solens May 29 '22 at 02:06

1 Answers1

4

Because changing a public API like that is a breaking change.

Changing the argument to pass by value like clippy recommends is easy if its an internal method, since you have control over all of the code that uses it. But if the argument is on a function or method exposed as part of the public API, changing it would require that all the other projects that use it change too, which is usually unacceptable for something as minor as passing a small Copy value by reference.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • That makes a lot of sense, thanks! However, are public module declarations in `main.rs` still considered a public API even if my crate does not contain a library? After searching for a few minutes, I haven't found a way that external crates can link with mine if mine does not contain `lib.rs` – Solens May 29 '22 at 02:35
  • 1
    I think it is probably the case that Clippy is run against each file separately, so it does not necessarily have visibility over wether pub items could be externally public. – harmic May 29 '22 at 03:05
  • 2
    @Solens Rust considered public module declarations in a binary to be public API, for whatever reason. You can see this with the unused warnings in the base compiler as well. – Colonel Thirty Two May 29 '22 at 13:26