diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-11-23 07:05:31 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-11-23 07:05:31 +0000 |
commit | 224387a4de8b780dee0014ba61a6fcad20726f5f (patch) | |
tree | 658935369dc3ce1601a153ad55fd2eec787c4db9 | |
parent | cadf0e9fb630d04367ef2611383865963d84ab54 (diff) | |
parent | 8a11da40a789e5d73c5c11d69ba87638ddff8676 (diff) |
Merge #6606
6606: Parse unsafe extern block r=lnicola a=dtolnay
`unsafe extern` block is parsed successfully by rustc, which means it is usable in attribute macro input.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6f805556f176d082d87255957f16b5f6
```rust
#[cfg(parse)]
unsafe extern "C++" {
fn demo();
}
```
```diff
[email protected]
- [email protected]
+ [email protected]
[email protected]
[email protected] "#"
[email protected] "["
[email protected]
[email protected]
[email protected]
[email protected] "cfg"
[email protected]
[email protected] "("
[email protected] "parse"
[email protected] ")"
[email protected] "]"
[email protected] "\n"
[email protected] "unsafe"
[email protected] " "
[email protected]
[email protected] "extern"
[email protected] " "
[email protected] "\"C++\""
- [email protected] " "
- [email protected]
- [email protected] "{"
- [email protected] "\n "
- [email protected]
- [email protected] "fn"
- [email protected] " "
- [email protected]
- [email protected] "demo"
- [email protected]
- [email protected] "("
- [email protected] ")"
- [email protected] ";"
- [email protected] "\n"
- [email protected] "}"
+ [email protected] " "
+ [email protected]
+ [email protected] "{"
+ [email protected] "\n "
+ [email protected]
+ [email protected] "fn"
+ [email protected] " "
+ [email protected]
+ [email protected] "demo"
+ [email protected]
+ [email protected] "("
+ [email protected] ")"
+ [email protected] ";"
+ [email protected] "\n"
+ [email protected] "}"
```
This is of interest for https://github.com/dtolnay/cxx.
Co-authored-by: David Tolnay <[email protected]>
-rw-r--r-- | crates/parser/src/grammar/items.rs | 10 | ||||
-rw-r--r-- | crates/syntax/test_data/parser/ok/0068_item_modifiers.rast | 16 | ||||
-rw-r--r-- | crates/syntax/test_data/parser/ok/0068_item_modifiers.rs | 2 |
3 files changed, 25 insertions, 3 deletions
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 780bc470a..ad29b82f7 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs | |||
@@ -112,7 +112,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
112 | has_mods = true; | 112 | has_mods = true; |
113 | } | 113 | } |
114 | 114 | ||
115 | if p.at(T![extern]) { | 115 | if p.at(T![extern]) && p.nth(1) != T!['{'] && (p.nth(1) != STRING || p.nth(2) != T!['{']) { |
116 | has_mods = true; | 116 | has_mods = true; |
117 | abi(p); | 117 | abi(p); |
118 | } | 118 | } |
@@ -181,6 +181,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
181 | T![type] => { | 181 | T![type] => { |
182 | type_alias(p, m); | 182 | type_alias(p, m); |
183 | } | 183 | } |
184 | |||
185 | // unsafe extern "C" {} | ||
186 | T![extern] => { | ||
187 | abi(p); | ||
188 | extern_item_list(p); | ||
189 | m.complete(p, EXTERN_BLOCK); | ||
190 | } | ||
191 | |||
184 | _ => { | 192 | _ => { |
185 | if !has_visibility && !has_mods { | 193 | if !has_visibility && !has_mods { |
186 | return Err(m); | 194 | return Err(m); |
diff --git a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast b/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast index 50a6d8ee9..87eebf185 100644 --- a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast +++ b/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast | |||
@@ -1,4 +1,4 @@ | |||
1 | [email protected]04 | 1 | [email protected]28 |
2 | [email protected] | 2 | [email protected] |
3 | [email protected] "async" | 3 | [email protected] "async" |
4 | [email protected] " " | 4 | [email protected] " " |
@@ -215,4 +215,16 @@ [email protected] | |||
215 | [email protected] | 215 | [email protected] |
216 | [email protected] "{" | 216 | [email protected] "{" |
217 | [email protected] "}" | 217 | [email protected] "}" |
218 | [email protected] "\n" | 218 | [email protected] "\n\n" |
219 | [email protected] | ||
220 | [email protected] "unsafe" | ||
221 | [email protected] " " | ||
222 | [email protected] | ||
223 | [email protected] "extern" | ||
224 | [email protected] " " | ||
225 | [email protected] "\"C++\"" | ||
226 | [email protected] " " | ||
227 | [email protected] | ||
228 | [email protected] "{" | ||
229 | [email protected] "}" | ||
230 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs b/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs index 8d697c04b..6d27a082c 100644 --- a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs +++ b/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs | |||
@@ -14,3 +14,5 @@ unsafe auto trait T {} | |||
14 | unsafe impl Foo {} | 14 | unsafe impl Foo {} |
15 | default impl Foo {} | 15 | default impl Foo {} |
16 | unsafe default impl Foo {} | 16 | unsafe default impl Foo {} |
17 | |||
18 | unsafe extern "C++" {} | ||