Rollup merge of #122416 - Zalathar:levels, r=petrochenkov

Various style improvements to `rustc_lint::levels`

While reading this file, I noticed a few opportunities to make things a little nicer:

- Replace some nested if-let with let-chains
- Tweak a match pattern to allow shorthand struct syntax
- Fuse an `is_empty` check with getting the last element
- Merge some common code that emits `MalformedAttribute` and continues
- Format `"{tool}::{name}"` in a way that's consistent with other match arms
- Replace if-let-else-panic with let-else
- Use early-exit to flatten a method body

Some of these changes cause indentation churn, so ignoring whitespace is recommended.
This commit is contained in:
Matthias Krüger 2024-03-14 11:09:59 +01:00 committed by GitHub
commit 0286591d59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -103,11 +103,12 @@ fn raw_lint_id_level(
mut idx: LintStackIndex, mut idx: LintStackIndex,
aux: Option<&FxIndexMap<LintId, LevelAndSource>>, aux: Option<&FxIndexMap<LintId, LevelAndSource>>,
) -> (Option<Level>, LintLevelSource) { ) -> (Option<Level>, LintLevelSource) {
if let Some(specs) = aux { if let Some(specs) = aux
if let Some(&(level, src)) = specs.get(&id) { && let Some(&(level, src)) = specs.get(&id)
return (Some(level), src); {
} return (Some(level), src);
} }
loop { loop {
let LintSet { ref specs, parent } = self.list[idx]; let LintSet { ref specs, parent } = self.list[idx];
if let Some(&(level, src)) = specs.get(&id) { if let Some(&(level, src)) = specs.get(&id) {
@ -177,7 +178,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
// There is only something to do if there are attributes at all. // There is only something to do if there are attributes at all.
[] => {} [] => {}
// Most of the time, there is only one attribute. Avoid fetching HIR in that case. // Most of the time, there is only one attribute. Avoid fetching HIR in that case.
[(local_id, _)] => levels.add_id(HirId { owner, local_id: *local_id }), &[(local_id, _)] => levels.add_id(HirId { owner, local_id }),
// Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
// a standard visit. // a standard visit.
// FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's. // FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's.
@ -643,63 +644,61 @@ fn insert_spec(&mut self, id: LintId, (mut level, src): LevelAndSource) {
// //
// This means that this only errors if we're truly lowering the lint // This means that this only errors if we're truly lowering the lint
// level from forbid. // level from forbid.
if self.lint_added_lints && level != Level::Forbid { if self.lint_added_lints && level != Level::Forbid && old_level == Level::Forbid {
if let Level::Forbid = old_level { // Backwards compatibility check:
// Backwards compatibility check: //
// // We used to not consider `forbid(lint_group)`
// We used to not consider `forbid(lint_group)` // as preventing `allow(lint)` for some lint `lint` in
// as preventing `allow(lint)` for some lint `lint` in // `lint_group`. For now, issue a future-compatibility
// `lint_group`. For now, issue a future-compatibility // warning for this case.
// warning for this case. let id_name = id.lint.name_lower();
let id_name = id.lint.name_lower(); let fcw_warning = match old_src {
let fcw_warning = match old_src { LintLevelSource::Default => false,
LintLevelSource::Default => false, LintLevelSource::Node { name, .. } => self.store.is_lint_group(name),
LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol), };
}; debug!(
debug!( "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}",
"fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}", fcw_warning,
fcw_warning, self.current_specs(),
self.current_specs(), old_src,
old_src, id_name
id_name );
); let sub = match old_src {
let sub = match old_src { LintLevelSource::Default => {
LintLevelSource::Default => { OverruledAttributeSub::DefaultSource { id: id.to_string() }
OverruledAttributeSub::DefaultSource { id: id.to_string() } }
} LintLevelSource::Node { span, reason, .. } => {
LintLevelSource::Node { span, reason, .. } => { OverruledAttributeSub::NodeSource { span, reason }
OverruledAttributeSub::NodeSource { span, reason } }
} LintLevelSource::CommandLine(_, _) => OverruledAttributeSub::CommandLineSource,
LintLevelSource::CommandLine(_, _) => OverruledAttributeSub::CommandLineSource, };
}; if !fcw_warning {
if !fcw_warning { self.sess.dcx().emit_err(OverruledAttribute {
self.sess.dcx().emit_err(OverruledAttribute { span: src.span(),
span: src.span(), overruled: src.span(),
lint_level: level.as_str(),
lint_source: src.name(),
sub,
});
} else {
self.emit_span_lint(
FORBIDDEN_LINT_GROUPS,
src.span().into(),
OverruledAttributeLint {
overruled: src.span(), overruled: src.span(),
lint_level: level.as_str(), lint_level: level.as_str(),
lint_source: src.name(), lint_source: src.name(),
sub, sub,
}); },
} else { );
self.emit_span_lint( }
FORBIDDEN_LINT_GROUPS,
src.span().into(),
OverruledAttributeLint {
overruled: src.span(),
lint_level: level.as_str(),
lint_source: src.name(),
sub,
},
);
}
// Retain the forbid lint level, unless we are // Retain the forbid lint level, unless we are
// issuing a FCW. In the FCW case, we want to // issuing a FCW. In the FCW case, we want to
// respect the new setting. // respect the new setting.
if !fcw_warning { if !fcw_warning {
return; return;
}
} }
} }
@ -770,15 +769,15 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
let Some(mut metas) = attr.meta_item_list() else { continue }; let Some(mut metas) = attr.meta_item_list() else { continue };
if metas.is_empty() { // Check whether `metas` is empty, and get its last element.
let Some(tail_li) = metas.last() else {
// This emits the unused_attributes lint for `#[level()]` // This emits the unused_attributes lint for `#[level()]`
continue; continue;
} };
// Before processing the lint names, look for a reason (RFC 2383) // Before processing the lint names, look for a reason (RFC 2383)
// at the end. // at the end.
let mut reason = None; let mut reason = None;
let tail_li = &metas[metas.len() - 1];
if let Some(item) = tail_li.meta_item() { if let Some(item) = tail_li.meta_item() {
match item.kind { match item.kind {
ast::MetaItemKind::Word => {} // actual lint names handled later ast::MetaItemKind::Word => {} // actual lint names handled later
@ -834,21 +833,16 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
let meta_item = match li { let meta_item = match li {
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item, ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
_ => { _ => {
if let Some(item) = li.meta_item() { let sub = if let Some(item) = li.meta_item()
if let ast::MetaItemKind::NameValue(_) = item.kind { && let ast::MetaItemKind::NameValue(_) = item.kind
if item.path == sym::reason { && item.path == sym::reason
sess.dcx().emit_err(MalformedAttribute { {
span: sp, MalformedAttributeSub::ReasonMustComeLast(sp)
sub: MalformedAttributeSub::ReasonMustComeLast(sp), } else {
}); MalformedAttributeSub::BadAttributeArgument(sp)
continue; };
}
} sess.dcx().emit_err(MalformedAttribute { span: sp, sub });
}
sess.dcx().emit_err(MalformedAttribute {
span: sp,
sub: MalformedAttributeSub::BadAttributeArgument(sp),
});
continue; continue;
} }
}; };
@ -987,11 +981,7 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
} }
CheckLintNameResult::NoLint(suggestion) => { CheckLintNameResult::NoLint(suggestion) => {
let name = if let Some(tool_ident) = tool_ident { let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
format!("{}::{}", tool_ident.name, name)
} else {
name.to_string()
};
let suggestion = suggestion.map(|(replace, from_rustc)| { let suggestion = suggestion.map(|(replace, from_rustc)| {
UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc } UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc }
}); });
@ -1005,27 +995,24 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
if let CheckLintNameResult::Renamed(new_name) = lint_result { if let CheckLintNameResult::Renamed(new_name) = lint_result {
// Ignore any errors or warnings that happen because the new name is inaccurate // Ignore any errors or warnings that happen because the new name is inaccurate
// NOTE: `new_name` already includes the tool name, so we don't have to add it again. // NOTE: `new_name` already includes the tool name, so we don't have to add it again.
if let CheckLintNameResult::Ok(ids) = let CheckLintNameResult::Ok(ids) =
self.store.check_lint_name(&new_name, None, self.registered_tools) self.store.check_lint_name(&new_name, None, self.registered_tools)
{ else {
let src = LintLevelSource::Node {
name: Symbol::intern(&new_name),
span: sp,
reason,
};
for &id in ids {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
if let Level::Expect(expect_id) = level {
self.provider.push_expectation(
expect_id,
LintExpectation::new(reason, sp, false, tool_name),
);
}
} else {
panic!("renamed lint does not exist: {new_name}"); panic!("renamed lint does not exist: {new_name}");
};
let src =
LintLevelSource::Node { name: Symbol::intern(&new_name), span: sp, reason };
for &id in ids {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
if let Level::Expect(expect_id) = level {
self.provider.push_expectation(
expect_id,
LintExpectation::new(reason, sp, false, tool_name),
);
} }
} }
} }
@ -1058,38 +1045,44 @@ fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id:
/// Returns `true` if the lint's feature is enabled. /// Returns `true` if the lint's feature is enabled.
#[track_caller] #[track_caller]
fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool { fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool {
if let Some(feature) = lint_id.lint.feature_gate { let feature = if let Some(feature) = lint_id.lint.feature_gate
if !self.features.active(feature) { && !self.features.active(feature)
if self.lint_added_lints { {
let lint = builtin::UNKNOWN_LINTS; // Lint is behind a feature that is not enabled; eventually return false.
let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS); feature
// FIXME: make this translatable } else {
#[allow(rustc::diagnostic_outside_of_impl)] // Lint is ungated or its feature is enabled; exit early.
#[allow(rustc::untranslatable_diagnostic)] return true;
lint_level( };
self.sess,
if self.lint_added_lints {
let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
lint_level(
self.sess,
lint,
level,
src,
Some(span.into()),
fluent::lint_unknown_gated_lint,
|lint| {
lint.arg("name", lint_id.lint.name_lower());
lint.note(fluent::lint_note);
rustc_session::parse::add_feature_diagnostics_for_issue(
lint, lint,
level, &self.sess,
src, feature,
Some(span.into()), GateIssue::Language,
fluent::lint_unknown_gated_lint, lint_from_cli,
|lint| {
lint.arg("name", lint_id.lint.name_lower());
lint.note(fluent::lint_note);
rustc_session::parse::add_feature_diagnostics_for_issue(
lint,
&self.sess,
feature,
GateIssue::Language,
lint_from_cli,
);
},
); );
} },
return false; );
}
} }
true
false
} }
/// Find the lint level for a lint. /// Find the lint level for a lint.