convert entire codebase to parsed inline attrs
This commit is contained in:
@@ -10,7 +10,7 @@ use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc_abi::{Align, ExternAbi, Size};
|
||||
use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast};
|
||||
use rustc_attr_data_structures::{AttributeKind, ReprAttr, find_attr};
|
||||
use rustc_attr_data_structures::{AttributeKind, InlineAttr, ReprAttr, find_attr};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
|
||||
use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
|
||||
@@ -124,6 +124,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
AttributeKind::Stability { span, .. }
|
||||
| AttributeKind::ConstStability { span, .. },
|
||||
) => self.check_stability_promotable(*span, target),
|
||||
Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
|
||||
self.check_inline(hir_id, *attr_span, span, kind, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self
|
||||
.check_allow_internal_unstable(
|
||||
hir_id,
|
||||
@@ -158,7 +161,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
[sym::diagnostic, sym::on_unimplemented, ..] => {
|
||||
self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target)
|
||||
}
|
||||
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
|
||||
[sym::coverage, ..] => self.check_coverage(attr, span, target),
|
||||
[sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
|
||||
[sym::no_sanitize, ..] => {
|
||||
@@ -367,11 +369,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
self.check_rustc_force_inline(hir_id, attrs, span, target);
|
||||
}
|
||||
|
||||
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
|
||||
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::IgnoredAttrWithMacro { sym },
|
||||
);
|
||||
}
|
||||
@@ -431,7 +433,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
}
|
||||
|
||||
/// Checks if an `#[inline]` is applied to a function or a closure.
|
||||
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
|
||||
fn check_inline(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr_span: Span,
|
||||
defn_span: Span,
|
||||
kind: &InlineAttr,
|
||||
target: Target,
|
||||
) {
|
||||
match target {
|
||||
Target::Fn
|
||||
| Target::Closure
|
||||
@@ -440,7 +449,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::IgnoredInlineAttrFnProto,
|
||||
)
|
||||
}
|
||||
@@ -451,25 +460,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
Target::AssocConst => self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::IgnoredInlineAttrConstants,
|
||||
),
|
||||
// FIXME(#80564): Same for fields, arms, and macro defs
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline")
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "inline")
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::InlineNotFnOrClosure {
|
||||
attr_span: attr.span(),
|
||||
defn_span: span,
|
||||
});
|
||||
self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span });
|
||||
}
|
||||
}
|
||||
|
||||
// `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
|
||||
if let Some(did) = hir_id.as_owner()
|
||||
&& self.tcx.def_kind(did).has_codegen_attrs()
|
||||
&& !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never))
|
||||
&& kind != &InlineAttr::Never
|
||||
{
|
||||
let attrs = self.tcx.codegen_fn_attrs(did);
|
||||
// Not checking naked as `#[inline]` is forbidden for naked functions anyways.
|
||||
@@ -477,7 +483,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::InlineIgnoredForExported {},
|
||||
);
|
||||
}
|
||||
@@ -711,6 +717,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
|
||||
// `#[naked]` attribute with just a lint, because we previously
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "naked")
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
attr_span: attr.span(),
|
||||
@@ -787,7 +800,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
for attr in attrs {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "track_caller");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@@ -830,7 +843,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "non_exhaustive");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::NonExhaustiveWrongLocation {
|
||||
@@ -850,7 +863,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "marker");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait {
|
||||
@@ -904,7 +917,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "target_feature");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
@@ -1619,7 +1632,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "cold");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "cold");
|
||||
}
|
||||
_ => {
|
||||
// FIXME: #[cold] was previously allowed on non-functions and some crates used
|
||||
@@ -1661,7 +1674,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_name");
|
||||
}
|
||||
_ => {
|
||||
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
|
||||
@@ -1695,7 +1708,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span });
|
||||
@@ -1717,7 +1730,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "export_name");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::ExportName { attr_span: attr.span(), span });
|
||||
@@ -1891,7 +1904,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_section");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_section");
|
||||
}
|
||||
_ => {
|
||||
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
|
||||
@@ -1916,7 +1929,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
|
||||
}
|
||||
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
|
||||
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
|
||||
@@ -2263,9 +2276,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable")
|
||||
}
|
||||
Target::Field | Target::Arm | Target::MacroDef => self
|
||||
.inline_attr_str_error_with_macro_def(
|
||||
hir_id,
|
||||
attr.span(),
|
||||
"allow_internal_unstable",
|
||||
),
|
||||
_ => {
|
||||
self.tcx
|
||||
.dcx()
|
||||
@@ -2638,8 +2654,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
span: Span,
|
||||
target: Target,
|
||||
) {
|
||||
let force_inline_attr = attrs.iter().find(|attr| attr.has_name(sym::rustc_force_inline));
|
||||
match (target, force_inline_attr) {
|
||||
match (
|
||||
target,
|
||||
find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span),
|
||||
) {
|
||||
(Target::Closure, None) => {
|
||||
let is_coro = matches!(
|
||||
self.tcx.hir_expect_expr(hir_id).kind,
|
||||
@@ -2651,20 +2669,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
);
|
||||
let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
|
||||
let parent_span = self.tcx.def_span(parent_did);
|
||||
let parent_force_inline_attr =
|
||||
self.tcx.get_attr(parent_did, sym::rustc_force_inline);
|
||||
if let Some(attr) = parent_force_inline_attr
|
||||
&& is_coro
|
||||
|
||||
if let Some(attr_span) = find_attr!(
|
||||
self.tcx.get_all_attrs(parent_did),
|
||||
AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
|
||||
) && is_coro
|
||||
{
|
||||
self.dcx().emit_err(errors::RustcForceInlineCoro {
|
||||
attr_span: attr.span(),
|
||||
span: parent_span,
|
||||
});
|
||||
self.dcx()
|
||||
.emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
|
||||
}
|
||||
}
|
||||
(Target::Fn, _) => (),
|
||||
(_, Some(attr)) => {
|
||||
self.dcx().emit_err(errors::RustcForceInline { attr_span: attr.span(), span });
|
||||
(_, Some(attr_span)) => {
|
||||
self.dcx().emit_err(errors::RustcForceInline { attr_span, span });
|
||||
}
|
||||
(_, None) => (),
|
||||
}
|
||||
@@ -2885,10 +2902,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
||||
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
|
||||
let attrs = tcx.hir_attrs(item.hir_id());
|
||||
|
||||
for attr in attrs {
|
||||
if attr.has_name(sym::inline) {
|
||||
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span: attr.span() });
|
||||
}
|
||||
if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline(_, span) => *span) {
|
||||
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2908,6 +2923,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { check_mod_attrs, ..*providers };
|
||||
}
|
||||
|
||||
// FIXME(jdonszelmann): remove, check during parsing
|
||||
fn check_duplicates(
|
||||
tcx: TyCtxt<'_>,
|
||||
attr: &Attribute,
|
||||
|
||||
Reference in New Issue
Block a user