summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes/src/check_attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes/src/check_attr.rs')
-rw-r--r--compiler/rustc_passes/src/check_attr.rs82
1 files changed, 73 insertions, 9 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a2ac329f2..b3f15ba7c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -16,6 +16,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID};
use rustc_hir::{MethodKind, Target};
use rustc_middle::hir::nested_filter;
+use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
@@ -130,6 +131,7 @@ impl CheckAttrVisitor<'_> {
| sym::rustc_if_this_changed
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
+ sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
sym::const_trait => self.check_const_trait(attr, span, target),
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
sym::must_use => self.check_must_use(hir_id, &attr, span, target),
@@ -146,6 +148,7 @@ impl CheckAttrVisitor<'_> {
| sym::stable
| sym::rustc_allowed_through_unstable_modules
| sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
+ sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
_ => true,
};
is_valid &= attr_is_valid;
@@ -171,6 +174,7 @@ impl CheckAttrVisitor<'_> {
sym::no_implicit_prelude => {
self.check_generic_attr(hir_id, attr, target, &[Target::Mod])
}
+ sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id),
_ => {}
}
@@ -209,7 +213,14 @@ impl CheckAttrVisitor<'_> {
}
// FIXME(@lcnr): this doesn't belong here.
- if matches!(target, Target::Closure | Target::Fn | Target::Method(_) | Target::ForeignFn) {
+ if matches!(
+ target,
+ Target::Closure
+ | Target::Fn
+ | Target::Method(_)
+ | Target::ForeignFn
+ | Target::ForeignStatic
+ ) {
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
}
@@ -402,6 +413,38 @@ impl CheckAttrVisitor<'_> {
}
}
+ /// Debugging aid for `object_lifetime_default` query.
+ fn check_object_lifetime_default(&self, hir_id: HirId) {
+ let tcx = self.tcx;
+ if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) {
+ for p in generics.params {
+ let hir::GenericParamKind::Type { .. } = p.kind else { continue };
+ let param_id = tcx.hir().local_def_id(p.hir_id);
+ let default = tcx.object_lifetime_default(param_id);
+ let repr = match default {
+ ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
+ ObjectLifetimeDefault::Static => "'static".to_owned(),
+ ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
+ ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
+ };
+ tcx.sess.span_err(p.span, &repr);
+ }
+ }
+ }
+
+ /// Checks if `#[collapse_debuginfo]` is applied to a macro.
+ fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) -> bool {
+ match target {
+ Target::MacroDef => true,
+ _ => {
+ self.tcx
+ .sess
+ .emit_err(errors::CollapseDebuginfo { attr_span: attr.span, defn_span: span });
+ false
+ }
+ }
+ }
+
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
fn check_track_caller(
&self,
@@ -632,6 +675,7 @@ impl CheckAttrVisitor<'_> {
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
+ | Target::ImplTraitPlaceholder
| Target::Enum
| Target::Variant
| Target::Struct
@@ -644,7 +688,9 @@ impl CheckAttrVisitor<'_> {
| Target::ForeignStatic
| Target::ForeignTy
| Target::GenericParam(..)
- | Target::MacroDef => None,
+ | Target::MacroDef
+ | Target::PatField
+ | Target::ExprField => None,
} {
tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return false;
@@ -1620,6 +1666,8 @@ impl CheckAttrVisitor<'_> {
E0552,
"unrecognized representation hint"
)
+ .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, \
+ `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`")
.emit();
continue;
@@ -1886,6 +1934,16 @@ impl CheckAttrVisitor<'_> {
}
}
+ fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
+ match target {
+ Target::ForeignFn | Target::ForeignStatic => true,
+ _ => {
+ self.tcx.sess.emit_err(errors::LinkOrdinal { attr_span: attr.span });
+ false
+ }
+ }
+ }
+
fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) {
match target {
Target::Closure | Target::Expression | Target::Statement | Target::Arm => {
@@ -2048,14 +2106,14 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_expr(self, expr)
}
- fn visit_variant(
- &mut self,
- variant: &'tcx hir::Variant<'tcx>,
- generics: &'tcx hir::Generics<'tcx>,
- item_id: HirId,
- ) {
+ fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::ExprField, None);
+ intravisit::walk_expr_field(self, field)
+ }
+
+ fn visit_variant(&mut self, variant: &'tcx hir::Variant<'tcx>) {
self.check_attributes(variant.id, variant.span, Target::Variant, None);
- intravisit::walk_variant(self, variant, generics, item_id)
+ intravisit::walk_variant(self, variant)
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
@@ -2063,6 +2121,11 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_param(self, param);
}
+
+ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::PatField, None);
+ intravisit::walk_pat_field(self, field);
+ }
}
fn is_c_like_enum(item: &Item<'_>) -> bool {
@@ -2092,6 +2155,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
sym::automatically_derived,
sym::start,
sym::rustc_main,
+ sym::unix_sigpipe,
sym::derive,
sym::test,
sym::test_case,