Skip to content

Commit bf62be2

Browse files
committed
Add unstable --print=crate-root-lint-levels
1 parent 69cb0a9 commit bf62be2

File tree

9 files changed

+164
-3
lines changed

9 files changed

+164
-3
lines changed

compiler/rustc_driver_impl/src/lib.rs

+28
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,34 @@ fn print_crate_info(
691691
};
692692
println_info!("{}", passes::get_crate_name(sess, attrs));
693693
}
694+
CrateRootLintLevels => {
695+
let Some(attrs) = attrs.as_ref() else {
696+
// no crate attributes, print out an error and exit
697+
return Compilation::Continue;
698+
};
699+
let crate_name = passes::get_crate_name(sess, attrs);
700+
let lint_store = crate::unerased_lint_store(sess);
701+
let registered_tools = rustc_resolve::registered_tools_ast(sess.dcx(), attrs);
702+
let features = rustc_expand::config::features(sess, attrs, crate_name);
703+
let lint_levels = rustc_lint::LintLevelsBuilder::crate_root(
704+
sess,
705+
&features,
706+
true,
707+
lint_store,
708+
&registered_tools,
709+
attrs,
710+
);
711+
for lint in lint_store.get_lints() {
712+
if let Some(feature_symbol) = lint.feature_gate
713+
&& !features.enabled(feature_symbol)
714+
{
715+
// lint is unstable and feature gate isn't active, don't print
716+
continue;
717+
}
718+
let level = lint_levels.lint_level(lint).0;
719+
println_info!("{}={}", lint.name_lower(), level.as_str());
720+
}
721+
}
694722
Cfg => {
695723
let mut cfgs = sess
696724
.psess

compiler/rustc_session/src/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
5050
("check-cfg", PrintKind::CheckCfg),
5151
("code-models", PrintKind::CodeModels),
5252
("crate-name", PrintKind::CrateName),
53+
("crate-root-lint-levels", PrintKind::CrateRootLintLevels),
5354
("deployment-target", PrintKind::DeploymentTarget),
5455
("file-names", PrintKind::FileNames),
5556
("host-tuple", PrintKind::HostTuple),
@@ -881,6 +882,7 @@ pub enum PrintKind {
881882
CheckCfg,
882883
CodeModels,
883884
CrateName,
885+
CrateRootLintLevels,
884886
DeploymentTarget,
885887
FileNames,
886888
HostTuple,
@@ -2067,6 +2069,7 @@ fn check_print_request_stability(
20672069
match print_kind {
20682070
PrintKind::AllTargetSpecsJson
20692071
| PrintKind::CheckCfg
2072+
| PrintKind::CrateRootLintLevels
20702073
| PrintKind::SupportedCrateTypes
20712074
| PrintKind::TargetSpecJson
20722075
if !unstable_opts.unstable_options =>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# `print=crate-root-lint-levels`
2+
3+
The tracking issue for this feature is: [#139180](https://github.com/rust-lang/rust/issues/139180).
4+
5+
------------------------
6+
7+
This option of the `--print` flag print the list of lints with print out all the lints and their associated levels (`allow`, `warn`, `deny`, `forbid`) based on the regular Rust rules at crate root, that is *(roughly)*:
8+
- command line args (`-W`, `-A`, ...)
9+
- crate root attributes (`#![allow]`, `#![warn]`, ...)
10+
- *the special `warnings` lint group*
11+
- the default lint level
12+
13+
The output format is `LINT_NAME=LINT_LEVEL`, e.g.:
14+
```text
15+
unknown_lint=warn
16+
arithmetic_overflow=deny
17+
```
18+
19+
To be used like this:
20+
21+
```bash
22+
rustc --print=crate-root-lint-levels -Zunstable-options lib.rs
23+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![allow(unexpected_cfgs)]
2+
#![expect(unused_mut)]
3+
4+
#[deny(unknown_lints)]
5+
mod my_mod {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! This checks the output of `--print=crate-root-lint-levels`
2+
3+
extern crate run_make_support;
4+
5+
use std::collections::HashSet;
6+
use std::iter::FromIterator;
7+
8+
use run_make_support::rustc;
9+
10+
struct CrateRootLintLevels {
11+
args: &'static [&'static str],
12+
contains: Contains,
13+
}
14+
15+
struct Contains {
16+
contains: &'static [&'static str],
17+
doesnt_contain: &'static [&'static str],
18+
}
19+
20+
fn main() {
21+
check(CrateRootLintLevels {
22+
args: &[],
23+
contains: Contains {
24+
contains: &[
25+
"unexpected_cfgs=allow",
26+
"unused_mut=expect",
27+
"warnings=warn",
28+
"stable_features=warn",
29+
"unknown_lints=warn",
30+
],
31+
doesnt_contain: &["unexpected_cfgs=warn", "unused_mut=warn"],
32+
},
33+
});
34+
check(CrateRootLintLevels {
35+
args: &["-Wunexpected_cfgs"],
36+
contains: Contains {
37+
contains: &["unexpected_cfgs=allow", "warnings=warn"],
38+
doesnt_contain: &["unexpected_cfgs=warn"],
39+
},
40+
});
41+
check(CrateRootLintLevels {
42+
args: &["-Dwarnings"],
43+
contains: Contains {
44+
contains: &[
45+
"unexpected_cfgs=allow",
46+
"warnings=deny",
47+
"stable_features=deny",
48+
"unknown_lints=deny",
49+
],
50+
doesnt_contain: &["warnings=warn"],
51+
},
52+
});
53+
check(CrateRootLintLevels {
54+
args: &["-Dstable_features"],
55+
contains: Contains {
56+
contains: &["warnings=warn", "stable_features=deny", "unexpected_cfgs=allow"],
57+
doesnt_contain: &["warnings=deny"],
58+
},
59+
});
60+
}
61+
62+
fn check(CrateRootLintLevels { args, contains }: CrateRootLintLevels) {
63+
let output = rustc()
64+
.input("lib.rs")
65+
.arg("-Zunstable-options")
66+
.print("crate-root-lint-levels")
67+
.args(args)
68+
.run();
69+
70+
let stdout = output.stdout_utf8();
71+
72+
let mut found = HashSet::<String>::new();
73+
74+
for l in stdout.lines() {
75+
assert!(l == l.trim());
76+
if let Some((left, right)) = l.split_once('=') {
77+
assert!(!left.contains("\""));
78+
assert!(!right.contains("\""));
79+
} else {
80+
assert!(l.contains('='));
81+
}
82+
assert!(found.insert(l.to_string()), "{}", &l);
83+
}
84+
85+
let Contains { contains, doesnt_contain } = contains;
86+
87+
{
88+
let should_found = HashSet::<String>::from_iter(contains.iter().map(|s| s.to_string()));
89+
let diff: Vec<_> = should_found.difference(&found).collect();
90+
assert!(diff.is_empty(), "should found: {:?}, didn't found {:?}", &should_found, &diff);
91+
}
92+
{
93+
let should_not_find =
94+
HashSet::<String>::from_iter(doesnt_contain.iter().map(|s| s.to_string()));
95+
let diff: Vec<_> = should_not_find.intersection(&found).collect();
96+
assert!(diff.is_empty(), "should not find {:?}, did found {:?}", &should_not_find, &diff);
97+
}
98+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: Argument to option 'print' missing
22
Usage:
3-
--print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
3+
--print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
44
Compiler information to print on stdout
55

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unknown print request: `yyyy`
22
|
3-
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
3+
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
44
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
55

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
error: unknown print request: `lints`
22
|
3-
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
3+
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
44
= help: use `-Whelp` to print a list of lints
55
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
66

tests/ui/print-request/stability.rs

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
//@[all_target_specs_json] compile-flags: --print=all-target-specs-json
1919
//@[all_target_specs_json] error-pattern: the `-Z unstable-options` flag must also be passed
2020

21+
//@ revisions: crate_root_lint_levels
22+
//@[crate_root_lint_levels] compile-flags: --print=crate-root-lint-levels
23+
//@[crate_root_lint_levels] error-pattern: the `-Z unstable-options` flag must also be passed
24+
2125
//@ revisions: check_cfg
2226
//@[check_cfg] compile-flags: --print=check-cfg
2327
//@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed

0 commit comments

Comments
 (0)