Skip to content

Commit 6a3556b

Browse files
committed
Auto merge of rust-lang#17195 - Veykril:unsafe-attr, r=Veykril
Implement unsafe attribute parsing
2 parents 48bcef3 + 58d58af commit 6a3556b

File tree

8 files changed

+534
-11
lines changed

8 files changed

+534
-11
lines changed

src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,18 @@ impl Attr {
252252
Some(Attr { id, path, input, ctxt: span.ctx })
253253
}
254254

255-
fn from_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree], id: AttrId) -> Option<Attr> {
256-
let ctxt = tt.first()?.first_span().ctx;
255+
fn from_tt(db: &dyn ExpandDatabase, mut tt: &[tt::TokenTree], id: AttrId) -> Option<Attr> {
256+
if matches!(tt,
257+
[tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text, .. })), ..]
258+
if text == "unsafe"
259+
) {
260+
match tt.get(1) {
261+
Some(tt::TokenTree::Subtree(subtree)) => tt = &subtree.token_trees,
262+
_ => return None,
263+
}
264+
}
265+
let first = &tt.first()?;
266+
let ctxt = first.first_span().ctx;
257267
let path_end = tt
258268
.iter()
259269
.position(|tt| {
@@ -435,7 +445,7 @@ fn inner_attributes(
435445

436446
// Input subtree is: `(cfg, $(attr),+)`
437447
// Split it up into a `cfg` subtree and the `attr` subtrees.
438-
pub fn parse_cfg_attr_input(
448+
fn parse_cfg_attr_input(
439449
subtree: &Subtree,
440450
) -> Option<(&[tt::TokenTree], impl Iterator<Item = &[tt::TokenTree]>)> {
441451
let mut parts = subtree

src/tools/rust-analyzer/crates/ide/src/runnables.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,9 @@ fn main() {}
609609
#[export_name = "main"]
610610
fn __cortex_m_rt_main_trampoline() {}
611611
612+
#[unsafe(export_name = "main")]
613+
fn __cortex_m_rt_main_trampoline_unsafe() {}
614+
612615
#[test]
613616
fn test_foo() {}
614617
@@ -628,13 +631,14 @@ mod not_a_root {
628631
"#,
629632
expect![[r#"
630633
[
631-
"(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..253, name: \"\", kind: Module })",
634+
"(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..331, name: \"\", kind: Module })",
632635
"(Bin, NavigationTarget { file_id: FileId(0), full_range: 1..13, focus_range: 4..8, name: \"main\", kind: Function })",
633636
"(Bin, NavigationTarget { file_id: FileId(0), full_range: 15..76, focus_range: 42..71, name: \"__cortex_m_rt_main_trampoline\", kind: Function })",
634-
"(Test, NavigationTarget { file_id: FileId(0), full_range: 78..102, focus_range: 89..97, name: \"test_foo\", kind: Function })",
635-
"(Test, NavigationTarget { file_id: FileId(0), full_range: 104..155, focus_range: 136..150, name: \"test_full_path\", kind: Function })",
636-
"(Test, NavigationTarget { file_id: FileId(0), full_range: 157..191, focus_range: 178..186, name: \"test_foo\", kind: Function })",
637-
"(Bench, NavigationTarget { file_id: FileId(0), full_range: 193..215, focus_range: 205..210, name: \"bench\", kind: Function })",
637+
"(Bin, NavigationTarget { file_id: FileId(0), full_range: 78..154, focus_range: 113..149, name: \"__cortex_m_rt_main_trampoline_unsafe\", kind: Function })",
638+
"(Test, NavigationTarget { file_id: FileId(0), full_range: 156..180, focus_range: 167..175, name: \"test_foo\", kind: Function })",
639+
"(Test, NavigationTarget { file_id: FileId(0), full_range: 182..233, focus_range: 214..228, name: \"test_full_path\", kind: Function })",
640+
"(Test, NavigationTarget { file_id: FileId(0), full_range: 235..269, focus_range: 256..264, name: \"test_foo\", kind: Function })",
641+
"(Bench, NavigationTarget { file_id: FileId(0), full_range: 271..293, focus_range: 283..288, name: \"bench\", kind: Function })",
638642
]
639643
"#]],
640644
);

src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,33 @@ fn attr(p: &mut Parser<'_>, inner: bool) {
3636
attr.complete(p, ATTR);
3737
}
3838

39+
// test metas
40+
// #![simple_ident]
41+
// #![simple::path]
42+
// #![simple_ident_expr = ""]
43+
// #![simple::path::Expr = ""]
44+
// #![simple_ident_tt(a b c)]
45+
// #![simple_ident_tt[a b c]]
46+
// #![simple_ident_tt{a b c}]
47+
// #![simple::path::tt(a b c)]
48+
// #![simple::path::tt[a b c]]
49+
// #![simple::path::tt{a b c}]
50+
// #![unsafe(simple_ident)]
51+
// #![unsafe(simple::path)]
52+
// #![unsafe(simple_ident_expr = "")]
53+
// #![unsafe(simple::path::Expr = "")]
54+
// #![unsafe(simple_ident_tt(a b c))]
55+
// #![unsafe(simple_ident_tt[a b c])]
56+
// #![unsafe(simple_ident_tt{a b c})]
57+
// #![unsafe(simple::path::tt(a b c))]
58+
// #![unsafe(simple::path::tt[a b c])]
59+
// #![unsafe(simple::path::tt{a b c})]
3960
pub(super) fn meta(p: &mut Parser<'_>) {
4061
let meta = p.start();
62+
let is_unsafe = p.eat(T![unsafe]);
63+
if is_unsafe {
64+
p.expect(T!['(']);
65+
}
4166
paths::use_path(p);
4267

4368
match p.current() {
@@ -50,6 +75,9 @@ pub(super) fn meta(p: &mut Parser<'_>) {
5075
T!['('] | T!['['] | T!['{'] => items::token_tree(p),
5176
_ => {}
5277
}
78+
if is_unsafe {
79+
p.expect(T![')']);
80+
}
5381

5482
meta.complete(p, META);
5583
}

0 commit comments

Comments
 (0)