Skip to content

Doc: clarify priority of lint level sources #142021

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

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

Conversation

HamidrezaSK
Copy link

@HamidrezaSK HamidrezaSK commented Jun 4, 2025

This updates the rustc book to clearly document how conflicting lint configurations are resolved across different sources, including command-line flags, crate-level attributes, in-line attributes, and --cap-lints.

It also explains the special behavior of forbid and force_warn.

Fixes #124088

This updates the rustc book to clearly document how conflicting lint configurations are resolved across different sources, including command-line flags, crate-level attributes, in-line attributes, and `--cap-lints`.

It also explains the special behavior of `forbid` and `force_warn`.
@rustbot
Copy link
Collaborator

rustbot commented Jun 4, 2025

r? @ehuss

rustbot has assigned @ehuss.
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 the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 4, 2025
@rust-log-analyzer
Copy link
Collaborator

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
---

COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check-1/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 npm install eslint@$(head -n 1 /tmp/eslint.version) && \
 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#15 3.059 Building wheels for collected packages: reuse
#15 3.060   Building wheel for reuse (pyproject.toml): started
#15 3.271   Building wheel for reuse (pyproject.toml): finished with status 'done'
#15 3.272   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132719 sha256=d2a2565e7037ad3883fb9337653f2e25bbb588534fbef3697286cbc26d1bf634
#15 3.272   Stored in directory: /tmp/pip-ephem-wheel-cache-_n6ivlr0/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#15 3.274 Successfully built reuse
#15 3.275 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#15 3.680 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#15 3.681 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#15 4.207 Collecting virtualenv
#15 4.294   Downloading virtualenv-20.31.2-py3-none-any.whl (6.1 MB)
#15 4.452      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.1/6.1 MB 39.4 MB/s eta 0:00:00
#15 4.514 Collecting filelock<4,>=3.12.2
#15 4.535   Downloading filelock-3.18.0-py3-none-any.whl (16 kB)
#15 4.570 Collecting platformdirs<5,>=3.9.1
#15 4.591   Downloading platformdirs-4.3.8-py3-none-any.whl (18 kB)
#15 4.609 Collecting distlib<1,>=0.3.7
#15 4.630   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#15 4.638      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 82.1 MB/s eta 0:00:00
#15 4.717 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#15 4.909 Successfully installed distlib-0.3.9 filelock-3.18.0 platformdirs-4.3.8 virtualenv-20.31.2
#15 4.909 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#15 DONE 5.0s

#16 [10/11] COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/
#16 DONE 0.0s
---
DirectMap4k:      147392 kB
DirectMap2M:     7192576 kB
DirectMap1G:    11534336 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 npm install eslint@$(head -n 1 /tmp/eslint.version) &&  python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ head -n 1 /tmp/eslint.version
+ TIDY_PRINT_DIFF=1 npm install eslint@8.6.0
npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm WARN deprecated @humanwhocodes/config-array@0.9.5: Use @eslint/config-array instead
npm WARN deprecated @humanwhocodes/object-schema@1.2.1: Use @eslint/object-schema instead
npm WARN deprecated eslint@8.6.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 89 packages in 2s

17 packages are looking for funding
  run `npm fund` for details
+ python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-05-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
fmt: checked 6036 files
tidy check
Running eslint on rustdoc JS files
tidy: Skipping binary file check, read-only filesystem
tidy error: /checkout/src/doc/rustc/src/lints/levels.md: missing trailing newline
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'venv'
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'virtualenv'
Requirement already satisfied: pip in ./build/venv/lib/python3.10/site-packages (25.1.1)
linting python files
All checks passed!
checking python file formatting
28 files already formatted
checking C++ file formatting
some tidy checks failed
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:01:28
  local time: Wed Jun  4 10:09:14 UTC 2025
  network time: Wed, 04 Jun 2025 10:09:15 GMT
##[error]Process completed with exit code 1.
Post job cleanup.


## Priority of Lint Level Sources

Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.
Copy link
Member

@jieyouxu jieyouxu Jun 4, 2025

Choose a reason for hiding this comment

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

Some general remarks (I don't have bandwidth to take over review for this ATM):

  • I wonder if we should explicitly delineate between lint level control mechanisms which are compiler-only, versus those part of the language (such as in-source lint level attributes).
  • I'm not so sure the priority order is well-defined. See Support overriding warnings level for a specific lint via command line #113307 (comment).
  • Note that the ordering of compiler flags can matter! Some flags are "commutative" (in terms of observable final behavior) with respect to each other IIRC, while some flags aren't.
  • (Unstable, not suitable for stable rustc book) there's also the --crate-attr flag, which can somewhat blur the line between compiler vs language.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the feedback! I took a closer look and I think you're right. If that's the case, it might be best to just document the ordering for in-source lint level attributes, where the behavior is straightforward: the closer attribute takes precedence.

@jieyouxu jieyouxu added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools labels Jun 4, 2025
Copy link
Contributor

@ehuss ehuss left a comment

Choose a reason for hiding this comment

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

Thanks!

Looks like there is a CI error that needs to be resolved.


## Priority of Lint Level Sources

Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.
Copy link
Contributor

Choose a reason for hiding this comment

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

What is a "global compiler configuration"?


Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.

This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.
Copy link
Contributor

Choose a reason for hiding this comment

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

Wording nit:

Suggested change
This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.
This section explains how conflicts are resolved between **different sources of lint configuration**, rather than between the lint levels themselves.


This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.

### Priority of Sources (Highest to Lowest)
Copy link
Contributor

Choose a reason for hiding this comment

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

Usually use sentence case for section titles.

Suggested change
### Priority of Sources (Highest to Lowest)
### Priority of sources (highest to lowest)

Comment on lines +345 to +346
in-line attributes (#[...]) >
crate-level attributes (#![...]) >
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the way this is presented is possibly confusing. The language doesn't differentiate between inner and outer attributes for lint levels. It just so happens that crate-level can only be specified by an inner attribute. But inner attributes can show up in many places. I would probably just say "attributes" here, since attributes just create an AST-hierarchy with the most-specific taking precedence.

command-line flags (-A, -W, -D)
```

### Special Cases
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
### Special Cases
### Special case priorities


### Special Cases

The special levels `forbid(lint)` and `force_warn(lint)` take precedence over normal configurations **regardless of where they are set**.
Copy link
Contributor

Choose a reason for hiding this comment

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

The use of parentheses looks a little strange here to me, since force_warn(lint) isn't a valid syntax anywhere. How about just something like this?

Suggested change
The special levels `forbid(lint)` and `force_warn(lint)` take precedence over normal configurations **regardless of where they are set**.
The special levels forbid and force-warn take precedence over normal configurations **regardless of where they are set**.

I don't know what "normal configurations" are.

Also, this doesn't seem quite accurate to me. cap-lints takes precedence over forbid.
And in a sense it does matter where forbid is set, since it applies only to the AST-hierarchy below where it is set.

force-warn can only be set in one place (the CLI), though I'm not sure if this is trying to convey something about the order of CLI arguments?

This doesn't say how forbid and force-warn interact with one another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rustc book does not specify priority between lint options like -A and attributes
5 participants