Rollup merge of #97757 - xFrednet:rfc-2383-expect-with-force-warn, r=wesleywiser,flip1995
Support lint expectations for `--force-warn` lints (RFC 2383) Rustc has a `--force-warn` flag, which overrides lint level attributes and forces the diagnostics to always be warn. This means, that for lint expectations, the diagnostic can't be suppressed as usual. This also means that the expectation would not be fulfilled, even if a lint had been triggered in the expected scope. This PR now also tracks the expectation ID in the `ForceWarn` level. I've also made some minor adjustments, to possibly catch more bugs and make the whole implementation more robust. This will probably conflict with https://github.com/rust-lang/rust/pull/97718. That PR should ideally be reviewed and merged first. The conflict itself will be trivial to fix. --- r? `@wesleywiser` cc: `@flip1995` since you've helped with the initial review and also discussed this topic with me. 🙃 Follow-up of: https://github.com/rust-lang/rust/pull/87835 Issue: https://github.com/rust-lang/rust/issues/85549 Yeah, and that's it.
This commit is contained in:
commit
95be954af4
19 changed files with 317 additions and 71 deletions
|
@ -324,7 +324,7 @@ impl LintStore {
|
|||
registered_tools: &RegisteredTools,
|
||||
) {
|
||||
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
|
||||
if lint_name_only == crate::WARNINGS.name_lower() && level == Level::ForceWarn {
|
||||
if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn(_)) {
|
||||
struct_span_err!(
|
||||
sess,
|
||||
DUMMY_SP,
|
||||
|
@ -375,7 +375,7 @@ impl LintStore {
|
|||
match level {
|
||||
Level::Allow => "-A",
|
||||
Level::Warn => "-W",
|
||||
Level::ForceWarn => "--force-warn",
|
||||
Level::ForceWarn(_) => "--force-warn",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Expect(_) => {
|
||||
|
|
|
@ -19,16 +19,16 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
|
|||
let lint_expectations = &tcx.lint_levels(()).lint_expectations;
|
||||
|
||||
for (id, expectation) in lint_expectations {
|
||||
if !fulfilled_expectations.contains(id)
|
||||
&& tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
|
||||
{
|
||||
// This check will always be true, since `lint_expectations` only
|
||||
// holds stable ids
|
||||
if let LintExpectationId::Stable { hir_id, .. } = id {
|
||||
// This check will always be true, since `lint_expectations` only
|
||||
// holds stable ids
|
||||
if let LintExpectationId::Stable { hir_id, .. } = id {
|
||||
if !fulfilled_expectations.contains(&id)
|
||||
&& tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
|
||||
{
|
||||
emit_unfulfilled_expectation_lint(tcx, *hir_id, expectation);
|
||||
} else {
|
||||
unreachable!("at this stage all `LintExpectationId`s are stable");
|
||||
}
|
||||
} else {
|
||||
unreachable!("at this stage all `LintExpectationId`s are stable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,9 @@ impl<'s> LintLevelsBuilder<'s> {
|
|||
};
|
||||
for id in ids {
|
||||
// ForceWarn and Forbid cannot be overridden
|
||||
if let Some((Level::ForceWarn | Level::Forbid, _)) = self.current_specs().get(&id) {
|
||||
if let Some((Level::ForceWarn(_) | Level::Forbid, _)) =
|
||||
self.current_specs().get(&id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -226,11 +228,18 @@ impl<'s> LintLevelsBuilder<'s> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Level::ForceWarn = old_level {
|
||||
self.current_specs_mut().insert(id, (old_level, old_src));
|
||||
} else {
|
||||
self.current_specs_mut().insert(id, (level, src));
|
||||
}
|
||||
match (old_level, level) {
|
||||
// If the new level is an expectation store it in `ForceWarn`
|
||||
(Level::ForceWarn(_), Level::Expect(expectation_id)) => self
|
||||
.current_specs_mut()
|
||||
.insert(id, (Level::ForceWarn(Some(expectation_id)), old_src)),
|
||||
// Keep `ForceWarn` level but drop the expectation
|
||||
(Level::ForceWarn(_), _) => {
|
||||
self.current_specs_mut().insert(id, (Level::ForceWarn(None), old_src))
|
||||
}
|
||||
// Set the lint level as normal
|
||||
_ => self.current_specs_mut().insert(id, (level, src)),
|
||||
};
|
||||
}
|
||||
|
||||
/// Pushes a list of AST lint attributes onto this context.
|
||||
|
@ -269,6 +278,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
|||
|
||||
let level = match Level::from_attr(attr) {
|
||||
None => continue,
|
||||
// This is the only lint level with a `LintExpectationId` that can be created from an attribute
|
||||
Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
|
||||
let stable_id = self.create_stable_id(unstable_id, hir_id, attr_index);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue