Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command-line -F then -A lint-level flags behave inconsistently versus in-source #[forbid(..)] then #[allow(..)] lint-level attributes #133346

Closed
jieyouxu opened this issue Nov 22, 2024 · 8 comments
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-CLI Area: Command-line interface (CLI) to the compiler A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@jieyouxu
Copy link
Member

jieyouxu commented Nov 22, 2024

For a given program

#![crate_type = "lib"]
fn foo() {}

Currently (rustc 1.82.0), rustc -F unused -A unused will produce

error: function `foo` is never used
 --> .\bar.rs:1:4
  |
1 | fn foo() {}
  |    ^^^
  |
  = note: `-F dead-code` implied by `-F unused`

error: aborting due to 1 previous error

However, switching to source lint level attributes

#![forbid(unused)]
#![allow(unused)]
#![crate_type = "lib"]
fn foo() {}

will instead produce

warning: allow(unused) incompatible with previous forbid
 --> .\foo.rs:2:10
  |
1 | #![forbid(unused)]
  |           ------ `forbid` level set here
2 | #![allow(unused)]
  |          ^^^^^^ overruled by previous forbid
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
  = note: `#[warn(forbidden_lint_groups)]` on by default

warning: 1 warning emitted

According to my understanding, the purpose of -F/forbid for lints is that they can not be allowed any more. Thus I would expect that calling rustc with -Funused -Aunused will fail when there is unused code in the file.
-- #70819 (comment)

This was changed in #67885.


Original issue reported by @RalfJung, this issue is extracted out of #70819 to focus on the difference between rustc cli lint level flags (e.g. -F../-A..) versus source lint level attributes (e.g. #[forbid(..)]/#[allow(..)]).

cc @RalfJung could you double-check if my transcription is accurate of what you find surprising/undesirable?

@jieyouxu jieyouxu added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 22, 2024
@jieyouxu jieyouxu self-assigned this Nov 22, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 22, 2024
@jieyouxu jieyouxu added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-lang Relevant to the language team, which will review and decide on the PR/issue. A-CLI Area: Command-line interface (CLI) to the compiler and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 22, 2024
@jieyouxu jieyouxu changed the title TODO: cli lint level issue Command-line -F then -A lint-level flags behave inconsistently versus in-source #[forbid(..)] then #[allow(..)] lint-level attributes Nov 22, 2024
@jieyouxu jieyouxu removed their assignment Nov 22, 2024
@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. labels Nov 22, 2024
@jieyouxu
Copy link
Member Author

(Tagging as C-discussion status to determine if this is "intended behavior" or "bug" for now.)

@RalfJung
Copy link
Member

To be clear, the way the attributes behave here is IMO the intended way. "forbid" means "cannot be allowed later", so -F unused -A unused should not allow unused code.

@DJMcNab
Copy link
Contributor

DJMcNab commented Nov 27, 2024

This allegedly intended behaviour of the conflicting attributes themselves being an unconditional hard error (rather than only if the lint would trigger) has some unfortunate consequences. The case I'm running into is:

  1. A macro we use has allow(clippy::restriction) on their generated code (to avoid forward compatibility hazards)
  2. We want to forbid clippy::fn_to_numeric_cast_any for our own development (even if the macro did start to use this capability)

In this case, we get a hard error (E0453) - even though the offending lint would not actually be triggered. I think that these exceptions from the macro are probably over-broad, but I can't really fault the macro crate for not wanting to deal with complaints about new clippy lints.

My preferred solution would be for the hard error E0453 to instead be a deny by default lint. We would then allow that for this case, which would be us taking on responsibility for the future breakage introduced by changes the macro to use fn_to_numeric_cast_any or when clippy detects fn_to_numeric_cast_any. To be clear, I'm not advocating that the macro generated code would be allowed to use fn_to_numeric_cast_any in this case; that would still be expected to be forbidden. I just want the control over what my response to the macro doing that is, rather than the current state of being forced to accept it doing so.

I would like this to be consistent between command line and attributes, but I'd rather the behaviour were consistently the way it works on the command line.

@RalfJung
Copy link
Member

@DJMcNab that is a separate issue, please file a new issue for this. This issue here is about the command-line flags.

@RalfJung
Copy link
Member

RalfJung commented Nov 27, 2024

I'd rather the behaviour were consistently the way it works on the command line.

That contradicts your earlier statements. This issue got opened because if you pass -F unused -A unused on the command line, unused code was allowed! If you still want the code to be rejected, and the -A to be just silently ignored, that's a completely different request. IMO silently ignoring flags is a bad idea, but anyway that should be discussed on a new issue.

@RalfJung
Copy link
Member

What I had entirely missed is that #81670 exists now. Seems like #70819 was independently rediscovered by others. So I think we can close this issue in favor of #81670, all that's left to do is turn that lint into a hard error.

@DJMcNab
Copy link
Contributor

DJMcNab commented Nov 27, 2024

That contradicts your earlier statements.

Hmm, I based that sentence on the original comment in this issue:

For a given program

#![crate_type = "lib"]
fn foo() {}

Currently (rustc 1.82.0), rustc -F unused -A unused will produce

error: function `foo` is never used
 --> .\bar.rs:1:4
  |
1 | fn foo() {}
  |    ^^^
  |
  = note: `-F dead-code` implied by `-F unused`

error: aborting due to 1 previous error

That error to me certainly looks like the dead_code lint is being triggered as expected? I was able to trigger the exact same reported behaviour myself, so I'm not sure how what I said is a contradiction.

My reading of this issue is that it was tracking that the -A unused is entirely ignored; that it should instead give the hard error E453. I recognise that that makes this not the forum to push against E453 being a hard error at all. But as far as I can tell, this issue still exists.

@RalfJung
Copy link
Member

RalfJung commented Nov 27, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-CLI Area: Command-line interface (CLI) to the compiler A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants