warning: all if blocks contain the same code at the start
--> src/utils.rs:43:13
|
43 | / if self.kind == CheckType::Package {
44 | | w0005!(dir_entry_str, fsize / 1024 / 1024);
| |___________________________________________________________^
|
= note: `#[warn(clippy::branches_sharing_code)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#branches_sharing_code
help: consider moving the start statements out like this
|
43 | w0005!(dir_entry_str, fsize / 1024 / 1024);
44 | if self.kind == CheckType::Package {
|
I don't agree that all if blocks contain the same at the start. w0005! and w0006! are different.
A small experiment(click “Clippy” under “Tools”) seems to suggest that clippy considers the code after macro expansion in order to determine whether the “then” and “else” branch start the same (or are the same).
Maybe your macros w0005 and w0006 do the same thing? If this is intentional, e.g. dependent on conditional compilation or what not, feel free to silence the clippy warning; if it isn’t intentional, maybe it’s a bug? Edit: Wait, the message says the branches “start the same”, so apparently both macro expansions start the same way, which is probably intentional. I’m not sure if this is something that clippy should change, probably yes, because the warning is not really actionable like that; I’m not sure how clippy works internally, i.e. if that’s simple to fix of whether macro expansion happening first is a fundamental part of how clippy operates. In any case, just put an #[allow(clippy::branches_sharing_code)] on the containing block or function; locally disabling clippy lints for the occasional false positive isn’t considered bad style.
Good idea with the macro expansion but although they start the same insofar as in both a println! happens the text to output starts with W0005 resp. W0006.
I am also not sure if this is something clippy should do better.
However, I agree that for the time being it might be best to tell clippy to accept it as you suggested.
That seems odd; sounds like it really shouldn’t produce a warning in that case? I cannot analyze this any further without seeing the definition of those macros, though, or an equivalent example reproducing that warning.
Edit: I just realized that println is a macro, too. I wonder if certain differing println calls might also be able to expand to code that starts the same.
Edit2:, no, println! can’t be the problem; it wraps its entire contents in a block and the branches_sharing_code lint doesn’t fire if stuff is wrapped in an additional layer of {}. Perhaps, if you have control over those, changing the definition of w0005, etc from something like
could be a good idea. This would also make the w0005 macro usable as an expression, while currently it’s probably only usable as a statement (i.e. I’d assume you can’t currently write things like let _ = w0005!(…);).
Right, I think it’s probably the best idea to add an additional layer of {} to each macro definition consisting of more statements than a single expression; furthermore I’d leave out the ; after println!("blablabla"), or wrap it into a block as-well.
The first layer of {} in a macro_rules definition just delimits the right-hand-side of the macro definition, it does not produce a block on its own. This is why e.g. a macro definition like
macro_rules! define {
($i:ident) => {
let x = 42_i32;
}
}
can be used to define a variable in the containing scope, e.g.
Generally in Rust, we want to have that “everything is an expression”, except for let-statements, and similarly except for macros that uselet-statements to define something in their surrounding context. If your macro doesn’t define something to be used later, add a block to make it (usable as) an expression Your minimal example fixed (link).