Fix ICE when a future-incompat-report has its command-line level capped
Fixes #78660 With PR https://github.com/rust-lang/rust/pull/75534 merged, we now run more lint-related code for future-incompat-report, even when their final level is Allow. Some lint-related code was not expecting `Level::Allow`, and had an explicit panic. This PR explicitly tracks the lint level set on the command line before `--cap-lints` is applied. This is used to emit a more precise error note (e.g. we don't say that `-W lint-name` was specified on the command line just because a lint was capped to Warn). As a result, we can now correctly emit a note that `-A` was used if we got `Level::Allow` from the command line (before the cap is applied).
This commit is contained in:
parent
d8ef0d7757
commit
6c1f15fa81
4 changed files with 34 additions and 10 deletions
|
@ -74,6 +74,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
|
|
||||||
for &(ref lint_name, level) in &sess.opts.lint_opts {
|
for &(ref lint_name, level) in &sess.opts.lint_opts {
|
||||||
store.check_lint_name_cmdline(sess, &lint_name, level);
|
store.check_lint_name_cmdline(sess, &lint_name, level);
|
||||||
|
let orig_level = level;
|
||||||
|
|
||||||
// If the cap is less than this specified level, e.g., if we've got
|
// If the cap is less than this specified level, e.g., if we've got
|
||||||
// `--cap-lints allow` but we've also got `-D foo` then we ignore
|
// `--cap-lints allow` but we've also got `-D foo` then we ignore
|
||||||
|
@ -88,7 +89,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
};
|
};
|
||||||
for id in ids {
|
for id in ids {
|
||||||
self.check_gated_lint(id, DUMMY_SP);
|
self.check_gated_lint(id, DUMMY_SP);
|
||||||
let src = LintSource::CommandLine(lint_flag_val);
|
let src = LintSource::CommandLine(lint_flag_val, orig_level);
|
||||||
specs.insert(id, (level, src));
|
specs.insert(id, (level, src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +124,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
diag_builder.note(&rationale.as_str());
|
diag_builder.note(&rationale.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LintSource::CommandLine(_) => {
|
LintSource::CommandLine(_, _) => {
|
||||||
diag_builder.note("`forbid` lint level was set on command line");
|
diag_builder.note("`forbid` lint level was set on command line");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,7 +423,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
let forbidden_lint_name = match forbid_src {
|
let forbidden_lint_name = match forbid_src {
|
||||||
LintSource::Default => id.to_string(),
|
LintSource::Default => id.to_string(),
|
||||||
LintSource::Node(name, _, _) => name.to_string(),
|
LintSource::Node(name, _, _) => name.to_string(),
|
||||||
LintSource::CommandLine(name) => name.to_string(),
|
LintSource::CommandLine(name, _) => name.to_string(),
|
||||||
};
|
};
|
||||||
let (lint_attr_name, lint_attr_span) = match *src {
|
let (lint_attr_name, lint_attr_span) = match *src {
|
||||||
LintSource::Node(name, span, _) => (name, span),
|
LintSource::Node(name, span, _) => (name, span),
|
||||||
|
@ -446,7 +447,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
diag_builder.note(&rationale.as_str());
|
diag_builder.note(&rationale.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LintSource::CommandLine(_) => {
|
LintSource::CommandLine(_, _) => {
|
||||||
diag_builder.note("`forbid` lint level was set on command line");
|
diag_builder.note("`forbid` lint level was set on command line");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@ pub enum LintSource {
|
||||||
Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */),
|
Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */),
|
||||||
|
|
||||||
/// Lint level was set by a command-line flag.
|
/// Lint level was set by a command-line flag.
|
||||||
CommandLine(Symbol),
|
/// The provided `Level` is the level specified on the command line -
|
||||||
|
/// the actual level may be lower due to `--cap-lints`
|
||||||
|
CommandLine(Symbol, Level),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LintSource {
|
impl LintSource {
|
||||||
|
@ -30,7 +32,7 @@ impl LintSource {
|
||||||
match *self {
|
match *self {
|
||||||
LintSource::Default => symbol::kw::Default,
|
LintSource::Default => symbol::kw::Default,
|
||||||
LintSource::Node(name, _, _) => name,
|
LintSource::Node(name, _, _) => name,
|
||||||
LintSource::CommandLine(name) => name,
|
LintSource::CommandLine(name, _) => name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ impl LintSource {
|
||||||
match *self {
|
match *self {
|
||||||
LintSource::Default => DUMMY_SP,
|
LintSource::Default => DUMMY_SP,
|
||||||
LintSource::Node(_, span, _) => span,
|
LintSource::Node(_, span, _) => span,
|
||||||
LintSource::CommandLine(_) => DUMMY_SP,
|
LintSource::CommandLine(_, _) => DUMMY_SP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,12 +281,12 @@ pub fn struct_lint_level<'s, 'd>(
|
||||||
&format!("`#[{}({})]` on by default", level.as_str(), name),
|
&format!("`#[{}({})]` on by default", level.as_str(), name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
LintSource::CommandLine(lint_flag_val) => {
|
LintSource::CommandLine(lint_flag_val, orig_level) => {
|
||||||
let flag = match level {
|
let flag = match orig_level {
|
||||||
Level::Warn => "-W",
|
Level::Warn => "-W",
|
||||||
Level::Deny => "-D",
|
Level::Deny => "-D",
|
||||||
Level::Forbid => "-F",
|
Level::Forbid => "-F",
|
||||||
Level::Allow => panic!(),
|
Level::Allow => "-A",
|
||||||
};
|
};
|
||||||
let hyphen_case_lint_name = name.replace("_", "-");
|
let hyphen_case_lint_name = name.replace("_", "-");
|
||||||
if lint_flag_val.as_str() == name {
|
if lint_flag_val.as_str() == name {
|
||||||
|
|
10
src/test/ui/lint/issue-78660-cap-lints-future-compat.rs
Normal file
10
src/test/ui/lint/issue-78660-cap-lints-future-compat.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// compile-flags: -D warnings --cap-lints allow
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Regression test for issue #78660
|
||||||
|
// Tests that we don't ICE when a future-incompat-report lint has
|
||||||
|
// has a command-line source, but is capped to allow
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
["hi"].into_iter();
|
||||||
|
}
|
11
src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr
Normal file
11
src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Future incompatibility report: Future breakage date: None, diagnostic:
|
||||||
|
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
|
||||||
|
--> $DIR/issue-78660-cap-lints-future-compat.rs:9:12
|
||||||
|
|
|
||||||
|
LL | ["hi"].into_iter();
|
||||||
|
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
||||||
|
|
|
||||||
|
= note: `-D array-into-iter` implied by `-D warnings`
|
||||||
|
= 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue