rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.86k stars 12.67k forks source link

Effective breakage to `jiff` due to `ambiguous_negative_literals` #128287

Open traviscross opened 2 months ago

traviscross commented 2 months ago

We should discuss this bit of evidence that came in after the FCP completed on:

@BurntSushi said:

This completely broke Jiff once the change landed. Because it specifically supports negating spans like -1.hour(). In the case of Jiff, there is no ambiguity because -1.hour() and (-1).hour() and -(1.hour()) are all precisely equivalent.

cc @BurntSushi @rust-lang/lang

@rustbot labels +T-lang +I-lang-nominated

workingjubilee commented 2 months ago

This lint indeed assumes the operations are ordering-sensitive. Like abs. Perhaps the lint should be on the function, not the operator?

Urgau commented 2 months ago

The partially-uplifted Clippy clippy::precedence lint (which made up this lint) had a basic heuristic for not linting in cases where the precedence of the operations didn't matter. It was part of the original PR, but @RalfJung preferred consistent linting [comment]:

Personally I'd prefer it to warn consistently, even if the semantics of the function mean it doesn't matter. (a) that seems more consistent and less surprising, and (b) I am writing tests which ensure that sin behaves correctly, and I care about which sign the argument actually has.

Urgau commented 2 months ago

If it's decided that it's not worth linting on these cases, I would propose using the #[diagnostic] namespace by introducing an opt-out, that library authors could use on to suppress the lint for downstream users.

Something like #[diagnostic::irrelevant_negative_literal_precedence] (better name to be found) which could applied to all the relevant function definitions.

As for my rational of being opt-out instead of opt-in, I think it will avoid discrepancy in the coverage as (the wast majority) of users won't know to annotate the functions that are sensitive to negative literals, which is the point of the lint, bring awareness to this surprising aspect of Rust.

traviscross commented 2 months ago

We discussed this in our lang triage call today.

@Urgau: If you would, we'd like this lint changed to allow-by-default while we consider this question further.

cc @compiler-errors

Urgau commented 2 months ago

As asked the lint was changed to allow-by-default in https://github.com/rust-lang/rust/pull/128449.

traviscross commented 2 weeks ago

@BurntSushi: What do you think of the proposal that @Urgau makes here, as it applies to jiff?

I'd also be interested to hear your thoughts on the question of whether something like this should be opt-in or opt-out.

BurntSushi commented 2 weeks ago

@traviscross I love @Urgau's idea. Will it be possible to use that annotation on older Rust compilers where it will just be ignored? Otherwise it would be hard for me to use it until my MSRV matches the Rust release where the annotation becomes available. (Or do a build script with conditional compilation.)

In terms of opt-in or opt-out, I agree that opt-out makes the most sense. Otherwise I think this lint would probably not be nearly as effective.

compiler-errors commented 2 weeks ago

Using an attribute from the diagnostic namespace -- even an unknown one -- will bump your MSRV to 1.78, when the diagnostic namespace was stabilized. Before that you'll get resolver errors that afaict you cannot suppress.

BurntSushi commented 2 weeks ago

@compiler-errors I think that should be fine. Probably by the time everything lands on stable, I'll soon thereafter be able to bump my MSRV to 1.78. Worst case, I'll bite the bullet and do version sniffing in build.rs.

compiler-errors commented 2 weeks ago

Yep, and 1.78 should be the MSRV for all future tricks of this same sort.