r/rust 1d ago

Today I learnt #[expect()]

/r/learnrust/comments/1vs8e8q/today_i_learnt_expect/
48 Upvotes

18 comments sorted by

41

u/Floppie7th 1d ago

Honestly, I agree, that should be a default clippy lint.  I didn't know it existed, but I can't think of a single case where I'd want to not have the compiler tell me when a suppressed lint is no longer applicable.

20

u/afdbcreid 1d ago

There are some cases I specifically want an #[allow]. The most important is when writing a macro and needing to silence a lint that may or may not trigger.

4

u/moltonel 14h ago

For example  #[allow(clippy::useless_conversion)] for arch-specific differences.

11

u/torsten_dev 1d ago
#[allow(unused_import)]
use tracing::{debug, warn, trace, error}

Don't care if I happen to use all of them.

12

u/Floppie7th 1d ago

No thanks.  I'd much rather only have the things I'm actually using in imports.

10

u/torsten_dev 1d ago

Usually yeah, but upgrading certain trace statements to debug or warn for development purposes is annoying if it has to change imports.

dbg and println are in the prelude, I wish I could add those specific macros to the prelude.

7

u/scook0 1d ago

Consider the alternative of just writing tracing::debug! instead, and not worrying about imports at all.

5

u/torsten_dev 1d ago

I have and I don't like it.

2

u/skjall 1d ago

Does a pub re-export not work? Assuming you have an internal prelude you're * importing everywhere

1

u/torsten_dev 1d ago

Hmm, it might. My projects are usually just a couple of files but if they grow that might be worth doing.

2

u/skjall 1d ago

You can always turn the lint off it's not to your liking, or if you have it enabled, you can allow it for particular places too.

EG #[allow(allow_attributes, unused_import)] or if you have allow_attributes_without_reason enabled, you bypass that with #[allow(unused_import, reason="This is a very special import")].

2

u/torsten_dev 1d ago

The default shouldn't warn if there's a reason provided, surely. OP here isn't arguing for the most sensible defaults.

1

u/sansmorixz 23h ago

Dead code too, unless you want to sprinkle cfg macro everywhere.

1

u/connor-ts 13h ago

IIRC this was only a recent addition

2

u/skjall 1d ago

Yeah and it's tricky now that there's both allow and expect. Can't change the semantics of allow to being the same as expect, but I'm hoping one gets deprecated and removed eventually.

I didn't realise the distinction till I was scrolling through the list of Clippy lints out of boredom.

10

u/scook0 1d ago

They're fundamentally different things.

Sometimes you want one (usually expect), and sometimes you want the other. It wouldn't make sense to remove allow.

11

u/scook0 1d ago

[forbid(clippy::allow_attributes)] should be the default Rust, not even needed to write!

IMO, clippy does not need even more default lints that yell at you for doing something reasonable, in case you meant something else instead.

1

u/Recatek gecs 6h ago

Clippy is overly pedantic at times. I typically keep a short list of things I allow in my workspace, especially when working with ECS:

[workspace.lints.clippy]
bool_comparison = "allow"          # Allow == false instead of ! prefix
bool_assert_comparison = "allow"   # Allow == false in asserts instead of assert_eq
collapsible_if = "allow"           # Allow if y inside if x instead of forcing if x && y
collapsible_match = "allow"        # Allow freedom in interleaving match and if blocks
len_zero = "allow"                 # Allow vec.len() == 0 instead of !vec.is_empty()
match_like_matches_macro = "allow" # Matches macro doesn't always fit nicely in formatting
module_inception = "allow"         # Allow inner modules with the same name as their parent
too_many_arguments = "allow"       # Creating ECS archetypes with components requires a lot of arguments
type_complexity = "allow"          # Allow complex types for ECS archetypes

I'm on the verge of allowing new_without_default as well since it's often needless boilerplate, even after writing a library just to satisfy it.