1
Fork 0

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.
This commit is contained in:
Matthias Krüger 2024-06-07 20:14:28 +02:00 committed by GitHub
commit 6e534c73c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 357 additions and 34 deletions

View file

@ -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::Safety::Unsafe(unsafe_span)
} else {
ast::Safety::Default
};
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::Safety::Unsafe(unsafe_span)
} else {
ast::Safety::Default
};
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> {

View file

@ -42,6 +42,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> {
let item = attr.get_normal_item();
Ok(MetaItem {
unsafety: item.unsafety,
span: attr.span,
path: item.path.clone(),
kind: match &item.args {