Skip to content

Commit a45af00

Browse files
committed
Parse unsafe attributes
1 parent e011ba7 commit a45af00

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

src/attr.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ pub(crate) mod parsing {
653653
use crate::parse::{Parse, ParseStream};
654654
use crate::path::Path;
655655
use crate::{mac, token};
656+
use proc_macro2::Ident;
656657
use std::fmt::{self, Display};
657658

658659
pub(crate) fn parse_inner(input: ParseStream, attrs: &mut Vec<Attribute>) -> Result<()> {
@@ -685,27 +686,38 @@ pub(crate) mod parsing {
685686
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
686687
impl Parse for Meta {
687688
fn parse(input: ParseStream) -> Result<Self> {
688-
let path = input.call(Path::parse_mod_style)?;
689+
let path = parse_outermost_meta_path(input)?;
689690
parse_meta_after_path(path, input)
690691
}
691692
}
692693

693694
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
694695
impl Parse for MetaList {
695696
fn parse(input: ParseStream) -> Result<Self> {
696-
let path = input.call(Path::parse_mod_style)?;
697+
let path = parse_outermost_meta_path(input)?;
697698
parse_meta_list_after_path(path, input)
698699
}
699700
}
700701

701702
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
702703
impl Parse for MetaNameValue {
703704
fn parse(input: ParseStream) -> Result<Self> {
704-
let path = input.call(Path::parse_mod_style)?;
705+
let path = parse_outermost_meta_path(input)?;
705706
parse_meta_name_value_after_path(path, input)
706707
}
707708
}
708709

710+
// Unlike meta::parse_meta_path which accepts arbitrary keywords in the path,
711+
// only the `unsafe` keyword is accepted as an attribute's outermost path.
712+
fn parse_outermost_meta_path(input: ParseStream) -> Result<Path> {
713+
if input.peek(Token![unsafe]) {
714+
let unsafe_token: Token![unsafe] = input.parse()?;
715+
Ok(Path::from(Ident::new("unsafe", unsafe_token.span)))
716+
} else {
717+
Path::parse_mod_style(input)
718+
}
719+
}
720+
709721
pub(crate) fn parse_meta_after_path(path: Path, input: ParseStream) -> Result<Meta> {
710722
if input.peek(token::Paren) || input.peek(token::Bracket) || input.peek(token::Brace) {
711723
parse_meta_list_after_path(path, input).map(Meta::List)

tests/repo/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@ static EXCLUDE_FILES: &[&str] = &[
2525
"tests/rustdoc/unsafe-extern-blocks.rs",
2626
"tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs",
2727

28-
// TODO: unsafe attributes: `#[unsafe(path::to)]`
29-
// https://github.com/dtolnay/syn/issues/1710
30-
"src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0213_metas.rs",
31-
"src/tools/rustfmt/tests/target/unsafe_attributes.rs",
32-
"tests/ui/attributes/unsafe/unsafe-attributes.rs",
33-
"tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs",
34-
3528
// TODO: non-lifetime binders: `where for<'a, T> &'a Struct<T>: Trait`
3629
// https://github.com/dtolnay/syn/issues/1435
3730
"src/tools/rustfmt/tests/source/issue_5721.rs",

0 commit comments

Comments
 (0)