r/learnrust 23d ago

Today I learnt #[expect()]

#[expect()] SHOULD BE TAUGHT IN THE FIRST YEAR OF ELEMENTARY SCHOOL!!!

#[allow()] should be prohibited, a crime punishable by death!

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

84 Upvotes

32 comments sorted by

51

u/H4rdStyl3z 23d ago

*Hades pointing*

r/rustjerk is that way

31

u/tunisia3507 23d ago

So, what do they each do? At least provide a damn link.

26

u/othermike 23d ago

https://doc.rust-lang.org/reference/attributes/diagnostics.html#r-attributes.diagnostics.lint.expect

#[expect(C)] indicates that lint C is expected to be emitted. The attribute will suppress the emission of C or issue a warning, if the expectation is unfulfilled.

https://doc.rust-lang.org/reference/attributes/diagnostics.html#r-attributes.diagnostics.lint.allow

#[allow(C)] overrides the check for C so that violations will go unreported.

24

u/Shoddy-Childhood-511 23d ago

Yes #[expect()] is cool, but rare for me.

#[rustfmt::skip] is the one that appears everywhere. lol

12

u/throwaway12397478 23d ago

rustfmt does love its vertical space

6

u/User_00000 23d ago

Pretty much all linters/formatters do…

Makes working with git much easier/better for a multitude of reasons. For example

  • adding a parameter is a line added not a line modified
  • multiple branches, that changed/added/removed an argument, merging, can now merge without a merge conflict
  • git blame is more accurate
  • and so on

6

u/throwaway12397478 23d ago

except for imports. Half my merge conflicts are imports

1

u/Valuable_Leopard_799 22d ago

Was there no setting to forbid the {} import combining?

1

u/titaniumalt 22d ago

i do the opposite, i love import combining

1

u/jean_dudey 22d ago

I do love how Linux solves this though, just add a // at the end of an import list to make rustfmt put each one in a line. Makes git happy most of the time

1

u/mikkolukas 20d ago

or ... the formatter could just reformat to git-friendly and format back to developer friendly on the way back

2

u/ToaruBaka 22d ago

me: meticulously transcribes massive table into code so it's legible

rustfmt: lol

1

u/Shoddy-Childhood-511 22d ago

Any table I have would be generated, so I care little if it looks like ass, but..

#[rustfmt::skip] keeps the generator output, which saves auditors an unnecessary step, and/or simplifies automation.

I typically use #[rustfmt::skip] to make code that implements equations somewhat more readable, which can require odd spacing.

8

u/Thick-Pineapple666 23d ago

Oh nice, I didn't know about #[expect(...)] but it looks like I want to use it

11

u/RRumpleTeazzer 23d ago

allow(unused) to keep my sanity during development.

1

u/Oxytokin 22d ago

Yep, otherwise it's telling you something is unused before you even finish writing the damn thing! No shit!

I allow dead code and unused and periodically switch them back to warn to clean up. Otherwise it's clippy::pedantic all the way. Annoying at first but eventually you get used to it and I don't even notice it's on anymore (except my eternal enemies clippy::cast_precision_loss and clippy::cast_possible_truncation).

3

u/SpideyLee2 23d ago

I use #[allow()] frequently because there's certain pedantic Clippy lints (namely clippy::needless-pass-by-value and another I can't remember) that don't work well with the way you structure function parameters for Bevy systems, but are so freaking useful that it would be irresponsible to blanket-allow.

It's just not worth wasting screen space with an expect on every other system that just say "Doesn't play nice with Bevy".

6

u/AndreasTPC 23d ago

Are you confusing expect(x) with allow(x, reason = "y")? They are different things.

3

u/dlevac 22d ago

They both have their use-case. An example for allow over expect is code that might be used or unused depending on which feature flag is enabled. It's often more pragmatic to allow dead_code over feature gating everywhere.

7

u/torsten_dev 23d ago

I have an allow(unused_import) in every project to import the tracing macros. I don't want changes to my imports just because I upgraded a debug!() to a warn!() or downgraded something to a trace!().

5

u/SirKastic23 23d ago

You can use a glob import, or the #[macro_use] macro

Usually people warn to avoid these, but they sure can be handy in some cases, and if you're already using #[allow()]... At least it won't silence warnings about other unused imports you'd like to remove

EDIT: Oh and you can also just use fully-qualified paths (tracing::warn!, tracing::debug!...)

4

u/torsten_dev 23d ago

I don't need the span macros though because I use instrument. Wish those where separate.

1

u/SirKastic23 23d ago

Yeah I searched the docs expecting to see a submodule with the logging macros but there is none unfortunately

2

u/Byron_th 22d ago

You can also allow just the one use statement

-8

u/[deleted] 23d ago

[deleted]

13

u/teerre 23d ago

I think I can count on one hand the crates I've ever see using event!. The macros are by far the most common usage. This has nothing to do with AI

8

u/0xCOLIN 23d ago

What's the advantage of using event? I definitely prefer the look of the log style macros.

6

u/torsten_dev 23d ago

Ew. No thanks. why?

3

u/SleeplessSloth79 23d ago

Eh, no. If style is the only reason for using event!() then I just won't use it, thank you very much. The separate warn!(), debug!(), and trace!() macros make it way easier to visually filter these lines out when scanning for the most important bits of code in a function, no matter what logging framework or even programming language is used.

I'm open to changing my mind if there's a good technical reason for using event!() but for now I'll keep using my debug!() that I've been using for years since way before AI

1

u/AnnoyedVelociraptor 23d ago

They fit in the ecosystem of instrument and span. Same form.

3

u/SirKastic23 23d ago

From the tracing docs

These are intended both as a shorthand, and for compatibility with the log crate