mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Rollup merge of #99712 - davidtwco:translation-migrate-passes-2, r=compiler-errors
passes: port more of `check_attr` module Continues from #99213. Port more diagnostics in `rustc_passes::check_attr` to using the diagnostic derive and translation machinery. r? `@compiler-errors`
This commit is contained in:
commit
fe51d07b99
@ -149,3 +149,110 @@ passes-cold = {passes-should-be-applied-to-fn}
|
||||
passes-link = attribute should be applied to an `extern` block with non-Rust ABI
|
||||
.warn = {-passes-previously-accepted}
|
||||
.label = not an `extern` block
|
||||
|
||||
passes-link-name = attribute should be applied to a foreign function or static
|
||||
.warn = {-passes-previously-accepted}
|
||||
.label = not a foreign function or static
|
||||
.help = try `#[link(name = "{$value}")]` instead
|
||||
|
||||
passes-no-link = attribute should be applied to an `extern crate` item
|
||||
.label = not an `extern crate` item
|
||||
|
||||
passes-export-name = attribute should be applied to a free function, impl method or static
|
||||
.label = not a free function, impl method or static
|
||||
|
||||
passes-rustc-layout-scalar-valid-range-not-struct = attribute should be applied to a struct
|
||||
.label = not a struct
|
||||
|
||||
passes-rustc-layout-scalar-valid-range-arg = expected exactly one integer literal argument
|
||||
|
||||
passes-rustc-legacy-const-generics-only = #[rustc_legacy_const_generics] functions must only have const generics
|
||||
.label = non-const generic parameter
|
||||
|
||||
passes-rustc-legacy-const-generics-index = #[rustc_legacy_const_generics] must have one index for each generic parameter
|
||||
.label = generic parameters
|
||||
|
||||
passes-rustc-legacy-const-generics-index-exceed = index exceeds number of arguments
|
||||
.label = there {$arg_count ->
|
||||
[one] is
|
||||
*[other] are
|
||||
} only {$arg_count} {$arg_count ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}
|
||||
|
||||
passes-rustc-legacy-const-generics-index-negative = arguments should be non-negative integers
|
||||
|
||||
passes-rustc-dirty-clean = attribute requires -Z query-dep-graph to be enabled
|
||||
|
||||
passes-link-section = attribute should be applied to a function or static
|
||||
.warn = {-passes-previously-accepted}
|
||||
.label = not a function or static
|
||||
|
||||
passes-no-mangle-foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
|
||||
.warn = {-passes-previously-accepted}
|
||||
.label = foreign {$foreign_item_kind}
|
||||
.note = symbol names in extern blocks are not mangled
|
||||
.suggestion = remove this attribute
|
||||
|
||||
passes-no-mangle = attribute should be applied to a free function, impl method or static
|
||||
.warn = {-passes-previously-accepted}
|
||||
.label = not a free function, impl method or static
|
||||
|
||||
passes-repr-ident = meta item in `repr` must be an identifier
|
||||
|
||||
passes-repr-conflicting = conflicting representation hints
|
||||
|
||||
passes-used-static = attribute must be applied to a `static` variable
|
||||
|
||||
passes-used-compiler-linker = `used(compiler)` and `used(linker)` can't be used together
|
||||
|
||||
passes-allow-internal-unstable = attribute should be applied to a macro
|
||||
.label = not a macro
|
||||
|
||||
passes-debug-visualizer-placement = attribute should be applied to a module
|
||||
|
||||
passes-debug-visualizer-invalid = invalid argument
|
||||
.note-1 = expected: `natvis_file = "..."`
|
||||
.note-2 = OR
|
||||
.note-3 = expected: `gdb_script_file = "..."`
|
||||
|
||||
passes-rustc-allow-const-fn-unstable = attribute should be applied to `const fn`
|
||||
.label = not a `const fn`
|
||||
|
||||
passes-rustc-std-internal-symbol = attribute should be applied to functions or statics
|
||||
.label = not a function or static
|
||||
|
||||
passes-const-trait = attribute should be applied to a trait
|
||||
|
||||
passes-stability-promotable = attribute cannot be applied to an expression
|
||||
|
||||
passes-deprecated = attribute is ignored here
|
||||
|
||||
passes-macro-use = `#[{$name}]` only has an effect on `extern crate` and modules
|
||||
|
||||
passes-macro-export = `#[macro_export]` only has an effect on macro definitions
|
||||
|
||||
passes-plugin-registrar = `#[plugin_registrar]` only has an effect on functions
|
||||
|
||||
passes-unused-empty-lints-note = attribute `{$name}` with an empty list has no effect
|
||||
|
||||
passes-unused-no-lints-note = attribute `{$name}` without any lints has no effect
|
||||
|
||||
passes-unused-default-method-body-const-note =
|
||||
`default_method_body_is_const` has been replaced with `#[const_trait]` on traits
|
||||
|
||||
passes-unused = unused attribute
|
||||
.suggestion = remove this attribute
|
||||
|
||||
passes-non-exported-macro-invalid-attrs = attribute should be applied to function or closure
|
||||
.label = not a function or closure
|
||||
|
||||
passes-unused-duplicate = unused attribute
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
.warn = {-passes-previously-accepted}
|
||||
|
||||
passes-unused-multiple = multiple `{$name}` attributes
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
|
@ -7,7 +7,7 @@
|
||||
use crate::errors;
|
||||
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{fluent, pluralize, struct_span_err, Applicability, MultiSpan};
|
||||
use rustc_errors::{fluent, struct_span_err, Applicability, MultiSpan};
|
||||
use rustc_expand::base::resolve_path;
|
||||
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_hir as hir;
|
||||
@ -1180,30 +1180,22 @@ impl CheckAttrVisitor<'_> {
|
||||
_ => {
|
||||
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
|
||||
// used this, so only emit a warning.
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
let mut diag =
|
||||
lint.build("attribute should be applied to a foreign function or static");
|
||||
diag.warn(
|
||||
"this was previously accepted by the compiler but is \
|
||||
being phased out; it will become a hard error in \
|
||||
a future release!",
|
||||
let attr_span = matches!(target, Target::ForeignMod).then_some(attr.span);
|
||||
if let Some(s) = attr.value_str() {
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::LinkName { span, attr_span, value: s.as_str() },
|
||||
);
|
||||
|
||||
// See issue #47725
|
||||
if let Target::ForeignMod = target {
|
||||
if let Some(value) = attr.value_str() {
|
||||
diag.span_help(
|
||||
attr.span,
|
||||
&format!(r#"try `#[link(name = "{value}")]` instead"#),
|
||||
);
|
||||
} else {
|
||||
diag.span_help(attr.span, r#"try `#[link(name = "...")]` instead"#);
|
||||
}
|
||||
}
|
||||
|
||||
diag.span_label(span, "not a foreign function or static");
|
||||
diag.emit();
|
||||
});
|
||||
} else {
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::LinkName { span, attr_span, value: "..." },
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1221,14 +1213,7 @@ impl CheckAttrVisitor<'_> {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"attribute should be applied to an `extern crate` item",
|
||||
)
|
||||
.span_label(span, "not an `extern crate` item")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::NoLink { attr_span: attr.span, span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1258,14 +1243,7 @@ impl CheckAttrVisitor<'_> {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"attribute should be applied to a free function, impl method or static",
|
||||
)
|
||||
.span_label(span, "not a free function, impl method or static")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::ExportName { attr_span: attr.span, span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1278,11 +1256,10 @@ impl CheckAttrVisitor<'_> {
|
||||
target: Target,
|
||||
) -> bool {
|
||||
if target != Target::Struct {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a struct")
|
||||
.span_label(span, "not a struct")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeNotStruct {
|
||||
attr_span: attr.span,
|
||||
span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1293,10 +1270,7 @@ impl CheckAttrVisitor<'_> {
|
||||
if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) {
|
||||
true
|
||||
} else {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "expected exactly one integer literal argument")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1311,11 +1285,10 @@ impl CheckAttrVisitor<'_> {
|
||||
) -> bool {
|
||||
let is_function = matches!(target, Target::Fn);
|
||||
if !is_function {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a function")
|
||||
.span_label(span, "not a function")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
attr_span: attr.span,
|
||||
defn_span: span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1335,29 +1308,20 @@ impl CheckAttrVisitor<'_> {
|
||||
match param.kind {
|
||||
hir::GenericParamKind::Const { .. } => {}
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"#[rustc_legacy_const_generics] functions must \
|
||||
only have const generics",
|
||||
)
|
||||
.span_label(param.span, "non-const generic parameter")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLegacyConstGenericsOnly {
|
||||
attr_span: attr.span,
|
||||
param_span: param.span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if list.len() != generics.params.len() {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"#[rustc_legacy_const_generics] must have one index for each generic parameter",
|
||||
)
|
||||
.span_label(generics.span, "generic parameters")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLegacyConstGenericsIndex {
|
||||
attr_span: attr.span,
|
||||
generics_span: generics.span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1367,19 +1331,10 @@ impl CheckAttrVisitor<'_> {
|
||||
if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
|
||||
if *val >= arg_count {
|
||||
let span = meta.span();
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(span, "index exceeds number of arguments")
|
||||
.span_label(
|
||||
span,
|
||||
format!(
|
||||
"there {} only {} argument{}",
|
||||
pluralize!("is", arg_count),
|
||||
arg_count,
|
||||
pluralize!(arg_count)
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLegacyConstGenericsIndexExceed {
|
||||
span,
|
||||
arg_count: arg_count as usize,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -1388,10 +1343,7 @@ impl CheckAttrVisitor<'_> {
|
||||
}
|
||||
|
||||
if !invalid_args.is_empty() {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(invalid_args, "arguments should be non-negative integers")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args });
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -1403,11 +1355,10 @@ impl CheckAttrVisitor<'_> {
|
||||
fn check_applied_to_fn_or_method(&self, attr: &Attribute, span: Span, target: Target) -> bool {
|
||||
let is_function = matches!(target, Target::Fn | Target::Method(..));
|
||||
if !is_function {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a function")
|
||||
.span_label(span, "not a function")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
attr_span: attr.span,
|
||||
defn_span: span,
|
||||
});
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -1437,10 +1388,7 @@ impl CheckAttrVisitor<'_> {
|
||||
if self.tcx.sess.opts.unstable_opts.query_dep_graph {
|
||||
true
|
||||
} else {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute requires -Z query-dep-graph to be enabled")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::RustcDirtyClean { span: attr.span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1459,16 +1407,12 @@ impl CheckAttrVisitor<'_> {
|
||||
_ => {
|
||||
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
|
||||
// crates used this, so only emit a warning.
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("attribute should be applied to a function or static")
|
||||
.warn(
|
||||
"this was previously accepted by the compiler but is \
|
||||
being phased out; it will become a hard error in \
|
||||
a future release!",
|
||||
)
|
||||
.span_label(span, "not a function or static")
|
||||
.emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::LinkSection { span },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1494,41 +1438,22 @@ impl CheckAttrVisitor<'_> {
|
||||
Target::ForeignStatic => "static",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build(&format!(
|
||||
"`#[no_mangle]` has no effect on a foreign {foreign_item_kind}"
|
||||
))
|
||||
.warn(
|
||||
"this was previously accepted by the compiler but is \
|
||||
being phased out; it will become a hard error in \
|
||||
a future release!",
|
||||
)
|
||||
.span_label(span, format!("foreign {foreign_item_kind}"))
|
||||
.note("symbol names in extern blocks are not mangled")
|
||||
.span_suggestion(
|
||||
attr.span,
|
||||
"remove this attribute",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::NoMangleForeign { span, attr_span: attr.span, foreign_item_kind },
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
|
||||
// crates used this, so only emit a warning.
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build(
|
||||
"attribute should be applied to a free function, impl method or static",
|
||||
)
|
||||
.warn(
|
||||
"this was previously accepted by the compiler but is \
|
||||
being phased out; it will become a hard error in \
|
||||
a future release!",
|
||||
)
|
||||
.span_label(span, "not a free function, impl method or static")
|
||||
.emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::NoMangle { span },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1561,13 +1486,7 @@ impl CheckAttrVisitor<'_> {
|
||||
|
||||
for hint in &hints {
|
||||
if !hint.is_meta_item() {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
hint.span(),
|
||||
E0565,
|
||||
"meta item in `repr` must be an identifier"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::ReprIdent { span: hint.span() });
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1688,15 +1607,11 @@ impl CheckAttrVisitor<'_> {
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
self.tcx.struct_span_lint_hir(
|
||||
self.tcx.emit_spanned_lint(
|
||||
CONFLICTING_REPR_HINTS,
|
||||
hir_id,
|
||||
hint_spans.collect::<Vec<Span>>(),
|
||||
|lint| {
|
||||
lint.build("conflicting representation hints")
|
||||
.code(rustc_errors::error_code!(E0566))
|
||||
.emit();
|
||||
},
|
||||
errors::ReprConflicting,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1706,9 +1621,7 @@ impl CheckAttrVisitor<'_> {
|
||||
let mut used_compiler_span = None;
|
||||
for attr in attrs.iter().filter(|attr| attr.has_name(sym::used)) {
|
||||
if target != Target::Static {
|
||||
self.tcx
|
||||
.sess
|
||||
.span_err(attr.span, "attribute must be applied to a `static` variable");
|
||||
self.tcx.sess.emit_err(errors::UsedStatic { span: attr.span });
|
||||
}
|
||||
let inner = attr.meta_item_list();
|
||||
match inner.as_deref() {
|
||||
@ -1734,14 +1647,9 @@ impl CheckAttrVisitor<'_> {
|
||||
}
|
||||
}
|
||||
if let (Some(linker_span), Some(compiler_span)) = (used_linker_span, used_compiler_span) {
|
||||
let spans = vec![linker_span, compiler_span];
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
spans,
|
||||
"`used(compiler)` and `used(linker)` can't be used together",
|
||||
)
|
||||
.emit();
|
||||
.emit_err(errors::UsedCompilerLinker { spans: vec![linker_span, compiler_span] });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1783,9 +1691,7 @@ impl CheckAttrVisitor<'_> {
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a macro")
|
||||
.span_label(span, "not a macro")
|
||||
.emit();
|
||||
.emit_err(errors::AllowInternalUnstable { attr_span: attr.span, span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1796,29 +1702,26 @@ impl CheckAttrVisitor<'_> {
|
||||
match target {
|
||||
Target::Mod => {}
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a module")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::DebugVisualizerPlacement { span: attr.span });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let Some(hints) = attr.meta_item_list() else {
|
||||
self.emit_debugger_visualizer_err(attr.span);
|
||||
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
|
||||
return false;
|
||||
};
|
||||
|
||||
let hint = match hints.len() {
|
||||
1 => &hints[0],
|
||||
_ => {
|
||||
self.emit_debugger_visualizer_err(attr.span);
|
||||
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let Some(meta_item) = hint.meta_item() else {
|
||||
self.emit_debugger_visualizer_err(attr.span);
|
||||
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
|
||||
return false;
|
||||
};
|
||||
|
||||
@ -1826,7 +1729,7 @@ impl CheckAttrVisitor<'_> {
|
||||
(sym::natvis_file, Some(value)) => value,
|
||||
(sym::gdb_script_file, Some(value)) => value,
|
||||
(_, _) => {
|
||||
self.emit_debugger_visualizer_err(meta_item.span);
|
||||
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: meta_item.span });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@ -1855,16 +1758,6 @@ impl CheckAttrVisitor<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_debugger_visualizer_err(&self, span: Span) {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(span, "invalid argument")
|
||||
.note(r#"expected: `natvis_file = "..."`"#)
|
||||
.note(r#"OR"#)
|
||||
.note(r#"expected: `gdb_script_file = "..."`"#)
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
|
||||
/// (Allows proc_macro functions)
|
||||
fn check_rustc_allow_const_fn_unstable(
|
||||
@ -1891,9 +1784,7 @@ impl CheckAttrVisitor<'_> {
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to `const fn`")
|
||||
.span_label(span, "not a `const fn`")
|
||||
.emit();
|
||||
.emit_err(errors::RustcAllowConstFnUnstable { attr_span: attr.span, span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1910,9 +1801,7 @@ impl CheckAttrVisitor<'_> {
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied functions or statics")
|
||||
.span_label(span, "not a function or static")
|
||||
.emit();
|
||||
.emit_err(errors::RustcStdInternalSymbol { attr_span: attr.span, span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1923,10 +1812,7 @@ impl CheckAttrVisitor<'_> {
|
||||
match target {
|
||||
Target::Trait => true,
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute should be applied to a trait")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::ConstTrait { attr_span: attr.span });
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -1935,10 +1821,7 @@ impl CheckAttrVisitor<'_> {
|
||||
fn check_stability_promotable(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
|
||||
match target {
|
||||
Target::Expression => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(attr.span, "attribute cannot be applied to an expression")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::StabilityPromotable { attr_span: attr.span });
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
@ -1948,9 +1831,12 @@ impl CheckAttrVisitor<'_> {
|
||||
fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) {
|
||||
match target {
|
||||
Target::Closure | Target::Expression | Target::Statement | Target::Arm => {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("attribute is ignored here").emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::Deprecated,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -1961,29 +1847,30 @@ impl CheckAttrVisitor<'_> {
|
||||
match target {
|
||||
Target::ExternCrate | Target::Mod => {}
|
||||
_ => {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build(&format!(
|
||||
"`#[{name}]` only has an effect on `extern crate` and modules"
|
||||
))
|
||||
.emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::MacroUse { name },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
if target != Target::MacroDef {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("`#[macro_export]` only has an effect on macro definitions").emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_plugin_registrar(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
if target != Target::Fn {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("`#[plugin_registrar]` only has an effect on functions").emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::PluginRegistrar,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2002,10 +1889,7 @@ impl CheckAttrVisitor<'_> {
|
||||
| sym::target_feature
|
||||
) && attr.meta_item_list().map_or(false, |list| list.is_empty())
|
||||
{
|
||||
format!(
|
||||
"attribute `{}` with an empty list has no effect",
|
||||
attr.name_or_empty()
|
||||
)
|
||||
errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
|
||||
} else if matches!(
|
||||
attr.name_or_empty(),
|
||||
sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
|
||||
@ -2015,27 +1899,19 @@ impl CheckAttrVisitor<'_> {
|
||||
&& let MetaItemKind::NameValue(_) = &item.kind
|
||||
&& item.path == sym::reason
|
||||
{
|
||||
format!(
|
||||
"attribute `{}` without any lints has no effect",
|
||||
attr.name_or_empty()
|
||||
)
|
||||
errors::UnusedNote::NoLints { name: attr.name_or_empty() }
|
||||
} else if attr.name_or_empty() == sym::default_method_body_is_const {
|
||||
format!("`default_method_body_is_const` has been replaced with `#[const_trait]` on traits")
|
||||
errors::UnusedNote::DefaultMethodBodyConst
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("unused attribute")
|
||||
.span_suggestion(
|
||||
attr.span,
|
||||
"remove this attribute",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.note(¬e)
|
||||
.emit();
|
||||
});
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span,
|
||||
errors::Unused { attr_span: attr.span, note },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2206,14 +2082,7 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>)
|
||||
|
||||
for attr in attrs {
|
||||
if attr.has_name(sym::inline) {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
attr.span,
|
||||
E0518,
|
||||
"attribute should be applied to function or closure",
|
||||
)
|
||||
.span_label(attr.span, "not a function or closure")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::NonExportedMacroInvalidAttrs { attr_span: attr.span });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2253,23 +2122,20 @@ fn check_duplicates(
|
||||
} else {
|
||||
(attr.span, *entry.get())
|
||||
};
|
||||
tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, this, |lint| {
|
||||
let mut db = lint.build("unused attribute");
|
||||
db.span_note(other, "attribute also specified here").span_suggestion(
|
||||
tcx.emit_spanned_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
this,
|
||||
errors::UnusedDuplicate {
|
||||
this,
|
||||
"remove this attribute",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
if matches!(duplicates, FutureWarnFollowing | FutureWarnPreceding) {
|
||||
db.warn(
|
||||
"this was previously accepted by the compiler but is \
|
||||
being phased out; it will become a hard error in \
|
||||
a future release!",
|
||||
);
|
||||
}
|
||||
db.emit();
|
||||
});
|
||||
other,
|
||||
warning: matches!(
|
||||
duplicates,
|
||||
FutureWarnFollowing | FutureWarnPreceding
|
||||
)
|
||||
.then_some(()),
|
||||
},
|
||||
);
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(attr.span);
|
||||
@ -2284,19 +2150,11 @@ fn check_duplicates(
|
||||
} else {
|
||||
(attr.span, *entry.get())
|
||||
};
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
this,
|
||||
&format!("multiple `{}` attributes", attr.name_or_empty()),
|
||||
)
|
||||
.span_note(other, "attribute also specified here")
|
||||
.span_suggestion(
|
||||
this,
|
||||
"remove this attribute",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::UnusedMultiple {
|
||||
this,
|
||||
other,
|
||||
name: attr.name_or_empty(),
|
||||
});
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(attr.span);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_errors::{Applicability, MultiSpan};
|
||||
use rustc_macros::{LintDiagnostic, SessionDiagnostic};
|
||||
use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
@ -360,3 +360,268 @@ pub struct Link {
|
||||
#[label]
|
||||
pub span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::link_name)]
|
||||
#[warn_]
|
||||
pub struct LinkName<'a> {
|
||||
#[help]
|
||||
pub attr_span: Option<Span>,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub value: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::no_link)]
|
||||
pub struct NoLink {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::export_name)]
|
||||
pub struct ExportName {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_layout_scalar_valid_range_not_struct)]
|
||||
pub struct RustcLayoutScalarValidRangeNotStruct {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_layout_scalar_valid_range_arg)]
|
||||
pub struct RustcLayoutScalarValidRangeArg {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_legacy_const_generics_only)]
|
||||
pub struct RustcLegacyConstGenericsOnly {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub param_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_legacy_const_generics_index)]
|
||||
pub struct RustcLegacyConstGenericsIndex {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub generics_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_legacy_const_generics_index_exceed)]
|
||||
pub struct RustcLegacyConstGenericsIndexExceed {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub arg_count: usize,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_legacy_const_generics_index_negative)]
|
||||
pub struct RustcLegacyConstGenericsIndexNegative {
|
||||
#[primary_span]
|
||||
pub invalid_args: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_dirty_clean)]
|
||||
pub struct RustcDirtyClean {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::link_section)]
|
||||
#[warn_]
|
||||
pub struct LinkSection {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::no_mangle_foreign)]
|
||||
#[warn_]
|
||||
#[note]
|
||||
pub struct NoMangleForeign {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[suggestion(applicability = "machine-applicable")]
|
||||
pub attr_span: Span,
|
||||
pub foreign_item_kind: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::no_mangle)]
|
||||
#[warn_]
|
||||
pub struct NoMangle {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::repr_ident, code = "E0565")]
|
||||
pub struct ReprIdent {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::repr_conflicting, code = "E0566")]
|
||||
pub struct ReprConflicting;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::used_static)]
|
||||
pub struct UsedStatic {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::used_compiler_linker)]
|
||||
pub struct UsedCompilerLinker {
|
||||
#[primary_span]
|
||||
pub spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::allow_internal_unstable)]
|
||||
pub struct AllowInternalUnstable {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::debug_visualizer_placement)]
|
||||
pub struct DebugVisualizerPlacement {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::debug_visualizer_invalid)]
|
||||
#[note(passes::note_1)]
|
||||
#[note(passes::note_2)]
|
||||
#[note(passes::note_3)]
|
||||
pub struct DebugVisualizerInvalid {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_allow_const_fn_unstable)]
|
||||
pub struct RustcAllowConstFnUnstable {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::rustc_std_internal_symbol)]
|
||||
pub struct RustcStdInternalSymbol {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::const_trait)]
|
||||
pub struct ConstTrait {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::stability_promotable)]
|
||||
pub struct StabilityPromotable {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::deprecated)]
|
||||
pub struct Deprecated;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::macro_use)]
|
||||
pub struct MacroUse {
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::macro_export)]
|
||||
pub struct MacroExport;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::plugin_registrar)]
|
||||
pub struct PluginRegistrar;
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub enum UnusedNote {
|
||||
#[note(passes::unused_empty_lints_note)]
|
||||
EmptyList { name: Symbol },
|
||||
#[note(passes::unused_no_lints_note)]
|
||||
NoLints { name: Symbol },
|
||||
#[note(passes::unused_default_method_body_const_note)]
|
||||
DefaultMethodBodyConst,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::unused)]
|
||||
pub struct Unused {
|
||||
#[suggestion(applicability = "machine-applicable")]
|
||||
pub attr_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub note: UnusedNote,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::non_exported_macro_invalid_attrs, code = "E0518")]
|
||||
pub struct NonExportedMacroInvalidAttrs {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[lint(passes::unused_duplicate)]
|
||||
pub struct UnusedDuplicate {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub this: Span,
|
||||
#[note]
|
||||
pub other: Span,
|
||||
#[warn_]
|
||||
pub warning: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(passes::unused_multiple)]
|
||||
pub struct UnusedMultiple {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub this: Span,
|
||||
#[note]
|
||||
pub other: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ error: malformed `rustc_lint_diagnostics` attribute input
|
||||
LL | #[rustc_lint_diagnostics(a)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]`
|
||||
|
||||
error: attribute should be applied to a function
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/diagnostics_incorrect.rs:5:1
|
||||
|
|
||||
LL | #[rustc_lint_diagnostics]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct Foo;
|
||||
| ----------- not a function
|
||||
| ----------- not a function definition
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,14 +4,14 @@ error: malformed `rustc_lint_query_instability` attribute input
|
||||
LL | #[rustc_lint_query_instability(a)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]`
|
||||
|
||||
error: attribute should be applied to a function
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/query_stability_incorrect.rs:5:1
|
||||
|
|
||||
LL | #[rustc_lint_query_instability]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct Foo;
|
||||
| ----------- not a function
|
||||
| ----------- not a function definition
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -50,13 +50,13 @@ error: arguments should be non-negative integers
|
||||
LL | #[rustc_legacy_const_generics(1, a, 2, b)]
|
||||
| ^ ^
|
||||
|
||||
error: attribute should be applied to a function
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:18:1
|
||||
|
|
||||
LL | #[rustc_legacy_const_generics(0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | struct S;
|
||||
| --------- not a function
|
||||
| --------- not a function definition
|
||||
|
||||
error: #[rustc_legacy_const_generics] functions must only have const generics
|
||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1
|
||||
@ -66,21 +66,21 @@ LL | #[rustc_legacy_const_generics(0)]
|
||||
LL | fn foo8<X>() {}
|
||||
| - non-const generic parameter
|
||||
|
||||
error: attribute should be applied to a function
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:5
|
||||
|
|
||||
LL | #[rustc_legacy_const_generics(0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | fn foo9<const X: usize>() {}
|
||||
| ---------------------------- not a function
|
||||
| ---------------------------- not a function definition
|
||||
|
||||
error: attribute should be applied to a function
|
||||
error: attribute should be applied to a function definition
|
||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5
|
||||
|
|
||||
LL | #[rustc_legacy_const_generics(1)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | fn foo7<const X: usize>();
|
||||
| -------------------------- not a function
|
||||
| -------------------------- not a function definition
|
||||
|
||||
error[E0044]: foreign items may not have const parameters
|
||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5
|
||||
|
Loading…
Reference in New Issue
Block a user