about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-07 20:14:28 +0200
committerGitHub <noreply@github.com>2024-06-07 20:14:28 +0200
commit6e534c73c35f569492ed5fb5f349075d58ed8b7e (patch)
treedb013e765334eeeee9ac1f98c05131cf91371a47 /compiler/rustc_passes/src
parent0acb5b8513e727ebb4f63d8d8ee8cfa285342a89 (diff)
parentf9104f0dfb531581aa96b19b333835351a566b04 (diff)
downloadrust-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.rs21
-rw-r--r--compiler/rustc_passes/src/errors.rs11
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,