diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 72e9f92c6b95a..46c9460d085c8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -378,6 +378,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { tcx.sess, tcx.features(), tcx.registered_attr_tools(()), + tcx.registered_lint_tools(()), ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, ), } diff --git a/compiler/rustc_attr_ir/src/lint.rs b/compiler/rustc_attr_ir/src/lint.rs index 4839412ed59ad..7b535c8768816 100644 --- a/compiler/rustc_attr_ir/src/lint.rs +++ b/compiler/rustc_attr_ir/src/lint.rs @@ -1,5 +1,5 @@ use rustc_macros::{Decodable, Encodable, PrintAttribute, StableHash}; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; use crate::{HashIgnoredAttrId, PrintAttribute}; #[derive(Clone, Copy, Debug, StableHash, Encodable, Decodable, PrintAttribute)] @@ -44,14 +44,13 @@ impl LintCheckKind { #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] pub struct LintCheck { /// The lint's tool name, if present. - pub tool: Option, - /// The lint's name, minus the tool name if any. + pub tool: Option, + /// The full normalized lint name of an existing lint, including the tool name. + /// This may not be what we user wrote down, in case of renamed lints the new lint name is here. + /// The above implies that `LintStore::find_lints` is guaranteed to find this lint using this symbol. /// - /// For example: - /// - `clippy::blah` -> `blah` - /// - `unstable_imports` -> `unstable_imports` - /// - `custom_tool::blah::bleh` -> `blah::bleh` - pub lint_name: Symbol, + /// For example, `single_use_lifetime` is changed to `single_use_lifetimes`. + pub lint_name_normalized: Symbol, /// The span of the lint name. /// /// For example `#[deny(foo, bar, reason = "reason")]` diff --git a/compiler/rustc_attr_parsing/src/attributes/lint.rs b/compiler/rustc_attr_parsing/src/attributes/lint.rs index db57b23f6296a..638c9a85b3f6e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint.rs @@ -2,12 +2,17 @@ use rustc_ast::join_path_syms; use rustc_attr_ir::AttributeKind; use rustc_attr_ir::lint::{LintCheck, LintCheckKind}; use rustc_attr_ir::target::{AssocCtxt, MethodKind, Target}; -use rustc_lint_defs::builtin::UNUSED_ATTRIBUTES; -use rustc_span::{Symbol, sym}; +use rustc_lint_defs::builtin::{RENAMED_AND_REMOVED_LINTS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES}; +use rustc_lint_defs::{CheckLintNameResult, LintId}; +use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::ThinVec; use crate::attributes::{AcceptMapping, AttributeParser, AttributeStability}; use crate::context::{AcceptContext, ExpectStringLiteral, FinalizeContext}; +use crate::diagnostics::{ + DeprecatedLintName, RemovedLint, RenamedLint, RenamedLintSuggestion, UnknownLint, + UnknownLintSuggestion, UnknownToolInScopedLint, +}; use crate::parser::{ArgParser, MetaItemOrLitParser}; use crate::target_checking::AllowedTargets; use crate::target_checking::Policy::{Allow, Warn}; @@ -69,9 +74,18 @@ impl LintParser { ), }; + let lint_name_normalized = if let Some((_lint_ids, new_lint_name)) = + LintParser::check_lint_name(lint_name, tool, p.span(), cx) + { + new_lint_name + } else { + // Discard lint attributes with unknown lints in them + continue; + }; + self.lints.push(LintCheck { - tool, - lint_name, + tool: tool.map(|tool| tool.name), + lint_name_normalized, lint_span: p.span(), kind, attr_id, @@ -130,6 +144,147 @@ impl LintParser { } } } + + fn check_lint_name<'a>( + lint_name: Symbol, + tool: Option, + lint_span: Span, + cx: &mut AcceptContext<'_, 'a>, + ) -> Option<(&'a [LintId], Symbol)> { + // FIXME For historic reasons these checks are not executed on macro calls + if cx.target == Target::MacroCall { + return None; + } + + let lint_result = cx.sess.lint_store.as_ref().unwrap().check_attribute_lint_name( + lint_name.as_str(), + tool.map(|tool| tool.name), + cx.lint_tools.unwrap(), + ); + + // FIXME(164898) Lint attributes are parsed twice, once on the AST and once on the HIR + // Both times emit diagnostics, for historic reasons + // We only want to emit these lints once, on the HIR. + // On the AST the parse filter will be `Some` (since we're only parsing lint attributes then) + // #164898 will fix this, after that PR this check can be removed + let should_lint = cx.parse_filter.is_none(); + + let (ids, name) = match lint_result { + CheckLintNameResult::Ok(ids) => (ids, lint_name), + + CheckLintNameResult::Tool(ids, new_lint_name) => { + let name = match new_lint_name { + None => { + let complete_name = &format!("{}::{lint_name}", tool.unwrap().name); + Symbol::intern(complete_name) + } + Some(new_lint_name) => { + let symbol = Symbol::intern(&new_lint_name); + if should_lint { + cx.emit_lint( + RENAMED_AND_REMOVED_LINTS, + DeprecatedLintName { + name: lint_name.to_string(), + suggestion: lint_span, + replace: new_lint_name, + }, + lint_span, + ); + } + symbol + } + }; + (ids, name) + } + + CheckLintNameResult::MissingTool => { + // If `MissingTool` is returned, then either the lint does not + // 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 + // this is the responsibility of the lint tool. + return None; + } + + CheckLintNameResult::NoTool => { + if should_lint { + cx.emit_err(UnknownToolInScopedLint { + span: Some(tool.unwrap().span), + tool_name: tool.unwrap().name, + lint_name: lint_name.to_string(), + is_nightly_build: cx.sess.is_nightly_build(), + }); + } + return None; + } + + CheckLintNameResult::Renamed(ref replace) => { + if should_lint { + let suggestion = RenamedLintSuggestion::WithSpan { + suggestion: lint_span, + replace: replace.clone(), + }; + let name = tool + .map(|Ident { name, .. }| format!("{name}::{lint_name}")) + .unwrap_or_else(|| lint_name.to_string()); + cx.emit_lint( + RENAMED_AND_REMOVED_LINTS, + RenamedLint { name, replace: replace.clone(), suggestion }, + lint_span, + ); + } + + // 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) = cx + .sess + .lint_store + .as_ref() + .unwrap() + .check_attribute_lint_name(replace, None, cx.lint_tools.unwrap()) + else { + panic!("renamed lint does not exist: {replace}"); + }; + + (ids, Symbol::intern(&replace)) + } + + CheckLintNameResult::Removed(ref reason) => { + if should_lint { + let name = if let Some(Ident { name, .. }) = tool { + format!("{name}::{lint_name}") + } else { + lint_name.to_string() + }; + cx.emit_lint( + RENAMED_AND_REMOVED_LINTS, + RemovedLint { name, reason: reason.clone() }, + lint_span, + ); + } + return None; + } + + CheckLintNameResult::NoLint(suggestion) => { + if should_lint { + let name = tool + .map(|Ident { name, .. }| format!("{name}::{lint_name}")) + .unwrap_or_else(|| lint_name.to_string()); + let suggestion = + suggestion.map(|(replace, from_rustc)| UnknownLintSuggestion::WithSpan { + suggestion: lint_span, + replace, + from_rustc, + }); + cx.emit_lint(UNKNOWN_LINTS, UnknownLint { name, suggestion }, lint_span); + } + return None; + } + }; + Some((ids, name)) + } } impl AttributeParser for LintParser { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 27fb67bd35006..58e5dd41b02b7 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -2199,3 +2199,84 @@ pub(crate) struct Unused { #[derive(Diagnostic)] #[diag("use of deprecated `no_link` attribute")] pub(crate) struct NoLinkAttrUsed; + +#[derive(Diagnostic)] +#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")] +pub(crate) struct DeprecatedLintName { + pub name: String, + #[suggestion("change it to", code = "{replace}", applicability = "machine-applicable")] + pub suggestion: Span, + pub replace: String, +} + +#[derive(Diagnostic)] +#[diag("unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`", code = E0710)] +pub(crate) struct UnknownToolInScopedLint { + #[primary_span] + pub span: Option, + pub tool_name: Symbol, + pub lint_name: String, + #[help("add `#![register_tool({$tool_name})]` to the crate root")] + pub is_nightly_build: bool, +} + +#[derive(Diagnostic)] +#[diag("lint `{$name}` has been renamed to `{$replace}`")] +pub(crate) struct RenamedLint { + pub name: String, + pub replace: String, + #[subdiagnostic] + pub suggestion: RenamedLintSuggestion, +} + +#[derive(Subdiagnostic)] +pub enum RenamedLintSuggestion { + #[suggestion("use the new name", code = "{replace}", applicability = "machine-applicable")] + WithSpan { + #[primary_span] + suggestion: Span, + replace: String, + }, + #[help("use the new name `{$replace}`")] + WithoutSpan { replace: String }, +} + +#[derive(Diagnostic)] +#[diag("unknown lint: `{$name}`")] +pub(crate) struct UnknownLint { + pub name: String, + #[subdiagnostic] + pub suggestion: Option, +} + +#[derive(Subdiagnostic)] +pub enum UnknownLintSuggestion { + #[suggestion( + "{$from_rustc -> + [true] a lint with a similar name exists in `rustc` lints + *[false] did you mean + }", + code = "{replace}", + applicability = "maybe-incorrect" + )] + WithSpan { + #[primary_span] + suggestion: Span, + replace: Symbol, + from_rustc: bool, + }, + #[help( + "{$from_rustc -> + [true] a lint with a similar name exists in `rustc` lints: `{$replace}` + *[false] did you mean: `{$replace}` + }" + )] + WithoutSpan { replace: Symbol, from_rustc: bool }, +} + +#[derive(Diagnostic)] +#[diag("lint `{$name}` has been removed: {$reason}")] +pub(crate) struct RemovedLint { + pub name: String, + pub reason: String, +} diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 3d2af3ba6b509..0e2b3eb212b96 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -39,6 +39,7 @@ pub struct EmitAttribute( /// context, through which all attributes can be lowered. pub struct AttributeParser<'sess> { pub(crate) attr_tools: Option<&'sess RegisteredTools>, + pub(crate) lint_tools: Option<&'sess RegisteredTools>, pub(crate) features: Option<&'sess Features>, pub(crate) sess: &'sess Session, pub(crate) should_emit: ShouldEmit, @@ -46,7 +47,7 @@ pub struct AttributeParser<'sess> { /// *Only* parse attributes that passes this filter. /// /// Used in cases where we want the lowering infrastructure for parse just limited attributes. - parse_filter: Option<&'sess dyn Fn(&ast::Attribute) -> bool>, + pub(crate) parse_filter: Option<&'sess dyn Fn(&ast::Attribute) -> bool>, } impl<'sess> AttributeParser<'sess> { @@ -114,6 +115,7 @@ impl<'sess> AttributeParser<'sess> { features, should_emit, None, + None, ); assert!(parsed.len() <= 1); parsed.pop() @@ -156,8 +158,10 @@ impl<'sess> AttributeParser<'sess> { features: Option<&'sess Features>, should_emit: ShouldEmit, attr_tools: Option<&'sess RegisteredTools>, + lint_tools: Option<&'sess RegisteredTools>, ) -> Vec { - let mut p = AttributeParser { features, attr_tools, parse_filter, sess, should_emit }; + let mut p = + AttributeParser { features, attr_tools, lint_tools, parse_filter, sess, should_emit }; p.parse_attribute_list( attrs, target_span, @@ -236,7 +240,14 @@ impl<'sess> AttributeParser<'sess> { parse_fn: fn(cx: &mut AcceptContext<'_, '_>, item: &I) -> T, template: &AttributeTemplate, ) -> T { - let mut parser = Self { features, attr_tools: None, parse_filter: None, sess, should_emit }; + let mut parser = Self { + features, + attr_tools: None, + lint_tools: None, + parse_filter: None, + sess, + should_emit, + }; let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: EmitAttribute| { sess.psess.dyn_buffer_lint_sess(lint_id.lint, span, target_node_id, kind.0) }; @@ -278,11 +289,13 @@ impl<'sess> AttributeParser<'sess> { sess: &'sess Session, features: &'sess Features, attr_tools: &'sess RegisteredTools, + lint_tools: &'sess RegisteredTools, should_emit: ShouldEmit, ) -> Self { Self { features: Some(features), attr_tools: Some(attr_tools), + lint_tools: Some(lint_tools), parse_filter: None, sess, should_emit, diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 4e6b8b2d38f3b..813c980411dd5 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -118,7 +118,7 @@ pub use attributes::cfg::{ pub use attributes::cfg_select::*; pub use attributes::util::{is_builtin_attr, parse_version}; pub use context::ShouldEmit; -pub use diagnostics::ParsedDescription; +pub use diagnostics::{ParsedDescription, RenamedLintSuggestion, UnknownLintSuggestion}; pub use interface::{AttributeParser, EmitAttribute}; pub use rustc_parse::parser::Recovery; pub use template::AttributeTemplate; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 2f7c05c906350..c2fcd18344728 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2246,6 +2246,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { Some(self.cx.ecfg.features), ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, Some(self.cx.resolver.registered_attr_tools()), + Some(self.cx.resolver.registered_lint_tools()), ); let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span }; diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs index a97aef1a66058..2595646cd0794 100644 --- a/compiler/rustc_interface/src/limits.rs +++ b/compiler/rustc_interface/src/limits.rs @@ -39,6 +39,7 @@ pub fn get_limits(krate_attrs: &[ast::Attribute], sess: &Session, features: &Fea // So, no lints here to avoid duplicates. ShouldEmit::EarlyFatal { also_emit_lints: false }, None, + None, ); let attrs = &attrs; Limits { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 9678ed65d2891..47d1a01555244 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -19,8 +19,8 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::{Pat, PatKind}; use rustc_lint_defs::{ - FutureIncompatibleInfo, Lint, LintExpectationId, LintId, StableLintExpectationId, - UnstableLintExpectationId, + CheckLintNameResult, FutureIncompatibleInfo, Lint, LintExpectationId, LintId, + StableLintExpectationId, UnstableLintExpectationId, }; use rustc_middle::lint::{LevelSpec, StableLevelSpec, UnstableLevelSpec}; use rustc_middle::middle::privacy::EffectiveVisibilities; @@ -91,6 +91,15 @@ impl DynLintStore for LintStore { rustc_session::LintGroup { name, lints, is_externally_loaded } })) } + + fn check_attribute_lint_name( + &self, + lint_name: &str, + tool_name: Option, + lint_tools: &RegisteredTools, + ) -> CheckLintNameResult<'_> { + self.check_lint_name(lint_name, tool_name, lint_tools) + } } /// The target of the `by_name` map, which accounts for renaming/deprecation. @@ -125,29 +134,6 @@ struct LintGroup { depr: Option, } -#[derive(Debug)] -pub enum CheckLintNameResult<'a> { - Ok(&'a [LintId]), - /// Lint doesn't exist. Potentially contains a suggestion for a correct lint name. - NoLint(Option<(Symbol, bool)>), - /// The lint refers to a tool that has not been registered. - NoTool, - /// The lint has been renamed to a new name. - Renamed(String), - /// The lint has been removed due to the given reason. - Removed(String), - - /// The lint is from a tool. The `LintId` will be returned as if it were a - /// rustc lint. The `Option` indicates if the lint has been - /// renamed. - Tool(&'a [LintId], Option), - - /// The lint is from a tool. Either the lint does not exist in the tool or - /// the code was not compiled with the tool and therefore the lint was - /// never added to the `LintStore`. - MissingTool, -} - impl LintStore { pub fn new() -> LintStore { LintStore { @@ -335,7 +321,7 @@ impl LintStore { /// Checks the name of a lint for its existence, and whether it was /// renamed or removed. Generates a `Diag` containing a - /// warning for renamed and removed lints. This is over both lint + /// warning for renamed and removed lints. aThis is over both lint /// names from attributes and those passed on the command line. Since /// it emits non-fatal warnings and there are *two* lint passes that /// inspect attributes, this is only run from the late pass to avoid diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 0f1d127b9d1b5..10c875b76780d 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -2,6 +2,7 @@ use std::num::NonZero; use rustc_attr_ir::find_attr; +use rustc_attr_parsing::{RenamedLintSuggestion, UnknownLintSuggestion}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::codes::*; use rustc_errors::formatting::DiagMessageAddArg; @@ -63,17 +64,6 @@ impl Subdiagnostic for OverruledAttributeSub { } } -#[derive(Diagnostic)] -#[diag("unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`", code = E0710)] -pub(crate) struct UnknownToolInScopedLint { - #[primary_span] - pub span: Option, - pub tool_name: Symbol, - pub lint_name: String, - #[help("add `#![register_tool({$tool_name})]` to the crate root")] - pub is_nightly_build: bool, -} - #[derive(Diagnostic)] #[diag("functions generic over types or consts must be mangled")] pub(crate) struct BuiltinNoMangleGeneric { @@ -1409,15 +1399,6 @@ pub(crate) struct OverruledAttributeLint<'a> { pub sub: OverruledAttributeSub, } -#[derive(Diagnostic)] -#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")] -pub(crate) struct DeprecatedLintName<'a> { - pub name: String, - #[suggestion("change it to", code = "{replace}", applicability = "machine-applicable")] - pub suggestion: Span, - pub replace: &'a str, -} - #[derive(Diagnostic)] #[diag("lint name `{$name}` is deprecated and may not have an effect in the future")] #[help("change it to {$replace}")] @@ -1428,45 +1409,17 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { pub requested_level: RequestedLevel<'a>, } -#[derive(Diagnostic)] -#[diag("lint `{$name}` has been renamed to `{$replace}`")] -pub(crate) struct RenamedLint<'a> { - pub name: &'a str, - pub replace: &'a str, - #[subdiagnostic] - pub suggestion: RenamedLintSuggestion<'a>, -} - -#[derive(Subdiagnostic)] -pub(crate) enum RenamedLintSuggestion<'a> { - #[suggestion("use the new name", code = "{replace}", applicability = "machine-applicable")] - WithSpan { - #[primary_span] - suggestion: Span, - replace: &'a str, - }, - #[help("use the new name `{$replace}`")] - WithoutSpan { replace: &'a str }, -} - #[derive(Diagnostic)] #[diag("lint `{$name}` has been renamed to `{$replace}`")] pub(crate) struct RenamedLintFromCommandLine<'a> { pub name: &'a str, pub replace: &'a str, #[subdiagnostic] - pub suggestion: RenamedLintSuggestion<'a>, + pub suggestion: RenamedLintSuggestion, #[subdiagnostic] pub requested_level: RequestedLevel<'a>, } -#[derive(Diagnostic)] -#[diag("lint `{$name}` has been removed: {$reason}")] -pub(crate) struct RemovedLint<'a> { - pub name: &'a str, - pub reason: &'a str, -} - #[derive(Diagnostic)] #[diag("lint `{$name}` has been removed: {$reason}")] pub(crate) struct RemovedLintFromCommandLine<'a> { @@ -1476,39 +1429,6 @@ pub(crate) struct RemovedLintFromCommandLine<'a> { pub requested_level: RequestedLevel<'a>, } -#[derive(Diagnostic)] -#[diag("unknown lint: `{$name}`")] -pub(crate) struct UnknownLint { - pub name: String, - #[subdiagnostic] - pub suggestion: Option, -} - -#[derive(Subdiagnostic)] -pub(crate) enum UnknownLintSuggestion { - #[suggestion( - "{$from_rustc -> - [true] a lint with a similar name exists in `rustc` lints - *[false] did you mean - }", - code = "{replace}", - applicability = "maybe-incorrect" - )] - WithSpan { - #[primary_span] - suggestion: Span, - replace: Symbol, - from_rustc: bool, - }, - #[help( - "{$from_rustc -> - [true] a lint with a similar name exists in `rustc` lints: `{$replace}` - *[false] did you mean: `{$replace}` - }" - )] - WithoutSpan { replace: Symbol, from_rustc: bool }, -} - #[derive(Diagnostic)] #[diag("unknown lint: `{$name}`", code = E0602)] pub(crate) struct UnknownLintFromCommandLine<'a> { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index a442c62819c8d..754f5036c2fd7 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -5,7 +5,9 @@ use rustc_ast::CRATE_NODE_ID; use rustc_attr_ir::lint::{LintCheck, LintCheckKind}; use rustc_attr_ir::target::Target; use rustc_attr_ir::{Attribute, DocAttribute, find_attr}; -use rustc_attr_parsing::{AttributeParser, Recovery, ShouldEmit}; +use rustc_attr_parsing::{ + AttributeParser, Recovery, RenamedLintSuggestion, ShouldEmit, UnknownLintSuggestion, +}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, MultiSpan, msg}; @@ -19,7 +21,8 @@ use rustc_lint_defs::builtin::{ UNFULFILLED_LINT_EXPECTATIONS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES, }; use rustc_lint_defs::{ - Level, Lint, LintExpectationId, LintId, StableLintExpectationId, UnstableLintExpectationId, + CheckLintNameResult, Level, Lint, LintExpectationId, LintId, StableLintExpectationId, + UnstableLintExpectationId, }; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ @@ -30,17 +33,15 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{RegisteredTools, TyCtxt}; use rustc_session::Session; use rustc_span::def_id::CRATE_MOD_ID; -use rustc_span::{AttrId, DUMMY_SP, Ident, Span, Symbol, sym}; +use rustc_span::{AttrId, DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builtin::MISSING_DOCS; -use crate::context::{CheckLintNameResult, LintStore}; +use crate::context::LintStore; use crate::diagnostics::{ - CheckNameUnknownTool, DeprecatedLintName, DeprecatedLintNameFromCommandLine, - IgnoredUnlessCrateSpecified, OverruledAttribute, OverruledAttributeLint, OverruledAttributeSub, - RemovedLint, RemovedLintFromCommandLine, RenamedLint, RenamedLintFromCommandLine, - RenamedLintSuggestion, RequestedLevel, UnknownLint, UnknownLintFromCommandLine, - UnknownLintSuggestion, UnknownToolInScopedLint, UnsupportedGroup, + CheckNameUnknownTool, DeprecatedLintNameFromCommandLine, IgnoredUnlessCrateSpecified, + OverruledAttribute, OverruledAttributeLint, OverruledAttributeSub, RemovedLintFromCommandLine, + RenamedLintFromCommandLine, RequestedLevel, UnknownLintFromCommandLine, UnsupportedGroup, }; use crate::late::unerased_lint_store; @@ -492,7 +493,8 @@ where { CheckLintNameResult::Renamed(ref replace) => { let name = lint_name.as_str(); - let suggestion = RenamedLintSuggestion::WithoutSpan { replace }; + let suggestion = + RenamedLintSuggestion::WithoutSpan { replace: replace.clone() }; let requested_level = RequestedLevel { level, lint_name }; let lint = RenamedLintFromCommandLine { name, replace, suggestion, requested_level }; @@ -700,6 +702,7 @@ where CRATE_NODE_ID, Some(self.features), ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, + None, Some(self.registered_lint_tools), ); self.add_hir_inner(&parsed, is_crate_node) @@ -724,14 +727,16 @@ where return; }; - let sess = self.sess; - - // FIXME: consider performing these checks in attribute parsing instead for (lint_index, lint_check) in lint_checks.into_iter().enumerate() { - let LintCheck { tool, lint_name, lint_span, kind, reason, attr_id, attr_span: _ } = - lint_check; - - let full_lint_name = lint_name.as_str(); + let LintCheck { + tool, + lint_name_normalized, + lint_span, + kind, + reason, + attr_id, + attr_span: _, + } = lint_check; let level = match kind { LintCheckKind::Allow => Level::Allow, @@ -746,122 +751,9 @@ where let lint_id = (level == Level::Expect) .then(|| self.provider.mk_lint_expectation_id(attr_id.attr_id, lint_index as u16)); - let lint_result = self.store.check_lint_name( - full_lint_name, - tool.map(|i| i.name), - self.registered_lint_tools, - ); - - let (ids, name) = match lint_result { - CheckLintNameResult::Ok(ids) => (ids, lint_name), - - CheckLintNameResult::Tool(ids, new_lint_name) => { - let name = match new_lint_name { - None => { - let complete_name = &format!("{}::{lint_name}", tool.unwrap().name); - Symbol::intern(complete_name) - } - Some(new_lint_name) => { - self.emit_span_lint( - builtin::RENAMED_AND_REMOVED_LINTS, - lint_span.into(), - DeprecatedLintName { - name: lint_name.to_string(), - suggestion: lint_span, - replace: &new_lint_name, - }, - ); - Symbol::intern(&new_lint_name) - } - }; - (ids, name) - } - - CheckLintNameResult::MissingTool => { - // If `MissingTool` is returned, then either the lint does not - // 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 - // this is the responsibility of the lint tool. - continue; - } - - CheckLintNameResult::NoTool => { - sess.dcx().emit_err(UnknownToolInScopedLint { - span: Some(tool.unwrap().span), - tool_name: tool.unwrap().name, - lint_name: full_lint_name.to_string(), - is_nightly_build: sess.is_nightly_build(), - }); - continue; - } - - CheckLintNameResult::Renamed(ref replace) => { - if self.lint_added_lints { - let suggestion = - RenamedLintSuggestion::WithSpan { suggestion: lint_span, replace }; - let name = tool - .map(|Ident { name, .. }| format!("{name}::{full_lint_name}")) - .unwrap_or_else(|| full_lint_name.to_string()); - self.emit_span_lint( - RENAMED_AND_REMOVED_LINTS, - lint_span.into(), - RenamedLint { name: name.as_str(), replace, suggestion }, - ); - } - - // 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_lint_tools) - else { - panic!("renamed lint does not exist: {replace}"); - }; - - (ids, Symbol::intern(&replace)) - } - - CheckLintNameResult::Removed(ref reason) => { - if self.lint_added_lints { - let name = if let Some(Ident { name, .. }) = tool { - &format!("{name}::{full_lint_name}") - } else { - full_lint_name - }; - self.emit_span_lint( - RENAMED_AND_REMOVED_LINTS, - lint_span.into(), - RemovedLint { name, reason }, - ); - } - continue; - } - - CheckLintNameResult::NoLint(suggestion) => { - if self.lint_added_lints { - let name = tool - .map(|Ident { name, .. }| format!("{name}::{full_lint_name}")) - .unwrap_or_else(|| full_lint_name.to_string()); - let suggestion = suggestion.map(|(replace, from_rustc)| { - UnknownLintSuggestion::WithSpan { - suggestion: lint_span, - replace, - from_rustc, - } - }); - self.emit_span_lint( - UNKNOWN_LINTS, - lint_span.into(), - UnknownLint { name, suggestion }, - ); - } - continue; - } - }; + let src = LintLevelSource::Node { name: lint_name_normalized, span: lint_span, reason }; + let ids = self.store.find_lints(lint_name_normalized.as_str()).unwrap(); - let src = LintLevelSource::Node { name, span: lint_span, reason }; for &id in ids { if self.check_gated_lint(id, lint_span, false) { self.insert_spec(id, LevelSpec::new(level, lint_id, src)); @@ -883,12 +775,7 @@ where }; self.provider.push_expectation( expect_id, - LintExpectation::new( - reason, - lint_span, - is_unfulfilled_lint_expectations, - tool.map(|i| i.name), - ), + LintExpectation::new(reason, lint_span, is_unfulfilled_lint_expectations, tool), ); } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 97c500ba74cee..1086e9b0dc982 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -139,7 +139,7 @@ use unused::*; #[rustfmt::skip] pub use builtin::MissingDoc; -pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; +pub use context::{EarlyContext, LateContext, LintContext, LintStore}; pub use early::diagnostics::DiagAndSess; pub use early::{EarlyCheckNode, check_ast_node}; pub use late::{check_crate, late_lint_mod, unerased_lint_store}; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 5e7b417ef68a4..fac9523767a92 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -603,6 +603,29 @@ pub enum DeprecatedSinceKind { pub type RegisteredTools = FxIndexSet; +#[derive(Debug)] +pub enum CheckLintNameResult<'a> { + Ok(&'a [LintId]), + /// Lint doesn't exist. Potentially contains a suggestion for a correct lint name. + NoLint(Option<(Symbol, bool)>), + /// The lint refers to a tool that has not been registered. + NoTool, + /// The lint has been renamed to a new name. + Renamed(String), + /// The lint has been removed due to the given reason. + Removed(String), + + /// The lint is from a tool. The `LintId` will be returned as if it were a + /// rustc lint. The `Option` indicates if the lint has been + /// renamed. + Tool(&'a [LintId], Option), + + /// The lint is from a tool. Either the lint does not exist in the tool or + /// the code was not compiled with the tool and therefore the lint was + /// never added to the `LintStore`. + MissingTool, +} + /// Declares a static item of type `&'static Lint`. /// /// See for diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 79c84b74b7222..27103e0a2778c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1365,7 +1365,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for lint in lints { let LintCheck { tool: None, - lint_name, + lint_name_normalized, lint_span, kind: _, reason: _, @@ -1376,7 +1376,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { continue; }; - match lint_name { + match lint_name_normalized { sym::dead_code_pub_in_binary => { if !self.tcx.crate_types().contains(&CrateType::Executable) { self.tcx.emit_node_span_lint( diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 474615c9a7672..6277fb69dc212 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -177,6 +177,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { &self.r.tcx.sess, self.r.features, self.r.tcx().registered_attr_tools(()), + self.r.tcx().registered_lint_tools(()), ShouldEmit::Nothing, ); let attrs = parser.parse_attribute_list( diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ad866eb5b28a7..12a8c906cfd7c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -20,6 +20,7 @@ use rustc_errors::{ Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, PResult, TerminalUrl, }; use rustc_feature::UnstableFeatures; +use rustc_lint_defs::{CheckLintNameResult, RegisteredTools}; use rustc_macros::StableHash; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; @@ -82,6 +83,13 @@ pub struct CompilerIO { pub trait DynLintStore: Any + DynSync + DynSend { /// Provides a way to access lint groups without depending on `rustc_lint` fn lint_groups_iter(&self) -> Box + '_>; + + fn check_attribute_lint_name( + &self, + lint_name: &str, + tool_name: Option, + lint_tools: &RegisteredTools, + ) -> CheckLintNameResult<'_>; } /// Hardware pointer-signing keys in ARM8.3. diff --git a/src/tools/clippy/clippy_lints/src/collapsible_if.rs b/src/tools/clippy/clippy_lints/src/collapsible_if.rs index a707fe845ef79..f69f27f2ca71e 100644 --- a/src/tools/clippy/clippy_lints/src/collapsible_if.rs +++ b/src/tools/clippy/clippy_lints/src/collapsible_if.rs @@ -10,7 +10,7 @@ use rustc_errors::Applicability; use rustc_hir::{Block, Expr, ExprKind, StmtKind}; use rustc_lexer::TokenKind; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; -use rustc_span::{BytePos, Ident, Span, Symbol}; +use rustc_span::{BytePos, Span, Symbol}; declare_clippy_lint! { /// ### What it does @@ -247,13 +247,13 @@ impl CollapsibleIf { matches!( lint, LintCheck { - tool: Some(Ident { name: sym::clippy, .. }), + tool: Some(sym::clippy), kind: LintCheckKind::Expect, .. } ) }) - .any(|lint| [expected_lint_name, sym::style, sym::all].contains(&lint.lint_name)) => + .any(|lint| [&format!("clippy::{expected_lint_name}"), "clippy::style", "clippy::all"].contains(&lint.lint_name_normalized.as_str())) => { let attr_span = lints.first().unwrap().attr_span.to(lints.last().unwrap().attr_span); // There is an `expect` attribute -- check that there is no _other_ significant text diff --git a/src/tools/clippy/clippy_lints/src/returns/needless_return.rs b/src/tools/clippy/clippy_lints/src/returns/needless_return.rs index 3e1b4be2cf031..055facd8465a1 100644 --- a/src/tools/clippy/clippy_lints/src/returns/needless_return.rs +++ b/src/tools/clippy/clippy_lints/src/returns/needless_return.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet_with_context; use clippy_utils::{ binary_expr_needs_parentheses, is_from_proc_macro, leaks_droppable_temporary_with_limited_lifetime, - span_contains_cfg, span_find_starting_semi, sym, + span_contains_cfg, span_find_starting_semi, }; use rustc_attr_ir::lang_items::LangItem; @@ -13,7 +13,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, Expr, ExprKind, HirId, MatchSource, StmtKind}; use rustc_lint::{LateContext, LintContext as _}; use rustc_middle::ty::{self, Ty}; -use rustc_span::{BytePos, Ident, Pos as _, Span}; +use rustc_span::{BytePos, Pos as _, Span}; use std::borrow::Cow; use std::fmt::Display; @@ -188,11 +188,11 @@ fn check_final_expr<'tcx>( matches!( lint, LintCheck { - tool: Some(Ident { name: sym::clippy, .. }), - lint_name: sym::needless_return | sym::style | sym::all | sym::warnings, + lint_name_normalized, kind: LintCheckKind::Expect, .. - } + } if ["clippy::needless_return", "clippy::style", "clippy::all", "clippy::warnings"].contains(&lint_name_normalized.as_str()) + ) }) => { diff --git a/tests/pretty/delegation/generics.pp b/tests/pretty/delegation/generics.pp index 5bfecd355396d..9016a9874383d 100644 --- a/tests/pretty/delegation/generics.pp +++ b/tests/pretty/delegation/generics.pp @@ -1,4 +1,4 @@ -#![attr = LintCheck([LintCheck {lint_name: "incomplete_features", +#![attr = LintCheck([LintCheck {lint_name_normalized: "incomplete_features", kind: Allow}])] #![attr = Feature([fn_delegation#0])] extern crate std; diff --git a/tests/pretty/delegation/inherit-attributes.pp b/tests/pretty/delegation/inherit-attributes.pp index 575e309c392bb..7c1818abfd632 100644 --- a/tests/pretty/delegation/inherit-attributes.pp +++ b/tests/pretty/delegation/inherit-attributes.pp @@ -1,4 +1,4 @@ -#![attr = LintCheck([LintCheck {lint_name: "incomplete_features", +#![attr = LintCheck([LintCheck {lint_name_normalized: "incomplete_features", kind: Allow}])] #![attr = Feature([fn_delegation#0])] extern crate std; diff --git a/tests/pretty/delegation/inline-attribute.pp b/tests/pretty/delegation/inline-attribute.pp index dfe1097035674..11641a867b87b 100644 --- a/tests/pretty/delegation/inline-attribute.pp +++ b/tests/pretty/delegation/inline-attribute.pp @@ -1,4 +1,4 @@ -#![attr = LintCheck([LintCheck {lint_name: "incomplete_features", +#![attr = LintCheck([LintCheck {lint_name_normalized: "incomplete_features", kind: Allow}])] #![attr = Feature([fn_delegation#0])] extern crate std; diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp index 15841d103e0f6..9b7e5d3893652 100644 --- a/tests/pretty/hir-delegation.pp +++ b/tests/pretty/hir-delegation.pp @@ -1,4 +1,4 @@ -#![attr = LintCheck([LintCheck {lint_name: "incomplete_features", +#![attr = LintCheck([LintCheck {lint_name_normalized: "incomplete_features", kind: Allow}])] #![attr = Feature([fn_delegation#0])] extern crate std; diff --git a/tests/pretty/hir-lifetimes.pp b/tests/pretty/hir-lifetimes.pp index 92cc37b584b32..603923f03303b 100644 --- a/tests/pretty/hir-lifetimes.pp +++ b/tests/pretty/hir-lifetimes.pp @@ -1,4 +1,5 @@ -#![attr = LintCheck([LintCheck {lint_name: "unused", kind: Allow}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "unused", +kind: Allow}])] extern crate std; #[attr = PreludeImport] use ::std::prelude::rust_2015::*; diff --git a/tests/pretty/lint-attrs-filtered-out.pp b/tests/pretty/lint-attrs-filtered-out.pp new file mode 100644 index 0000000000000..a829ca7770651 --- /dev/null +++ b/tests/pretty/lint-attrs-filtered-out.pp @@ -0,0 +1,11 @@ +extern crate std; +#[attr = PreludeImport] +use ::std::prelude::rust_2015::*; +//@ pretty-compare-only +//@ pretty-mode:hir +//@ pp-exact:lint-attrs-filtered-out.pp + +// `does_not_exist` is filtered out on the hir +#[attr = LintCheck([LintCheck {lint_name_normalized: "dead_code", +kind: Deny}])] +fn main() { } diff --git a/tests/pretty/lint-attrs-filtered-out.rs b/tests/pretty/lint-attrs-filtered-out.rs new file mode 100644 index 0000000000000..9dc4898f3ff41 --- /dev/null +++ b/tests/pretty/lint-attrs-filtered-out.rs @@ -0,0 +1,7 @@ +//@ pretty-compare-only +//@ pretty-mode:hir +//@ pp-exact:lint-attrs-filtered-out.pp + +// `does_not_exist` is filtered out on the hir +#[deny(dead_code, does_not_exist)] +fn main() {} diff --git a/tests/pretty/pin-ergonomics-hir.pp b/tests/pretty/pin-ergonomics-hir.pp index 5dd405c89258d..2a5e969a2bd2c 100644 --- a/tests/pretty/pin-ergonomics-hir.pp +++ b/tests/pretty/pin-ergonomics-hir.pp @@ -1,6 +1,7 @@ #![attr = Feature([pin_ergonomics#0])] -#![attr = LintCheck([LintCheck {lint_name: "dead_code", kind: Allow}, -LintCheck {lint_name: "incomplete_features", kind: Allow}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "dead_code", +kind: Allow}, LintCheck {lint_name_normalized: "incomplete_features", +kind: Allow}])] extern crate std; #[attr = PreludeImport] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/eii/cfg_on_eii.stdout b/tests/ui/eii/cfg_on_eii.stdout index e49f3cdbb8c45..a75ef4cec5cb4 100644 --- a/tests/ui/eii/cfg_on_eii.stdout +++ b/tests/ui/eii/cfg_on_eii.stdout @@ -1,5 +1,6 @@ #![attr = Feature([extern_item_impls#0])] -#![attr = LintCheck([LintCheck {lint_name: "deprecated", kind: Deny}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "deprecated", +kind: Deny}])] extern crate std; #[attr = PreludeImport] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr index 4e7c835b57912..d14e7328c308c 100644 --- a/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr +++ b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr @@ -10,14 +10,6 @@ LL | #![deny(implicit_provenance_casts)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `#[warn(unknown_lints)]` on by default -warning: lint `fuzzy_provenance_casts` has been renamed to `implicit_provenance_casts` - --> $DIR/feature-gate-strict_provenance_lints.rs:7:9 - | -LL | #![deny(fuzzy_provenance_casts)] - | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts` - | - = note: `#[warn(renamed_and_removed_lints)]` on by default - warning: unknown lint: `implicit_provenance_casts` --> $DIR/feature-gate-strict_provenance_lints.rs:7:9 | @@ -29,12 +21,6 @@ LL | #![deny(fuzzy_provenance_casts)] = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: lint `lossy_provenance_casts` has been renamed to `implicit_provenance_casts` - --> $DIR/feature-gate-strict_provenance_lints.rs:10:9 - | -LL | #![deny(lossy_provenance_casts)] - | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts` - warning: unknown lint: `implicit_provenance_casts` --> $DIR/feature-gate-strict_provenance_lints.rs:10:9 | @@ -46,5 +32,19 @@ LL | #![deny(lossy_provenance_casts)] = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +warning: lint `fuzzy_provenance_casts` has been renamed to `implicit_provenance_casts` + --> $DIR/feature-gate-strict_provenance_lints.rs:7:9 + | +LL | #![deny(fuzzy_provenance_casts)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts` + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +warning: lint `lossy_provenance_casts` has been renamed to `implicit_provenance_casts` + --> $DIR/feature-gate-strict_provenance_lints.rs:10:9 + | +LL | #![deny(lossy_provenance_casts)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts` + warning: 5 warnings emitted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index f685a989c0aa6..9b091ff4fbf91 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -12,6 +12,27 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | #[macro_escape] | ^^^^^^^^^^^^^^^ +warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:101:12 + | +LL | #![feature(rust1)] + | ^^^^^ + | + = note: `#[warn(stable_features)]` on by default + +warning: unused attribute + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:9 + | +LL | #![path="3800"] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: `#[path]` is unused on this inline module +note: the lint level is defined here + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:35:9 + | +LL | #![warn(unused_attributes, unknown_lints)] + | ^^^^^^^^^^^^^^^^^ + warning: unknown lint: `x5400` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:41:9 | @@ -42,6 +63,87 @@ warning: unknown lint: `x5100` LL | #![deny(x5100)] | ^^^^^ +warning: the `macro_use` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:4 + | +LL | #![macro_use] + | ^^^^^^^^^ + | + = help: the `macro_use` attribute can be applied to extern crates and modules + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `should_panic` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:51:4 + | +LL | #![should_panic] + | ^^^^^^^^^^^^ + | + = help: the `should_panic` attribute can only be applied to functions + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `ignore` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:4 + | +LL | #![ignore] + | ^^^^^^ + | + = help: the `ignore` attribute can only be applied to functions + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `proc_macro_derive` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:4 + | +LL | #![proc_macro_derive(Test)] + | ^^^^^^^^^^^^^^^^^ + | + = help: the `proc_macro_derive` attribute can only be applied to functions + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `cold` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:4 + | +LL | #![cold] + | ^^^^ + | + = help: the `cold` attribute can only be applied to functions + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `link` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:4 + | +LL | #![link(name = "x")] + | ^^^^ + | + = help: the `link` attribute can only be applied to foreign modules + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `link_name` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:4 + | +LL | #![link_name = "1900"] + | ^^^^^^^^^ + | + = help: the `link_name` attribute can be applied to foreign functions and foreign statics + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `link_section` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:81:4 + | +LL | #![link_section = ",1800"] + | ^^^^^^^^^^^^ + | + = help: the `link_section` attribute can be applied to functions and statics + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: the `must_use` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:86:4 + | +LL | #![must_use] + | ^^^^^^^^ + | + = help: the `must_use` attribute can be applied to data types, functions, and traits + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + warning: unknown lint: `x5400` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:8 | @@ -186,108 +288,6 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:101:12 - | -LL | #![feature(rust1)] - | ^^^^^ - | - = note: `#[warn(stable_features)]` on by default - -warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:9 - | -LL | #![path="3800"] - | ^^^^^^^^^^^^^^^ help: remove this attribute - | - = note: `#[path]` is unused on this inline module -note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:35:9 - | -LL | #![warn(unused_attributes, unknown_lints)] - | ^^^^^^^^^^^^^^^^^ - -warning: the `macro_use` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:4 - | -LL | #![macro_use] - | ^^^^^^^^^ - | - = help: the `macro_use` attribute can be applied to extern crates and modules - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `should_panic` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:51:4 - | -LL | #![should_panic] - | ^^^^^^^^^^^^ - | - = help: the `should_panic` attribute can only be applied to functions - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `ignore` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:4 - | -LL | #![ignore] - | ^^^^^^ - | - = help: the `ignore` attribute can only be applied to functions - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `proc_macro_derive` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:4 - | -LL | #![proc_macro_derive(Test)] - | ^^^^^^^^^^^^^^^^^ - | - = help: the `proc_macro_derive` attribute can only be applied to functions - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `cold` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:4 - | -LL | #![cold] - | ^^^^ - | - = help: the `cold` attribute can only be applied to functions - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `link` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:4 - | -LL | #![link(name = "x")] - | ^^^^ - | - = help: the `link` attribute can only be applied to foreign modules - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `link_name` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:4 - | -LL | #![link_name = "1900"] - | ^^^^^^^^^ - | - = help: the `link_name` attribute can be applied to foreign functions and foreign statics - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `link_section` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:81:4 - | -LL | #![link_section = ",1800"] - | ^^^^^^^^^^^^ - | - = help: the `link_section` attribute can be applied to functions and statics - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -warning: the `must_use` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:86:4 - | -LL | #![must_use] - | ^^^^^^^^ - | - = help: the `must_use` attribute can be applied to data types, functions, and traits - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - warning: the `macro_use` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:7 | diff --git a/tests/ui/lint/lint-check-on-macro.rs b/tests/ui/lint/lint-check-on-macro.rs new file mode 100644 index 0000000000000..b21ba9e13bc5f --- /dev/null +++ b/tests/ui/lint/lint-check-on-macro.rs @@ -0,0 +1,15 @@ +//@ check-pass + +macro_rules! wat { + () => { + #[allow(unused_attributes)] + { + #[allow(unregistered_tool::lint)] + println!("boo"); + } + }; +} + +fn main() { + wat!(); +} diff --git a/tests/ui/lint/register-tool-lint.rs b/tests/ui/lint/register-tool-lint.rs index 17d3afbf6e26e..f56d9a0a8c362 100644 --- a/tests/ui/lint/register-tool-lint.rs +++ b/tests/ui/lint/register-tool-lint.rs @@ -5,5 +5,3 @@ #![warn(abc::my_lint)] //~^ ERROR unknown tool name `abc` found in scoped lint //~| HELP add `#![register_tool(abc)]` -//~| ERROR unknown tool name `abc` -//~| HELP add `#![register_tool(abc)]` diff --git a/tests/ui/lint/register-tool-lint.stderr b/tests/ui/lint/register-tool-lint.stderr index 7ebdbdec92972..98b4af935d340 100644 --- a/tests/ui/lint/register-tool-lint.stderr +++ b/tests/ui/lint/register-tool-lint.stderr @@ -6,15 +6,6 @@ LL | #![warn(abc::my_lint)] | = help: add `#![register_tool(abc)]` to the crate root -error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint` - --> $DIR/register-tool-lint.rs:5:9 - | -LL | #![warn(abc::my_lint)] - | ^^^ - | - = help: add `#![register_tool(abc)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0710`. diff --git a/tests/ui/lint/renamed-lints-still-apply.stderr b/tests/ui/lint/renamed-lints-still-apply.stderr index 9eaf711293388..5e4dae1e21be7 100644 --- a/tests/ui/lint/renamed-lints-still-apply.stderr +++ b/tests/ui/lint/renamed-lints-still-apply.stderr @@ -1,11 +1,3 @@ -warning: lint `single_use_lifetime` has been renamed to `single_use_lifetimes` - --> $DIR/renamed-lints-still-apply.rs:2:9 - | -LL | #![deny(single_use_lifetime)] - | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `single_use_lifetimes` - | - = note: `#[warn(renamed_and_removed_lints)]` on by default - error: lifetime parameter `'a` only used once --> $DIR/renamed-lints-still-apply.rs:6:9 | @@ -25,5 +17,13 @@ LL - fn _foo<'a>(_x: &'a u32) {} LL + fn _foo(_x: &u32) {} | +warning: lint `single_use_lifetime` has been renamed to `single_use_lifetimes` + --> $DIR/renamed-lints-still-apply.rs:2:9 + | +LL | #![deny(single_use_lifetime)] + | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `single_use_lifetimes` + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/tool-attributes/cross-crate.rs b/tests/ui/tool-attributes/cross-crate.rs index 1992174aca3e1..11c594de02aa3 100644 --- a/tests/ui/tool-attributes/cross-crate.rs +++ b/tests/ui/tool-attributes/cross-crate.rs @@ -5,6 +5,4 @@ extern crate use_tool; #[foo::bar] //~ ERROR cannot find module or crate `foo` in this scope #[allow(foo::baz)] //~ ERROR unknown tool name `foo` - //~| ERROR unknown tool name `foo` - //~| ERROR unknown tool name `foo` fn main() {} diff --git a/tests/ui/tool-attributes/cross-crate.stderr b/tests/ui/tool-attributes/cross-crate.stderr index 051a1b05405e9..6b669601f24f2 100644 --- a/tests/ui/tool-attributes/cross-crate.stderr +++ b/tests/ui/tool-attributes/cross-crate.stderr @@ -1,11 +1,3 @@ -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::baz` - --> $DIR/cross-crate.rs:7:9 - | -LL | #[allow(foo::baz)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/cross-crate.rs:6:3 | @@ -19,18 +11,8 @@ LL | #[allow(foo::baz)] | ^^^ | = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::baz` - --> $DIR/cross-crate.rs:7:9 - | -LL | #[allow(foo::baz)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0433, E0710. For more information about an error, try `rustc --explain E0433`. diff --git a/tests/ui/tool-attributes/tool_lints.rs b/tests/ui/tool-attributes/tool_lints.rs index 9e4aa7a939acb..0a9be75681ca5 100644 --- a/tests/ui/tool-attributes/tool_lints.rs +++ b/tests/ui/tool-attributes/tool_lints.rs @@ -1,5 +1,3 @@ #[warn(foo::bar)] //~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar` -//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` -//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` fn main() {} diff --git a/tests/ui/tool-attributes/tool_lints.stderr b/tests/ui/tool-attributes/tool_lints.stderr index eee0a9784ece8..a0c5316d95b07 100644 --- a/tests/ui/tool-attributes/tool_lints.stderr +++ b/tests/ui/tool-attributes/tool_lints.stderr @@ -6,24 +6,6 @@ LL | #[warn(foo::bar)] | = help: add `#![register_tool(foo)]` to the crate root -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/tool_lints.rs:1:8 - | -LL | #[warn(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/tool_lints.rs:1:8 - | -LL | #[warn(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0710`. diff --git a/tests/ui/tool-attributes/unknown-lint-tool-name.rs b/tests/ui/tool-attributes/unknown-lint-tool-name.rs index 84ab7c1944ab2..cf26341d8b588 100644 --- a/tests/ui/tool-attributes/unknown-lint-tool-name.rs +++ b/tests/ui/tool-attributes/unknown-lint-tool-name.rs @@ -1,8 +1,4 @@ #![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar` - //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` - //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` #[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar` - //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` - //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar` fn main() {} diff --git a/tests/ui/tool-attributes/unknown-lint-tool-name.stderr b/tests/ui/tool-attributes/unknown-lint-tool-name.stderr index 91baf88273756..8ef80efdbcf51 100644 --- a/tests/ui/tool-attributes/unknown-lint-tool-name.stderr +++ b/tests/ui/tool-attributes/unknown-lint-tool-name.stderr @@ -7,49 +7,13 @@ LL | #![deny(foo::bar)] = help: add `#![register_tool(foo)]` to the crate root error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 + --> $DIR/unknown-lint-tool-name.rs:3:9 | LL | #[allow(foo::bar)] | ^^^ | = help: add `#![register_tool(foo)]` to the crate root -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:1:9 - | -LL | #![deny(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 - | -LL | #[allow(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:1:9 - | -LL | #![deny(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 - | -LL | #[allow(foo::bar)] - | ^^^ - | - = help: add `#![register_tool(foo)]` to the crate root - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0710`. diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 7fb3f85b7f5ce..904850e6277d1 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -3,8 +3,9 @@ coroutines#0, decl_macro#0, deref_patterns#0, explicit_tail_calls#0, gen_blocks#0, more_qualified_paths#0, never_patterns#0, pattern_types#0, pattern_type_macro#0, prelude_import#0, specialization#0, trace_macros#0, trait_alias#0, try_blocks#0, try_blocks_heterogeneous#0, yeet_expr#0])] -#![attr = LintCheck([LintCheck {lint_name: "incomplete_features", -kind: Allow}, LintCheck {lint_name: "unused_attributes", kind: Allow}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "incomplete_features", +kind: Allow}, LintCheck {lint_name_normalized: "unused_attributes", +kind: Allow}])] extern crate std; #[attr = PreludeImport] use std::prelude::rust_2024::*; @@ -39,8 +40,9 @@ use self::prelude::*; * inner multi-line doc comment */ #[doc = "inner doc attribute"] -#[attr = LintCheck([LintCheck {lint_name: "dead_code", kind: Allow}, -LintCheck {lint_name: "unused_variables", kind: Allow}])] +#[attr = LintCheck([LintCheck {lint_name_normalized: "dead_code", +kind: Allow}, LintCheck {lint_name_normalized: "unused_variables", +kind: Allow}])] #[attr = NoStd] mod attributes { diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout index 11d31361acdd6..c6769ae56b80c 100644 --- a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout @@ -1,6 +1,7 @@ #![attr = Feature([adt_const_params#0, gca_adts#0, gca_min_const_items#0, gca_macroless_args#0])] -#![attr = LintCheck([LintCheck {lint_name: "dead_code", kind: Allow}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "dead_code", +kind: Allow}])] extern crate std; #[attr = PreludeImport] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout index 9c70b1fec7469..82f9dd8952a1f 100644 --- a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout +++ b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout @@ -1,4 +1,5 @@ -#![attr = LintCheck([LintCheck {lint_name: "dead_code", kind: Allow}])] +#![attr = LintCheck([LintCheck {lint_name_normalized: "dead_code", +kind: Allow}])] extern crate std; #[attr = PreludeImport] use ::std::prelude::rust_2015::*;