Move attribute lints to rustc_lint
This commit is contained in:
parent
864339abf9
commit
8f59eb0177
27 changed files with 284 additions and 344 deletions
|
|
@ -3945,6 +3945,7 @@ dependencies = [
|
|||
"rustc_hashes",
|
||||
"rustc_hir_id",
|
||||
"rustc_index",
|
||||
"rustc_lint_defs",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
|
|
@ -3962,7 +3963,6 @@ dependencies = [
|
|||
"rustc_abi",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr_parsing",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
|
|
@ -3970,6 +3970,7 @@ dependencies = [
|
|||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_infer",
|
||||
"rustc_lint",
|
||||
"rustc_lint_defs",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
|
|
|
|||
|
|
@ -14,18 +14,6 @@ attr_parsing_deprecated_item_suggestion =
|
|||
.help = add `#![feature(deprecated_suggestion)]` to the crate root
|
||||
.note = see #94785 for more details
|
||||
|
||||
attr_parsing_empty_attribute =
|
||||
unused attribute
|
||||
.suggestion = {$valid_without_list ->
|
||||
[true] remove these parentheses
|
||||
*[other] remove this attribute
|
||||
}
|
||||
.note = {$valid_without_list ->
|
||||
[true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
|
||||
*[other] using `{$attr_path}` with an empty list has no effect
|
||||
}
|
||||
|
||||
|
||||
attr_parsing_empty_confusables =
|
||||
expected at least one confusable name
|
||||
attr_parsing_empty_link_name =
|
||||
|
|
@ -119,19 +107,9 @@ attr_parsing_invalid_repr_hint_no_value =
|
|||
attr_parsing_invalid_since =
|
||||
'since' must be a Rust version number, such as "1.31.0"
|
||||
|
||||
attr_parsing_invalid_style = {$is_used_as_inner ->
|
||||
[false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
|
||||
*[other] the `#![{$name}]` attribute can only be used at the crate root
|
||||
}
|
||||
.note = This attribute does not have an `!`, which means it is applied to this {$target}
|
||||
|
||||
attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
|
||||
.help = `#[{$name}]` can {$only}be applied to {$applied}
|
||||
.suggestion = remove the attribute
|
||||
attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target}
|
||||
.warn = {-attr_parsing_previously_accepted}
|
||||
.help = `#[{$name}]` can {$only}be applied to {$applied}
|
||||
.suggestion = remove the attribute
|
||||
|
||||
attr_parsing_limit_invalid =
|
||||
`limit` must be a non-negative integer
|
||||
|
|
@ -250,19 +228,10 @@ attr_parsing_unsupported_literal_generic =
|
|||
attr_parsing_unsupported_literal_suggestion =
|
||||
consider removing the prefix
|
||||
|
||||
attr_parsing_unused_duplicate =
|
||||
unused attribute
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
.warn = {-attr_parsing_previously_accepted}
|
||||
|
||||
attr_parsing_unused_multiple =
|
||||
multiple `{$name}` attributes
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
|
||||
-attr_parsing_previously_accepted =
|
||||
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
attr_parsing_whole_archive_needs_static =
|
||||
linking modifier `whole-archive` is only compatible with `static` linking kind
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// SingleAttributeParser which is what we have two of here.
|
||||
|
||||
use rustc_hir::attrs::{AttributeKind, InlineAttr};
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
|
|
@ -56,9 +57,7 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
|
|||
}
|
||||
}
|
||||
ArgParser::NameValue(_) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_feature::Features;
|
|||
use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
|
||||
use rustc_hir::attrs::*;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::kw;
|
||||
use rustc_target::spec::{Arch, BinaryFormat};
|
||||
|
|
@ -71,9 +72,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
|
|||
// Specifically `#[link = "dl"]` is accepted with a FCW
|
||||
// For more information, see https://github.com/rust-lang/rust/pull/143193
|
||||
ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use rustc_errors::DiagArgValue;
|
||||
use rustc_hir::attrs::MacroUseArgs;
|
||||
use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS;
|
||||
|
||||
use super::prelude::*;
|
||||
use crate::session_diagnostics::IllFormedAttributeInputLint;
|
||||
|
|
@ -152,23 +153,13 @@ impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
|
|||
ArgParser::NoArgs => false,
|
||||
ArgParser::List(list) => {
|
||||
let Some(l) = list.single() else {
|
||||
let span = cx.attr_span;
|
||||
let suggestions = cx.suggestions();
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS);
|
||||
return None;
|
||||
};
|
||||
match l.meta_item().and_then(|i| i.path().word_sym()) {
|
||||
Some(sym::local_inner_macros) => true,
|
||||
_ => {
|
||||
let span = cx.attr_span;
|
||||
let suggestions = cx.suggestions();
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ pub(super) use rustc_feature::{AttributeTemplate, template};
|
|||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::attrs::AttributeKind;
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::lints::AttributeLintKind;
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::{MethodKind, Target};
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
pub(crate) struct IgnoreParser;
|
||||
|
|
@ -20,20 +22,13 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
|
|||
ArgParser::NoArgs => None,
|
||||
ArgParser::NameValue(name_value) => {
|
||||
let Some(str_value) = name_value.value_as_str() else {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
};
|
||||
Some(str_value)
|
||||
}
|
||||
ArgParser::List(_) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
|
||||
use crate::AttributeParser;
|
||||
|
|
@ -381,7 +382,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
|
||||
/// must be delayed until after HIR is built. This method will take care of the details of
|
||||
/// that.
|
||||
pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
|
||||
pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) {
|
||||
if !matches!(
|
||||
self.stage.should_emit(),
|
||||
ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true }
|
||||
|
|
@ -389,11 +390,12 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
return;
|
||||
}
|
||||
let id = self.target_id;
|
||||
(self.emit_lint)(AttributeLint { id, span, kind: lint });
|
||||
(self.emit_lint)(AttributeLint { lint_id: LintId::of(lint), id, span, kind });
|
||||
}
|
||||
|
||||
pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::UnusedDuplicate {
|
||||
this: unused_span,
|
||||
other: used_span,
|
||||
|
|
@ -409,6 +411,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
unused_span: Span,
|
||||
) {
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::UnusedDuplicate {
|
||||
this: unused_span,
|
||||
other: used_span,
|
||||
|
|
@ -632,14 +635,25 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
|
|||
}
|
||||
|
||||
pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
|
||||
let attr_path = self.attr_path.clone();
|
||||
let attr_path = self.attr_path.clone().to_string();
|
||||
let valid_without_list = self.template.word;
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
|
||||
span,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn warn_ill_formed_attribute_input(&mut self, lint: &'static Lint) {
|
||||
let suggestions = self.suggestions();
|
||||
let span = self.attr_span;
|
||||
self.emit_lint(
|
||||
lint,
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None },
|
||||
span,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn suggestions(&self) -> Vec<String> {
|
||||
let style = match self.parsed_description {
|
||||
// If the outer and inner spans are equal, we are parsing an embedded attribute
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::lints::AttributeLint;
|
||||
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
|
||||
use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage};
|
||||
|
|
@ -115,7 +116,12 @@ impl<'sess> AttributeParser<'sess, Early> {
|
|||
OmitDoc::Skip,
|
||||
std::convert::identity,
|
||||
|lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
sess.psess.buffer_lint(
|
||||
lint.lint_id.lint,
|
||||
lint.span,
|
||||
lint.id,
|
||||
BuiltinLintDiag::AttributeLint(lint.kind),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -183,8 +189,13 @@ impl<'sess> AttributeParser<'sess, Early> {
|
|||
sess,
|
||||
stage: Early { emit_errors },
|
||||
};
|
||||
let mut emit_lint = |lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
let mut emit_lint = |lint: AttributeLint<NodeId>| {
|
||||
sess.psess.buffer_lint(
|
||||
lint.lint_id.lint,
|
||||
lint.span,
|
||||
lint.id,
|
||||
BuiltinLintDiag::AttributeLint(lint.kind),
|
||||
)
|
||||
};
|
||||
if let Some(safety) = attr_safety {
|
||||
parser.check_attribute_safety(
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ mod interface;
|
|||
/// like lists or name-value pairs.
|
||||
pub mod parser;
|
||||
|
||||
mod lints;
|
||||
mod safety;
|
||||
mod session_diagnostics;
|
||||
mod target_checking;
|
||||
|
|
@ -111,7 +110,6 @@ pub use attributes::cfg_select::*;
|
|||
pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version};
|
||||
pub use context::{Early, Late, OmitDoc, ShouldEmit};
|
||||
pub use interface::AttributeParser;
|
||||
pub use lints::emit_attribute_lint;
|
||||
pub use session_diagnostics::ParsedDescription;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
|
|
|||
|
|
@ -1,114 +0,0 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_errors::{DiagArgValue, LintEmitter};
|
||||
use rustc_hir::Target;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::session_diagnostics;
|
||||
|
||||
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emitter: L) {
|
||||
let AttributeLint { id, span, kind } = lint;
|
||||
|
||||
match kind {
|
||||
&AttributeLintKind::UnusedDuplicate { this, other, warning } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::UnusedDuplicate { this, other, warning },
|
||||
),
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::IllFormedAttributeInput {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::IllFormedAttributeInput {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
),
|
||||
},
|
||||
),
|
||||
AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*first_span,
|
||||
session_diagnostics::EmptyAttributeList {
|
||||
attr_span: *first_span,
|
||||
attr_path: attr_path.clone(),
|
||||
valid_without_list: *valid_without_list,
|
||||
},
|
||||
)
|
||||
}
|
||||
AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
// This check is here because `deprecated` had its own lint group and removing this would be a breaking change
|
||||
if name.segments[0].name == sym::deprecated
|
||||
&& ![
|
||||
Target::Closure,
|
||||
Target::Expression,
|
||||
Target::Statement,
|
||||
Target::Arm,
|
||||
Target::MacroCall,
|
||||
]
|
||||
.contains(target)
|
||||
{
|
||||
rustc_session::lint::builtin::USELESS_DEPRECATED
|
||||
} else {
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES
|
||||
},
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::InvalidTargetLint {
|
||||
name: name.clone(),
|
||||
target: target.plural_name(),
|
||||
applied: DiagArgValue::StrListSepByAnd(
|
||||
applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
|
||||
),
|
||||
only,
|
||||
attr_span: *span,
|
||||
},
|
||||
),
|
||||
|
||||
&AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::InvalidAttrStyle {
|
||||
name: name.clone(),
|
||||
is_used_as_inner,
|
||||
target_span: (!is_used_as_inner).then_some(target_span),
|
||||
target,
|
||||
},
|
||||
)
|
||||
}
|
||||
&AttributeLintKind::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span,
|
||||
sugg_spans: (left, right),
|
||||
} => lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::UnsafeAttrOutsideUnsafeLint {
|
||||
span: attribute_name_span,
|
||||
suggestion: session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left, right },
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ use rustc_ast::Safety;
|
|||
use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_session::lint::LintId;
|
||||
use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
use crate::context::Stage;
|
||||
|
|
@ -74,6 +76,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
);
|
||||
} else {
|
||||
emit_lint(AttributeLint {
|
||||
lint_id: LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE),
|
||||
id: target_id,
|
||||
span: path_span,
|
||||
kind: AttributeLintKind::UnsafeAttrOutsideUnsafe {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use rustc_errors::{
|
|||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
||||
};
|
||||
use rustc_feature::AttributeTemplate;
|
||||
use rustc_hir::{AttrPath, Target};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
|
|
@ -417,25 +417,6 @@ pub(crate) struct UnusedMultiple {
|
|||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_unused_duplicate)]
|
||||
pub(crate) struct UnusedDuplicate {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub this: Span,
|
||||
#[note]
|
||||
pub other: Span,
|
||||
#[warning]
|
||||
pub warning: bool,
|
||||
}
|
||||
|
||||
// FIXME(jdonszelmann): duplicated in rustc_lints, should be moved here completely.
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_ill_formed_attribute_input)]
|
||||
pub(crate) struct IllFormedAttributeInput {
|
||||
pub num_suggestions: usize,
|
||||
pub suggestions: DiagArgValue,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_ill_formed_attribute_input)]
|
||||
pub(crate) struct IllFormedAttributeInputLint {
|
||||
|
|
@ -501,29 +482,6 @@ pub(crate) struct EmptyConfusables {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_empty_attribute)]
|
||||
#[note]
|
||||
pub(crate) struct EmptyAttributeList {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub attr_span: Span,
|
||||
pub attr_path: AttrPath,
|
||||
pub valid_without_list: bool,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_invalid_target_lint)]
|
||||
#[warning]
|
||||
#[help]
|
||||
pub(crate) struct InvalidTargetLint {
|
||||
pub name: AttrPath,
|
||||
pub target: &'static str,
|
||||
pub applied: DiagArgValue,
|
||||
pub only: &'static str,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[help]
|
||||
#[diag(attr_parsing_invalid_target)]
|
||||
|
|
@ -803,15 +761,6 @@ pub(crate) struct UnsafeAttrOutsideUnsafe {
|
|||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_unsafe_attr_outside_unsafe)]
|
||||
pub(crate) struct UnsafeAttrOutsideUnsafeLint {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
attr_parsing_unsafe_attr_outside_unsafe_suggestion,
|
||||
|
|
@ -881,16 +830,6 @@ pub(crate) struct SuffixedLiteralInAttribute {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_invalid_style)]
|
||||
pub(crate) struct InvalidAttrStyle {
|
||||
pub name: AttrPath,
|
||||
pub is_used_as_inner: bool,
|
||||
#[note]
|
||||
pub target_span: Option<Span>,
|
||||
pub target: Target,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_empty_link_name, code = E0454)]
|
||||
pub(crate) struct EmptyLinkName {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use rustc_errors::DiagArgValue;
|
|||
use rustc_feature::Features;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_hir::{MethodKind, Target};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::AttributeParser;
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
|
|
@ -102,13 +103,31 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
let allowed_targets = allowed_targets.allowed_targets();
|
||||
let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
|
||||
let name = cx.attr_path.clone();
|
||||
|
||||
let lint = if name.segments[0].name == sym::deprecated
|
||||
&& ![
|
||||
Target::Closure,
|
||||
Target::Expression,
|
||||
Target::Statement,
|
||||
Target::Arm,
|
||||
Target::MacroCall,
|
||||
]
|
||||
.contains(&target)
|
||||
{
|
||||
rustc_session::lint::builtin::USELESS_DEPRECATED
|
||||
} else {
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES
|
||||
};
|
||||
|
||||
let attr_span = cx.attr_span;
|
||||
cx.emit_lint(
|
||||
lint,
|
||||
AttributeLintKind::InvalidTarget {
|
||||
name,
|
||||
target,
|
||||
name: name.to_string(),
|
||||
target: target.plural_name(),
|
||||
only: if only { "only " } else { "" },
|
||||
applied,
|
||||
attr_span,
|
||||
},
|
||||
attr_span,
|
||||
);
|
||||
|
|
@ -145,15 +164,15 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
return;
|
||||
}
|
||||
|
||||
let lint = AttributeLintKind::InvalidStyle {
|
||||
name: cx.attr_path.clone(),
|
||||
let kind = AttributeLintKind::InvalidStyle {
|
||||
name: cx.attr_path.to_string(),
|
||||
is_used_as_inner: cx.attr_style == AttrStyle::Inner,
|
||||
target,
|
||||
target: target.name(),
|
||||
target_span: cx.target_span,
|
||||
};
|
||||
let attr_span = cx.attr_span;
|
||||
|
||||
cx.emit_lint(lint, attr_span);
|
||||
cx.emit_lint(rustc_session::lint::builtin::UNUSED_ATTRIBUTES, kind, attr_span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use rustc_ast::{
|
|||
use rustc_errors::{Applicability, FatalError, PResult};
|
||||
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_parse::parse_in;
|
||||
use rustc_session::errors::report_lit_error;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
|
|
@ -202,10 +203,10 @@ fn emit_malformed_attribute(
|
|||
ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
span,
|
||||
ast::CRATE_NODE_ID,
|
||||
BuiltinLintDiag::IllFormedAttributeInput {
|
||||
BuiltinLintDiag::AttributeLint(AttributeLintKind::IllFormedAttributeInput {
|
||||
suggestions: suggestions.clone(),
|
||||
docs: template.docs,
|
||||
},
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
suggestions.sort();
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ pub use rustc_error_messages::{
|
|||
fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display,
|
||||
};
|
||||
use rustc_hashes::Hash128;
|
||||
use rustc_lint_defs::LintExpectationId;
|
||||
pub use rustc_lint_defs::{Applicability, listify, pluralize};
|
||||
use rustc_lint_defs::{Lint, LintExpectationId};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
pub use rustc_span::ErrorGuaranteed;
|
||||
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
|
||||
|
|
@ -106,20 +106,6 @@ rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
|
|||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
|
||||
|
||||
/// Used to avoid depending on `rustc_middle` in `rustc_attr_parsing`.
|
||||
/// Always the `TyCtxt`.
|
||||
pub trait LintEmitter: Copy {
|
||||
type Id: Copy;
|
||||
#[track_caller]
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
hir_id: Self::Id,
|
||||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()> + DynSend + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
|
||||
pub enum SuggestionStyle {
|
||||
/// Hide the suggested code when displaying this suggestion inline.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ rustc_error_messages = { path = "../rustc_error_messages" }
|
|||
rustc_hashes = { path = "../rustc_hashes" }
|
||||
rustc_hir_id = { path = "../rustc_hir_id" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
pub use rustc_lint_defs::AttributeLintKind;
|
||||
use rustc_lint_defs::LintId;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::{AttrPath, HirId, Target};
|
||||
use crate::HirId;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DelayedLints {
|
||||
|
|
@ -24,46 +26,8 @@ pub enum DelayedLint {
|
|||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub struct AttributeLint<Id> {
|
||||
pub lint_id: LintId,
|
||||
pub id: Id,
|
||||
pub span: Span,
|
||||
pub kind: AttributeLintKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum AttributeLintKind {
|
||||
/// Copy of `IllFormedAttributeInput`
|
||||
/// specifically for the `invalid_macro_export_arguments` lint until that is removed,
|
||||
/// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
|
||||
InvalidMacroExportArguments {
|
||||
suggestions: Vec<String>,
|
||||
},
|
||||
UnusedDuplicate {
|
||||
this: Span,
|
||||
other: Span,
|
||||
warning: bool,
|
||||
},
|
||||
IllFormedAttributeInput {
|
||||
suggestions: Vec<String>,
|
||||
},
|
||||
EmptyAttribute {
|
||||
first_span: Span,
|
||||
attr_path: AttrPath,
|
||||
valid_without_list: bool,
|
||||
},
|
||||
InvalidTarget {
|
||||
name: AttrPath,
|
||||
target: Target,
|
||||
applied: Vec<String>,
|
||||
only: &'static str,
|
||||
},
|
||||
InvalidStyle {
|
||||
name: AttrPath,
|
||||
is_used_as_inner: bool,
|
||||
target: Target,
|
||||
target_span: Span,
|
||||
},
|
||||
UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: Span,
|
||||
sugg_spans: (Span, Span),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ itertools = "0.12"
|
|||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_arena = { path = "../rustc_arena" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
|
|
@ -21,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
|||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_infer = { path = "../rustc_infer" }
|
||||
rustc_lint = { path = "../rustc_lint" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
|
|
|||
|
|
@ -158,7 +158,19 @@ pub fn provide(providers: &mut Providers) {
|
|||
fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
|
||||
match lint {
|
||||
DelayedLint::AttributeParsing(attribute_lint) => {
|
||||
rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx)
|
||||
tcx.node_span_lint(
|
||||
attribute_lint.lint_id.lint,
|
||||
attribute_lint.id,
|
||||
attribute_lint.span,
|
||||
|diag| {
|
||||
rustc_lint::decorate_attribute_lint(
|
||||
tcx.sess,
|
||||
Some(tcx),
|
||||
&attribute_lint.kind,
|
||||
diag,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,6 +245,19 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement
|
|||
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||
.label = argument has type `{$arg_ty}`
|
||||
|
||||
lint_empty_attribute =
|
||||
unused attribute
|
||||
.suggestion = {$valid_without_list ->
|
||||
[true] remove these parentheses
|
||||
*[other] remove this attribute
|
||||
}
|
||||
.note = {$valid_without_list ->
|
||||
[true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
|
||||
*[other] using `{$attr_path}` with an empty list has no effect
|
||||
}
|
||||
|
||||
-lint_previously_accepted =
|
||||
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
lint_enum_intrinsics_mem_discriminant =
|
||||
the return value of `mem::discriminant` is unspecified when called with a non-enum type
|
||||
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum
|
||||
|
|
@ -458,6 +471,17 @@ lint_invalid_reference_casting_note_book = for more information, visit <https://
|
|||
|
||||
lint_invalid_reference_casting_note_ty_has_interior_mutability = even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
|
||||
|
||||
lint_invalid_style = {$is_used_as_inner ->
|
||||
[false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
|
||||
*[other] the `#![{$name}]` attribute can only be used at the crate root
|
||||
}
|
||||
.note = This attribute does not have an `!`, which means it is applied to this {$target}
|
||||
|
||||
lint_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
|
||||
.warn = {-lint_previously_accepted}
|
||||
.help = `#[{$name}]` can {$only}be applied to {$applied}
|
||||
.suggestion = remove the attribute
|
||||
|
||||
lint_lintpass_by_hand = implementing `LintPass` by hand
|
||||
.help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
|
||||
|
|
@ -890,6 +914,10 @@ lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not
|
|||
|
||||
lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::`
|
||||
|
||||
lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
|
||||
.label = usage of unsafe attribute
|
||||
lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
|
||||
|
||||
lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´
|
||||
|
||||
lint_untranslatable_diag = diagnostics should be created using translatable messages
|
||||
|
|
@ -922,6 +950,12 @@ lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
|
|||
lint_unused_delim = unnecessary {$delim} around {$item}
|
||||
.suggestion = remove these {$delim}
|
||||
|
||||
lint_unused_duplicate =
|
||||
unused attribute
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
.warn = {-lint_previously_accepted}
|
||||
|
||||
lint_unused_import_braces = braces around {$node} is unnecessary
|
||||
|
||||
lint_unused_imports = {$num_snippets ->
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
|
|||
use rustc_errors::{
|
||||
Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion,
|
||||
};
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
|
|
@ -301,7 +302,21 @@ pub fn decorate_builtin_lint(
|
|||
BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => {
|
||||
lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag)
|
||||
}
|
||||
BuiltinLintDiag::IllFormedAttributeInput { suggestions, docs } => {
|
||||
BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, diag),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decorate_attribute_lint(
|
||||
_sess: &Session,
|
||||
_tcx: Option<TyCtxt<'_>>,
|
||||
kind: &AttributeLintKind,
|
||||
diag: &mut Diag<'_, ()>,
|
||||
) {
|
||||
match kind {
|
||||
&AttributeLintKind::UnusedDuplicate { this, other, warning } => {
|
||||
lints::UnusedDuplicate { this, other, warning }.decorate_lint(diag)
|
||||
}
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => {
|
||||
lints::IllFormedAttributeInput {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
|
|
@ -312,5 +327,42 @@ pub fn decorate_builtin_lint(
|
|||
}
|
||||
.decorate_lint(diag)
|
||||
}
|
||||
AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
|
||||
lints::EmptyAttributeList {
|
||||
attr_span: *first_span,
|
||||
attr_path: attr_path.clone(),
|
||||
valid_without_list: *valid_without_list,
|
||||
}
|
||||
.decorate_lint(diag)
|
||||
}
|
||||
AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => {
|
||||
lints::InvalidTargetLint {
|
||||
name: name.clone(),
|
||||
target,
|
||||
applied: DiagArgValue::StrListSepByAnd(
|
||||
applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
|
||||
),
|
||||
only,
|
||||
attr_span: *attr_span,
|
||||
}
|
||||
.decorate_lint(diag)
|
||||
}
|
||||
&AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => {
|
||||
lints::InvalidAttrStyle {
|
||||
name: name.clone(),
|
||||
is_used_as_inner,
|
||||
target_span: (!is_used_as_inner).then_some(target_span),
|
||||
target,
|
||||
}
|
||||
.decorate_lint(diag)
|
||||
}
|
||||
&AttributeLintKind::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span,
|
||||
sugg_spans: (left, right),
|
||||
} => lints::UnsafeAttrOutsideUnsafeLint {
|
||||
span: attribute_name_span,
|
||||
suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
|
||||
}
|
||||
.decorate_lint(diag),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ use unused::*;
|
|||
#[rustfmt::skip]
|
||||
pub use builtin::{MissingDoc, SoftLints};
|
||||
pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore};
|
||||
pub use early::diagnostics::decorate_builtin_lint;
|
||||
pub use early::diagnostics::{decorate_attribute_lint, decorate_builtin_lint};
|
||||
pub use early::{EarlyCheckNode, check_ast_node};
|
||||
pub use late::{check_crate, late_lint_mod, unerased_lint_store};
|
||||
pub use levels::LintLevelsBuilder;
|
||||
|
|
|
|||
|
|
@ -3126,3 +3126,68 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_empty_attribute)]
|
||||
#[note]
|
||||
pub(crate) struct EmptyAttributeList {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub attr_span: Span,
|
||||
pub attr_path: String,
|
||||
pub valid_without_list: bool,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_invalid_target)]
|
||||
#[warning]
|
||||
#[help]
|
||||
pub(crate) struct InvalidTargetLint {
|
||||
pub name: String,
|
||||
pub target: &'static str,
|
||||
pub applied: DiagArgValue,
|
||||
pub only: &'static str,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_invalid_style)]
|
||||
pub(crate) struct InvalidAttrStyle {
|
||||
pub name: String,
|
||||
pub is_used_as_inner: bool,
|
||||
#[note]
|
||||
pub target_span: Option<Span>,
|
||||
pub target: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_unused_duplicate)]
|
||||
pub(crate) struct UnusedDuplicate {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub this: Span,
|
||||
#[note]
|
||||
pub other: Span,
|
||||
#[warning]
|
||||
pub warning: bool,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_unsafe_attr_outside_unsafe)]
|
||||
pub(crate) struct UnsafeAttrOutsideUnsafeLint {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
lint_unsafe_attr_outside_unsafe_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
|
||||
#[suggestion_part(code = "unsafe(")]
|
||||
pub left: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub right: Span,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -696,10 +696,42 @@ pub enum BuiltinLintDiag {
|
|||
extern_crate: Symbol,
|
||||
local_crate: Symbol,
|
||||
},
|
||||
AttributeLint(AttributeLintKind),
|
||||
}
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum AttributeLintKind {
|
||||
UnusedDuplicate {
|
||||
this: Span,
|
||||
other: Span,
|
||||
warning: bool,
|
||||
},
|
||||
IllFormedAttributeInput {
|
||||
suggestions: Vec<String>,
|
||||
docs: Option<&'static str>,
|
||||
},
|
||||
EmptyAttribute {
|
||||
first_span: Span,
|
||||
attr_path: String,
|
||||
valid_without_list: bool,
|
||||
},
|
||||
InvalidTarget {
|
||||
name: String,
|
||||
target: &'static str,
|
||||
applied: Vec<String>,
|
||||
only: &'static str,
|
||||
attr_span: Span,
|
||||
},
|
||||
InvalidStyle {
|
||||
name: String,
|
||||
is_used_as_inner: bool,
|
||||
target: &'static str,
|
||||
target_span: Span,
|
||||
},
|
||||
UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: Span,
|
||||
sugg_spans: (Span, Span),
|
||||
},
|
||||
}
|
||||
|
||||
pub type RegisteredTools = FxIndexSet<Ident>;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use rustc_data_structures::sync::{
|
|||
self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
|
||||
};
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
|
||||
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||
|
|
@ -1534,20 +1534,6 @@ pub struct TyCtxt<'tcx> {
|
|||
gcx: &'tcx GlobalCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> LintEmitter for TyCtxt<'tcx> {
|
||||
type Id = HirId;
|
||||
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
self.emit_node_span_lint(lint, hir_id, span, decorator);
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
|
||||
// field are asserted to implement these traits below, so this is trivially safe, and it greatly
|
||||
// speeds-up compilation of this crate and its dependents.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use std::sync::atomic::AtomicBool;
|
|||
use std::{env, io};
|
||||
|
||||
use rand::{RngCore, rng};
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
|
||||
use rustc_data_structures::flock;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
|
|
@ -22,7 +21,7 @@ use rustc_errors::timings::TimingSectionHandler;
|
|||
use rustc_errors::translation::Translator;
|
||||
use rustc_errors::{
|
||||
Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort,
|
||||
LintEmitter, TerminalUrl, fallback_fluent_bundle,
|
||||
TerminalUrl, fallback_fluent_bundle,
|
||||
};
|
||||
use rustc_hir::limit::Limit;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
|
|
@ -160,20 +159,6 @@ pub struct Session {
|
|||
pub invocation_temp: Option<String>,
|
||||
}
|
||||
|
||||
impl LintEmitter for &'_ Session {
|
||||
type Id = NodeId;
|
||||
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static rustc_lint_defs::Lint,
|
||||
node_id: Self::Id,
|
||||
span: impl Into<rustc_errors::MultiSpan>,
|
||||
decorator: impl for<'a> rustc_errors::LintDiagnostic<'a, ()> + DynSend + 'static,
|
||||
) {
|
||||
self.psess.buffer_lint(lint, span, node_id, decorator);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum CodegenUnits {
|
||||
/// Specified by the user. In this case we try fairly hard to produce the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue