Pre-RFC: #[must_use = false]

This is a simple solution to a simple problem: it allow signaling to the compiler that a type marked as must_use can safely be ignored in this instance.

for example:

/// try to open a file before it is required.
///
/// this result can be safely ignored,
/// as the file will be automatically opened again
/// when it is actually needed.
#[must_use = false]
pub fn hint_premptive_open(&mut self) -> io::Result<()> {
   
}
7 Likes

I don't think we should add more attributes written like #[attr = value]. This should be something like #[must_use(false)] or #[no_must_use] or #[may_ignore].

Otherwise, this seems reasonable.

5 Likes

What about something like #[must_use("ignore")]?

1 Like

Or use lint terms: "allow", "warn", "deny", and "forbid".

I don't know if we want fine-grained control in that direction, but it seems like an interesting idea.

4 Likes

Any reason? I think the inclusion of the equal sign makes the meaning more apparent, where as must_use(false) seems more like you need to use the value false.

Also, strictly speaking, this isn't introducing another attribute, it's simply adding another possible to an existing attribute.

1 Like

Consistency, parsing simplification, simplifying things like unsafe attributes, making macro-defined attributes easier, etc.

The grammar is quite simple, and unsafe = attributes are already possible, per the Reference:

Attr : SimplePath AttrInput ? | unsafe ( SimplePath AttrInput ? )

AttrInput : DelimTokenTree | = Expression

IMO, the lack of = support should be seen as a restriction on attribute macros that should be lifted, not a “deprecated” language feature.

5 Likes

i feel like this could be very easily lifted on attribute helper macros, and should be, since those macros are just inert data that is fed into other macros.

You know how we had wildcard matches as base cases, but decided it would be nice if some matches could be proven to be exhaustive and not require wildcard matches? So then you couldn't add a variant to the enum or struct without it becoming obvious at all match sites?

You remember how we then decided it would be nice if library authors could force users to write wildcard matches to maintain backward compatibility, so we added #[non_exhaustive]?

You remember how people then said they'd rather have the breakage from the exhaustive match, so we added a lint for non-exhaustive matches on #[non_exhaustive] types?

...that result has felt a bit like a silly place to wind up in. Not bad per se, but that it might have been avoidable by thinking either slightly more expansively or trying to think one step ahead.

This feels a bit like that. I'm left wondering if the opt-in/opt-out of lints design space is worth thinking about more carefully.

3 Likes

Somewhat off-topic, but I've always wished non_exhaustive was based on privacy levels, and not hard-coded to non_exhaustive(crate).

6 Likes

The only alternative I can see is a future edition making must_use the default for functions that don't return (), and in that case, we'll need a way to opt out anyways.

RFC created