diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-06-07 20:14:28 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-07 20:14:28 +0200 |
| commit | 6e534c73c35f569492ed5fb5f349075d58ed8b7e (patch) | |
| tree | db013e765334eeeee9ac1f98c05131cf91371a47 /compiler/rustc_passes/src | |
| parent | 0acb5b8513e727ebb4f63d8d8ee8cfa285342a89 (diff) | |
| parent | f9104f0dfb531581aa96b19b333835351a566b04 (diff) | |
| download | rust-6e534c73c35f569492ed5fb5f349075d58ed8b7e.tar.gz rust-6e534c73c35f569492ed5fb5f349075d58ed8b7e.zip | |
Rollup merge of #124214 - carbotaniuman:parse_unsafe_attrs, r=michaelwoerister
Parse unsafe attributes Initial parse implementation for #123757 This is the initial work to parse unsafe attributes, which is represented as an extra `unsafety` field in `MetaItem` and `AttrItem`. There's two areas in the code where it appears that parsing is done manually and not using the parser stuff, and I'm not sure how I'm supposed to thread the change there.
Diffstat (limited to 'compiler/rustc_passes/src')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 11 |
2 files changed, 30 insertions, 2 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 39cb48c1af3..6ce7c41acc8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,7 +10,9 @@ use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::StashKey; use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan}; -use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{ + is_unsafe_attr, AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP, +}; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir}; @@ -114,6 +116,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut seen = FxHashMap::default(); let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { + self.check_unsafe_attr(attr); + match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend] => { self.check_do_not_recommend(attr.span, hir_id, target) @@ -308,6 +312,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> { true } + /// Checks if `unsafe()` is applied to an invalid attribute. + fn check_unsafe_attr(&self, attr: &Attribute) { + if !attr.is_doc_comment() { + let attr_item = attr.get_normal_item(); + if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety { + if !is_unsafe_attr(attr.name_or_empty()) { + self.dcx().emit_err(errors::InvalidAttrUnsafe { + span: unsafe_span, + name: attr_item.path.clone(), + }); + } + } + } + } + /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition fn check_diagnostic_on_unimplemented( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7fdd9924b51..a935f1ad7d3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::fluent_generated as fluent; -use rustc_ast::Label; +use rustc_ast::{ast, Label}; use rustc_errors::{ codes::*, Applicability, Diag, DiagCtxt, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic, @@ -863,6 +863,15 @@ pub struct InvalidAttrAtCrateLevel { pub item: Option<ItemFollowingInnerAttr>, } +#[derive(Diagnostic)] +#[diag(passes_invalid_attr_unsafe)] +#[note] +pub struct InvalidAttrUnsafe { + #[primary_span] + pub span: Span, + pub name: ast::Path, +} + #[derive(Clone, Copy)] pub struct ItemFollowingInnerAttr { pub span: Span, |
