about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/attr.rs
diff options
context:
space:
mode:
authorcarbotaniuman <41451839+carbotaniuman@users.noreply.github.com>2024-04-20 23:54:50 -0500
committercarbotaniuman <41451839+carbotaniuman@users.noreply.github.com>2024-06-06 20:26:27 -0500
commit67f5dd1ef112c8a87bc3353793cf4c1cece10c2d (patch)
treeafbeed6330ff7adea5d84a5ecf17dc3d1d3601b8 /compiler/rustc_parse/src/parser/attr.rs
parent76e7a0849c07d73e4d9afde8036ee8c450127cc8 (diff)
downloadrust-67f5dd1ef112c8a87bc3353793cf4c1cece10c2d.tar.gz
rust-67f5dd1ef112c8a87bc3353793cf4c1cece10c2d.zip
Parse unsafe attributes
Diffstat (limited to 'compiler/rustc_parse/src/parser/attr.rs')
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs35
1 files changed, 32 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 4acc610d8c4..2dd19f6c20a 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -7,7 +7,7 @@ use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter};
 use rustc_errors::{codes::*, Diag, PResult};
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{sym, symbol::kw, BytePos, Span};
 use thin_vec::ThinVec;
 use tracing::debug;
 
@@ -252,9 +252,23 @@ impl<'a> Parser<'a> {
         maybe_whole!(self, NtMeta, |attr| attr.into_inner());
 
         let do_parse = |this: &mut Self| {
+            let is_unsafe = this.eat_keyword(kw::Unsafe);
+            let unsafety = if is_unsafe {
+                let unsafe_span = this.prev_token.span;
+                this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+                this.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+
+                ast::Unsafe::Yes(unsafe_span)
+            } else {
+                ast::Unsafe::No
+            };
+
             let path = this.parse_path(PathStyle::Mod)?;
             let args = this.parse_attr_args()?;
-            Ok(ast::AttrItem { path, args, tokens: None })
+            if is_unsafe {
+                this.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
+            }
+            Ok(ast::AttrItem { unsafety, path, args, tokens: None })
         };
         // Attr items don't have attributes
         if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }
@@ -375,10 +389,25 @@ impl<'a> Parser<'a> {
         }
 
         let lo = self.token.span;
+        let is_unsafe = self.eat_keyword(kw::Unsafe);
+        let unsafety = if is_unsafe {
+            let unsafe_span = self.prev_token.span;
+            self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+            self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+
+            ast::Unsafe::Yes(unsafe_span)
+        } else {
+            ast::Unsafe::No
+        };
+
         let path = self.parse_path(PathStyle::Mod)?;
         let kind = self.parse_meta_item_kind()?;
+        if is_unsafe {
+            self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
+        }
         let span = lo.to(self.prev_token.span);
-        Ok(ast::MetaItem { path, kind, span })
+
+        Ok(ast::MetaItem { unsafety, path, kind, span })
     }
 
     pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {