1
Fork 0

Simplify lint source computation.

This commit is contained in:
Camille GILLOT 2024-07-04 10:33:42 +00:00
parent 5f1f45b095
commit ff1fc68c11

View file

@ -695,59 +695,20 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
let name = pprust::path_to_string(&meta_item.path); let name = pprust::path_to_string(&meta_item.path);
let lint_result = let lint_result =
self.store.check_lint_name(&name, tool_name, self.registered_tools); self.store.check_lint_name(&name, tool_name, self.registered_tools);
match &lint_result {
let (ids, name) = match lint_result {
CheckLintNameResult::Ok(ids) => { CheckLintNameResult::Ok(ids) => {
// This checks for instances where the user writes let name =
// `#[expect(unfulfilled_lint_expectations)]` in that case we want to avoid meta_item.path.segments.last().expect("empty lint name").ident.name;
// overriding the lint level but instead add an expectation that can't be (ids, name)
// fulfilled. The lint message will include an explanation, that the
// `unfulfilled_lint_expectations` lint can't be expected.
if let Level::Expect(expect_id) = level {
// The `unfulfilled_lint_expectations` lint is not part of any lint
// groups. Therefore. we only need to check the slice if it contains a
// single lint.
let is_unfulfilled_lint_expectations = match ids {
[lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS),
_ => false,
};
self.provider.push_expectation(
expect_id,
LintExpectation::new(
reason,
sp,
is_unfulfilled_lint_expectations,
tool_name,
),
);
}
let src = LintLevelSource::Node {
name: meta_item
.path
.segments
.last()
.expect("empty lint name")
.ident
.name,
span: sp,
reason,
};
for &id in *ids {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
} }
CheckLintNameResult::Tool(ids, new_lint_name) => { CheckLintNameResult::Tool(ids, new_lint_name) => {
let src = match new_lint_name { let name = match new_lint_name {
None => { None => {
let complete_name = let complete_name =
&format!("{}::{}", tool_ident.unwrap().name, name); &format!("{}::{}", tool_ident.unwrap().name, name);
LintLevelSource::Node { Symbol::intern(complete_name)
name: Symbol::intern(complete_name),
span: sp,
reason,
}
} }
Some(new_lint_name) => { Some(new_lint_name) => {
self.emit_span_lint( self.emit_span_lint(
@ -756,27 +717,13 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
DeprecatedLintName { DeprecatedLintName {
name, name,
suggestion: sp, suggestion: sp,
replace: new_lint_name, replace: &new_lint_name,
}, },
); );
LintLevelSource::Node { Symbol::intern(&new_lint_name)
name: Symbol::intern(new_lint_name),
span: sp,
reason,
}
} }
}; };
for &id in *ids { (ids, name)
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),
);
}
} }
CheckLintNameResult::MissingTool => { CheckLintNameResult::MissingTool => {
@ -784,9 +731,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
// exist in the tool or the code was not compiled with the tool and // exist in the tool or the code was not compiled with the tool and
// therefore the lint was never added to the `LintStore`. To detect // therefore the lint was never added to the `LintStore`. To detect
// this is the responsibility of the lint tool. // this is the responsibility of the lint tool.
continue;
} }
&CheckLintNameResult::NoTool => { CheckLintNameResult::NoTool => {
sess.dcx().emit_err(UnknownToolInScopedLint { sess.dcx().emit_err(UnknownToolInScopedLint {
span: tool_ident.map(|ident| ident.span), span: tool_ident.map(|ident| ident.span),
tool_name: tool_name.unwrap(), tool_name: tool_name.unwrap(),
@ -796,57 +744,87 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
continue; continue;
} }
_ if !self.lint_added_lints => {}
CheckLintNameResult::Renamed(ref replace) => { CheckLintNameResult::Renamed(ref replace) => {
let suggestion = if self.lint_added_lints {
RenamedLintSuggestion::WithSpan { suggestion: sp, replace }; let suggestion =
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
let lint = RenamedLint { name: name.as_str(), suggestion }; let name =
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
let lint = RenamedLint { name: name.as_str(), suggestion };
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}
// If this lint was renamed, apply the new lint instead of ignoring the
// attribute. 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.
let CheckLintNameResult::Ok(ids) =
self.store.check_lint_name(replace, None, self.registered_tools)
else {
panic!("renamed lint does not exist: {replace}");
};
(ids, Symbol::intern(&replace))
} }
CheckLintNameResult::Removed(ref reason) => { CheckLintNameResult::Removed(ref reason) => {
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); if self.lint_added_lints {
let lint = RemovedLint { name: name.as_str(), reason }; let name =
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
let lint = RemovedLint { name: name.as_str(), reason };
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}
continue;
} }
CheckLintNameResult::NoLint(suggestion) => { CheckLintNameResult::NoLint(suggestion) => {
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); if self.lint_added_lints {
let suggestion = suggestion.map(|(replace, from_rustc)| { let name =
UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc } tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
}); let suggestion = suggestion.map(|(replace, from_rustc)| {
let lint = UnknownLint { name, suggestion }; UnknownLintSuggestion::WithSpan {
self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint); suggestion: sp,
replace,
from_rustc,
}
});
let lint = UnknownLint { name, suggestion };
self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint);
}
continue;
}
};
let src = LintLevelSource::Node { name, span: sp, reason };
for &id in ids {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
} }
} }
// If this lint was renamed, apply the new lint instead of ignoring the attribute.
// This happens outside of the match because the new lint should be applied even if
// we don't warn about the name change.
if let CheckLintNameResult::Renamed(new_name) = lint_result {
// 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.
let CheckLintNameResult::Ok(ids) =
self.store.check_lint_name(&new_name, None, self.registered_tools)
else {
panic!("renamed lint does not exist: {new_name}");
};
let src = // This checks for instances where the user writes
LintLevelSource::Node { name: Symbol::intern(&new_name), span: sp, reason }; // `#[expect(unfulfilled_lint_expectations)]` in that case we want to avoid
for &id in ids { // overriding the lint level but instead add an expectation that can't be
if self.check_gated_lint(id, attr.span, false) { // fulfilled. The lint message will include an explanation, that the
self.insert_spec(id, (level, src)); // `unfulfilled_lint_expectations` lint can't be expected.
} if let Level::Expect(expect_id) = level {
} // The `unfulfilled_lint_expectations` lint is not part of any lint
if let Level::Expect(expect_id) = level { // groups. Therefore. we only need to check the slice if it contains a
self.provider.push_expectation( // single lint.
expect_id, let is_unfulfilled_lint_expectations = match ids {
LintExpectation::new(reason, sp, false, tool_name), [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS),
); _ => false,
} };
self.provider.push_expectation(
expect_id,
LintExpectation::new(
reason,
sp,
is_unfulfilled_lint_expectations,
tool_name,
),
);
} }
} }
} }