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
@ -74,6 +74,7 @@ fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
|
||||
|
||||
for &(ref lint_name, level) in &sess.opts.lint_opts {
|
||||
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
|
||||
// `--cap-lints allow` but we've also got `-D foo` then we ignore
|
||||
@ -88,7 +89,7 @@ fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
|
||||
};
|
||||
for id in ids {
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -123,7 +124,7 @@ fn insert_spec(
|
||||
diag_builder.note(&rationale.as_str());
|
||||
}
|
||||
}
|
||||
LintSource::CommandLine(_) => {
|
||||
LintSource::CommandLine(_, _) => {
|
||||
diag_builder.note("`forbid` lint level was set on command line");
|
||||
}
|
||||
}
|
||||
@ -422,7 +423,7 @@ pub(crate) fn push(
|
||||
let forbidden_lint_name = match forbid_src {
|
||||
LintSource::Default => id.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 {
|
||||
LintSource::Node(name, span, _) => (name, span),
|
||||
@ -446,7 +447,7 @@ pub(crate) fn push(
|
||||
diag_builder.note(&rationale.as_str());
|
||||
}
|
||||
}
|
||||
LintSource::CommandLine(_) => {
|
||||
LintSource::CommandLine(_, _) => {
|
||||
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 */),
|
||||
|
||||
/// 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 {
|
||||
@ -30,7 +32,7 @@ pub fn name(&self) -> Symbol {
|
||||
match *self {
|
||||
LintSource::Default => symbol::kw::Default,
|
||||
LintSource::Node(name, _, _) => name,
|
||||
LintSource::CommandLine(name) => name,
|
||||
LintSource::CommandLine(name, _) => name,
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +40,7 @@ pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
LintSource::Default => DUMMY_SP,
|
||||
LintSource::Node(_, span, _) => span,
|
||||
LintSource::CommandLine(_) => DUMMY_SP,
|
||||
LintSource::CommandLine(_, _) => DUMMY_SP,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,12 +281,12 @@ fn struct_lint_level_impl(
|
||||
&format!("`#[{}({})]` on by default", level.as_str(), name),
|
||||
);
|
||||
}
|
||||
LintSource::CommandLine(lint_flag_val) => {
|
||||
let flag = match level {
|
||||
LintSource::CommandLine(lint_flag_val, orig_level) => {
|
||||
let flag = match orig_level {
|
||||
Level::Warn => "-W",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Allow => panic!(),
|
||||
Level::Allow => "-A",
|
||||
};
|
||||
let hyphen_case_lint_name = name.replace("_", "-");
|
||||
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…
Reference in New Issue
Block a user