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

Allow #[deny] inside #[forbid] as a no-op with a warning #121560

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Nilstrieb
Copy link
Member

Forbid cannot be overriden. When someome tries to do this anyways, it results in a hard error. That makes sense.

Except it doesn't, because macros. Macros may reasonably use #[deny] (or #[warn] for an allow-by-default lint) in their expansion to assert that their expanded code follows the lint. This is doesn't work when the output gets expanded into a forbid() context. This is pretty silly, since both the macros and the code agree on the lint!

By making it a warning instead, we remove the problem with the macro, which is now nothing as warnings are suppressed in macro expanded code, while still telling users that something is up.

fixes #121483

Forbid cannot be overriden. When someome tries to do this anyways,
it results in a hard error. That makes sense.

Except it doesn't, because macros. Macros may reasonably use `#[deny]`
(or `#[warn]` for an allow-by-default lint) in their expansion to assert
that their expanded code follows the lint. This is doesn't work when the
output gets expanded into a `forbid()` context. This is pretty silly,
since both the macros and the code agree on the lint!

By making it a warning instead, we remove the problem with the macro,
which is now nothing as warnings are suppressed in macro expanded code,
while still telling users that something is up.
@rustbot
Copy link
Collaborator

rustbot commented Feb 24, 2024

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 24, 2024
/// expanded output, which might get expanded into a context that is `forbid()` already,
/// this is not a hard error.
/// As lints in macros are suppressed, so this lint will not show up in these cases.
pub UNOVERRIDABLE_LINT_LEVEL,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better lint name ideas welcome

@Nilstrieb Nilstrieb added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). I-lang-nominated The issue / PR has been nominated for discussion during a lang team meeting. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 24, 2024
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-16 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
#12 writing image sha256:be2472e195cc717a8234f6b08047e7da8db63a8f3101aa81dbccfb9d64ea410f done
#12 naming to docker.io/library/rust-ci done
#12 DONE 10.0s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-16]
##[group]Clock drift check
  local time: Sat Feb 24 17:24:13 UTC 2024
  network time: Sat, 24 Feb 2024 17:24:13 GMT
  network time: Sat, 24 Feb 2024 17:24:13 GMT
##[endgroup]
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-16', '--enable-llvm-link-shared', '--set', 'rust.thin-lto-import-instr-limit=10', '--set', 'change-id=99999999', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'build.optimized-compiler-builtins', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-16/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.thin-lto-import-instr-limit := 10
configure: change-id            := 99999999
---
##[endgroup]
Testing GCC stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
   Compiling y v0.1.0 (/checkout/compiler/rustc_codegen_gcc/build_system)
    Finished release [optimized] target(s) in 1.27s
     Running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-codegen/x86_64-unknown-linux-gnu/release/y test --use-system-gcc --use-backend gcc --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc --release --no-default-features --mini-tests --std-tests`
Using system GCC
Using system GCC
[BUILD] example
[AOT] mini_core_hello_world
/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc/mini_core_hello_world
abc
---
##[group]Testing stage2 error-index (x86_64-unknown-linux-gnu)
##[endgroup]


command did not execute successfully: CFG_RELEASE_CHANNEL="nightly" RUSTC_BOOTSTRAP="1" RUSTC_STAGE="2" RUSTC_SYSROOT="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" RUSTDOC_LIBDIR="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" RUSTDOC_REAL="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" RUST_TEST_THREADS="16" "/checkout/obj/build/bootstrap/debug/rustdoc" "-Wrustdoc::invalid_codeblock_attributes" "-Dwarnings" "-Znormalize-docs" "-Z" "unstable-options" "--test" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md" "--test-args" ""
expected success, got: exit status: 101

stdout ----

---
test /checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md - Rust_Compiler_Error_Index::E0797 (line 18007) ... ok

failures:

---- /checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md - Rust_Compiler_Error_Index::E0453::_::Note__this_error_code_is_no_longer_emitted_by_the_compiler_ (line 8734) stdout ----
warning[E0453]: allow(non_snake_case) incompatible with previous forbid
  |
  |
2 | #![forbid(non_snake_case)]
  |           -------------- `forbid` level set here
4 | #[allow(non_snake_case)]
  |         ^^^^^^^^^^^^^^ overruled by previous forbid
  |
  |
  = note: `#[warn(unoverridable_lint_level)]` on by default
warning: 1 warning emitted

For more information about this error, try `rustc --explain E0453`.
Test compiled successfully, but it's marked `compile_fail`.

@workingjubilee
Copy link
Contributor

workingjubilee commented Feb 25, 2024

My understanding is that this allows this pattern:

#![forbid(lint)]

#[deny(lint)]
fn something() {
    // code
}

Can this come with a test for this case?

#![forbid(lint)]

#[deny(lint)]
fn something() {
    #[allow(lint)]
    {
        // linted code
    }
}

Apologies if this test already exists and I just didn't notice it.

@TaKO8Ki
Copy link
Member

TaKO8Ki commented Feb 26, 2024

@rustbot author

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Feb 26, 2024
@scottmcm
Copy link
Member

scottmcm commented Feb 28, 2024

When do people really want forbid? The only thing that comes to mind for me is forbid(unsafe_code), where I could consider it a plus that a macro can't allow(unsafe_code) to use it anyway.

If people hit this, maybe the resolution instead would be to say "well use deny then"?

@joshtriplett
Copy link
Member

joshtriplett commented Feb 28, 2024

It seems completely fine to #[deny] inside a #[forbid], and I don't think we need a warning for that. (The lint should remain in the forbidden state, and should still not subsequently be allow-able.)

The thing that shouldn't be allowed is using #[warn] or #[allow] inside #[forbid]; that's the exact thing that #[forbid] forbids, so if you want to allow that, don't use #[forbid].

@joshtriplett
Copy link
Member

@workingjubilee Agreed that we should have a test for allow-inside-deny-inside-forbid, as well as a test for warn-inside-deny-inside-forbid, both of which should be an error. (The test should check the case where that happens via a macro, as well.)

@traviscross
Copy link
Contributor

traviscross commented Feb 28, 2024

We discussed this at the end of the lang triage call today and did not reach a resolution before running out of time.

We'll leave this nominated so as to discuss in the meeting on a future week.

@joshtriplett joshtriplett added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 6, 2024
@joshtriplett
Copy link
Member

We discussed this again in today's @rust-lang/lang meeting. Concrete proposal to get consensus on:

  • Allow deny within forbid, silently without any warning, but keep the state forbid. Rationale: forbid is just "deny and don't allow that to be changed".

  • Continue to hard-error on warn or allow within forbid. Re-evaluate after fixing deny.

@rfcbot merge

@rfcbot
Copy link

rfcbot commented Mar 6, 2024

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Mar 6, 2024
@joshtriplett
Copy link
Member

joshtriplett commented Mar 6, 2024

@Nilstrieb Could you please remove the warning, and silently allow deny within forbid (but ensure that the state remains forbid so that allow-inside-deny-inside-forbid is still a hard error)?

@traviscross
Copy link
Contributor

@rustbot labels -I-lang-nominated

As mentioned above, this was discussed today and the mood in the meeting was positive on doing what Josh proposed. Since it was discussed and there's now a propose FCP here, let's unnominate.

@rustbot rustbot removed the I-lang-nominated The issue / PR has been nominated for discussion during a lang team meeting. label Mar 6, 2024
@workingjubilee
Copy link
Contributor

Thanks! This will help me significantly for situations where a forbid(lint) holding is critical... yes, usually forbid(unsafe_code)... while permitting macro code to generate its own deny(lint)s so that it retains internal consistency in its expansion, so that if a macro is used in both a forbid(lint) context and outside of that context, it doesn't have to rethink how it expands certain pieces of code.

@bors
Copy link
Contributor

bors commented Mar 14, 2024

☔ The latest upstream changes (presumably #122483) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

thread_local with const { } fails to compile in file with #![forbid(unsafe_op_in_unsafe_fn)]
10 participants