Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntactically permit unsafety on mods #75857

Merged
merged 1 commit into from
Sep 10, 2020
Merged

Syntactically permit unsafety on mods #75857

merged 1 commit into from
Sep 10, 2020

Conversation

dtolnay
Copy link
Member

@dtolnay dtolnay commented Aug 23, 2020

Similar to #66183; we will accept these constructs syntactically but reject with a semantic check after macro expansion if a proc macro hasn't replaced it with something else meaningful to Rust.

#[mymacro]
unsafe mod m {
    ...
}

#[mymacro]
unsafe extern "C++" {
    ...
}

The intention is that this might be used as a kind of "item-level unsafe" in attribute macro DSLs -- holding things which are unsafe to declare but potentially safe to use. For example I look forward to using this in https://github.com/dtolnay/cxx.

In the absence of a procedural macro rewriting them to something else, they'll continue to be rejected at compile time though with a better error message than before.

Before:

error: expected item, found keyword `unsafe`
 --> src/main.rs:1:1
  |
1 | unsafe mod m {
  | ^^^^^^ expected item

After:

error: module cannot be declared unsafe
 --> src/main.rs:1:1
  |
1 | unsafe mod m {
  | ^^^^^^

error: extern block cannot be declared unsafe
 --> src/main.rs:4:1
  |
4 | unsafe extern "C++" {
  | ^^^^^^

Closes #68048.

@dtolnay dtolnay added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Aug 23, 2020
@rust-highfive
Copy link
Collaborator

r? @ecstatic-morse

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 23, 2020
@dtolnay
Copy link
Member Author

dtolnay commented Aug 23, 2020

r? @joshtriplett, since this is related to our discussion from yesterday.

@nagisa
Copy link
Member

nagisa commented Aug 25, 2020

Nicer error messages!

I wonder why rustfmt/hir lowering avoided being changed at all. Other than that this LGTM!

also cc @petrochenkov

@dtolnay
Copy link
Member Author

dtolnay commented Aug 25, 2020

@nagisa:

I wonder why rustfmt/hir lowering avoided being changed at all.

@nagisa
Copy link
Member

nagisa commented Aug 25, 2020

never makes it to HIR.

What I expected to see is a change to exhaustive match somewhere in HIR lowering, but looks like that goes through the visitor system.

@dtolnay
Copy link
Member Author

dtolnay commented Aug 25, 2020

Seems like that happens here and here. There isn't an exhaustive match, we just avoid accessing the new unsafety fields of Mod and ForeignMod.

@dtolnay dtolnay added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Aug 27, 2020
@dtolnay dtolnay requested a review from estebank August 27, 2020 18:07
@dtolnay
Copy link
Member Author

dtolnay commented Aug 27, 2020

I'll leave assigned to @joshtriplett for the lang FCP but request review from @estebank on the implementation.

@bors

This comment has been minimized.

@dtolnay
Copy link
Member Author

dtolnay commented Aug 30, 2020

@bors

This comment has been minimized.

@dtolnay
Copy link
Member Author

dtolnay commented Sep 2, 2020

@bors
Copy link
Contributor

bors commented Sep 10, 2020

☔ The latest upstream changes (presumably #76291) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@nagisa
Copy link
Member

nagisa commented Sep 10, 2020

I’m just going to call this r=me.

I don’t see any problems with the implementation or the idea behind it. The diagnostic improvements are nice and there are no semantic changes to the language, so its all benefits.

@nagisa
Copy link
Member

nagisa commented Sep 10, 2020

r? @nagisa

@rust-highfive rust-highfive assigned nagisa and unassigned joshtriplett Sep 10, 2020
@nagisa
Copy link
Member

nagisa commented Sep 10, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Sep 10, 2020

📌 Commit fd4dd00 has been approved by nagisa

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 10, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 10, 2020
Rollup of 11 pull requests

Successful merges:

 - rust-lang#75857 (Syntactically permit unsafety on mods)
 - rust-lang#76289 (Add docs about crate level documentation support)
 - rust-lang#76514 (Add revisions to const generic issue UI tests.)
 - rust-lang#76524 (typeck: don't suggest inaccessible private fields)
 - rust-lang#76548 (Validate removal of AscribeUserType, FakeRead, and Shallow borrow)
 - rust-lang#76555 (Reword `trivial_casts` lint in rustc book to better explain what it does.)
 - rust-lang#76559 (add the `const_evaluatable_checked` feature)
 - rust-lang#76563 (small typo fix in rustc_parse docs)
 - rust-lang#76565 (take reference to Place directly instead of taking reference to Box<Place>)
 - rust-lang#76567 (use push(char) to add chars (single-char &strs) to strings instead of push_str(&str))
 - rust-lang#76568 (Add missing examples on core traits' method)

Failed merges:

r? `@ghost`
@bors bors merged commit 5aed495 into rust-lang:master Sep 10, 2020
@rustbot rustbot added this to the 1.48.0 milestone Sep 10, 2020
@dtolnay dtolnay deleted the unsafe branch September 15, 2020 01:46
wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request Nov 24, 2020
Clean up some of the pkgsrc Makefile, there's still lots in here that
should just be deleted though.  Switch SunOS to the illumos bootstrap
by default.

Version 1.48.0 (2020-11-19)
==========================

Language
--------

- [The `unsafe` keyword is now syntactically permitted on modules.][75857] This
  is still rejected *semantically*, but can now be parsed by procedural macros.

Compiler
--------
- [Stabilised the `-C link-self-contained=<yes|no>` compiler flag.][76158] This tells
  `rustc` whether to link its own C runtime and libraries or to rely on a external
  linker to find them. (Supported only on `windows-gnu`, `linux-musl`, and `wasi` platforms.)
- [You can now use `-C target-feature=+crt-static` on `linux-gnu` targets.][77386]
  Note: If you're using cargo you must explicitly pass the `--target` flag.
- [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420]

\* Refer to Rust's [platform support page][forge-platform-support] for more
information on Rust's tiered platform support.

Libraries
---------
- [`io::Write` is now implemented for `&ChildStdin` `&Sink`, `&Stdout`,
  and `&Stderr`.][76275]
- [All arrays of any length now implement `TryFrom<Vec<T>>`.][76310]
- [The `matches!` macro now supports having a trailing comma.][74880]
- [`Vec<A>` now implements `PartialEq<[B]>` where `A: PartialEq<B>`.][74194]
- [The `RefCell::{replace, replace_with, clone}` methods now all use `#[track_caller]`.][77055]

Stabilized APIs
---------------
- [`slice::as_ptr_range`]
- [`slice::as_mut_ptr_range`]
- [`VecDeque::make_contiguous`]
- [`future::pending`]
- [`future::ready`]

The following previously stable methods are now `const fn`'s:

- [`Option::is_some`]
- [`Option::is_none`]
- [`Option::as_ref`]
- [`Result::is_ok`]
- [`Result::is_err`]
- [`Result::as_ref`]
- [`Ordering::reverse`]
- [`Ordering::then`]

Cargo
-----

Rustdoc
-------
- [You can now link to items in `rustdoc` using the intra-doc link
  syntax.][74430] E.g. ``/// Uses [`std::future`]`` will automatically generate
  a link to `std::future`'s documentation. See ["Linking to items by
  name"][intradoc-links] for more information.
- [You can now specify `#[doc(alias = "<alias>")]` on items to add search aliases
  when searching through `rustdoc`'s UI.][75740]

Compatibility Notes
-------------------
- [Promotion of references to `'static` lifetime inside `const fn` now follows the
  same rules as inside a `fn` body.][75502] In particular, `&foo()` will not be
  promoted to `'static` lifetime any more inside `const fn`s.
- [Associated type bindings on trait objects are now verified to meet the bounds
  declared on the trait when checking that they implement the trait.][27675]
- [When trait bounds on associated types or opaque types are ambiguous, the
  compiler no longer makes an arbitrary choice on which bound to use.][54121]
- [Fixed recursive nonterminals not being expanded in macros during
  pretty-print/reparse check.][77153] This may cause errors if your macro wasn't
  correctly handling recursive nonterminal tokens.
- [`&mut` references to non zero-sized types are no longer promoted.][75585]
- [`rustc` will now warn if you use attributes like `#[link_name]` or `#[cold]`
  in places where they have no effect.][73461]
- [Updated `_mm256_extract_epi8` and `_mm256_extract_epi16` signatures in
  `arch::{x86, x86_64}` to return `i32` to match the vendor signatures.][73166]
- [`mem::uninitialized` will now panic if any inner types inside a struct or enum
  disallow zero-initialization.][71274]
- [`#[target_feature]` will now error if used in a place where it has no effect.][78143]
- [Foreign exceptions are now caught by `catch_unwind` and will cause an abort.][70212]
  Note: This behaviour is not guaranteed and is still considered undefined behaviour,
  see the [`catch_unwind`] documentation for further information.

Internal Only
-------------
These changes provide no direct user facing benefits, but represent significant
improvements to the internals and overall performance of rustc and
related tools.
- [Building `rustc` from source now uses `ninja` by default over `make`.][74922]
  You can continue building with `make` by setting `ninja=false` in
  your `config.toml`.
- [cg_llvm: `fewer_names` in `uncached_llvm_type`][76030]
- [Made `ensure_sufficient_stack()` non-generic][76680]

[78143]: rust-lang/rust#78143
[76680]: rust-lang/rust#76680
[76030]: rust-lang/rust#76030
[70212]: rust-lang/rust#70212
[27675]: rust-lang/rust#27675
[54121]: rust-lang/rust#54121
[71274]: rust-lang/rust#71274
[77386]: rust-lang/rust#77386
[77153]: rust-lang/rust#77153
[77055]: rust-lang/rust#77055
[76275]: rust-lang/rust#76275
[76310]: rust-lang/rust#76310
[76420]: rust-lang/rust#76420
[76158]: rust-lang/rust#76158
[75857]: rust-lang/rust#75857
[75585]: rust-lang/rust#75585
[75740]: rust-lang/rust#75740
[75502]: rust-lang/rust#75502
[74880]: rust-lang/rust#74880
[74922]: rust-lang/rust#74922
[74430]: rust-lang/rust#74430
[74194]: rust-lang/rust#74194
[73461]: rust-lang/rust#73461
[73166]: rust-lang/rust#73166
[intradoc-links]: https://doc.rust-lang.org/rustdoc/linking-to-items-by-name.html
[`catch_unwind`]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
[`Option::is_some`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_some
[`Option::is_none`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_none
[`Option::as_ref`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_ref
[`Result::is_ok`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok
[`Result::is_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err
[`Result::as_ref`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.as_ref
[`Ordering::reverse`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.reverse
[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then
[`slice::as_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr_range
[`slice::as_mut_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr_range
[`VecDeque::make_contiguous`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.make_contiguous
[`future::pending`]: https://doc.rust-lang.org/std/future/fn.pending.html
[`future::ready`]: https://doc.rust-lang.org/std/future/fn.ready.html
adetaylor added a commit to adetaylor/syn that referenced this pull request Dec 5, 2020
adetaylor added a commit to adetaylor/syn that referenced this pull request Dec 5, 2020
This too was added in Rust 1.48 by
rust-lang/rust#75857
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jan 1, 2021
Pkgsrc changes:
 * Compensate for files being moved around upstream.
 * Introduce optional, on-by-default semi-static building of cargo,
   using the internal curl and openssl sources.  This reduces the dynamic
   dependencies of cargo and therefore the rust package itself.
   Ref. options.mk.
 * The 1.47.0 bootstrap kits have been re-built with the above option
   turned on, so no longer depends on curl or openssl from pkgsrc and/or
   from earlier OS or pkgsrc versions.  This should hopefully fix
   installation of rust with non-default PREFIX, ref. PR#54453.


Upstream changes:

Version 1.48.0 (2020-11-19)
==========================

Language
--------
- [The `unsafe` keyword is now syntactically permitted on modules.][75857] This
  is still rejected *semantically*, but can now be parsed by procedural macros.

Compiler
--------
- [Stabilised the `-C link-self-contained=<yes|no>` compiler flag.][76158]
  This tells `rustc` whether to link its own C runtime and libraries
  or to rely on a external linker to find them. (Supported only on
  `windows-gnu`, `linux-musl`, and `wasi` platforms.)
- [You can now use `-C target-feature=+crt-static` on `linux-gnu` targets.]
  [77386]
  Note: If you're using cargo you must explicitly pass the `--target` flag.
- [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420]

\* Refer to Rust's [platform support page][forge-platform-support] for more
information on Rust's tiered platform support.

Libraries
---------
- [`io::Write` is now implemented for `&ChildStdin` `&Sink`, `&Stdout`,
  and `&Stderr`.][76275]
- [All arrays of any length now implement `TryFrom<Vec<T>>`.][76310]
- [The `matches!` macro now supports having a trailing comma.][74880]
- [`Vec<A>` now implements `PartialEq<[B]>` where `A: PartialEq<B>`.][74194]
- [The `RefCell::{replace, replace_with, clone}` methods now all use
  `#[track_caller]`.][77055]

Stabilized APIs
---------------
- [`slice::as_ptr_range`]
- [`slice::as_mut_ptr_range`]
- [`VecDeque::make_contiguous`]
- [`future::pending`]
- [`future::ready`]

The following previously stable methods are now `const fn`'s:

- [`Option::is_some`]
- [`Option::is_none`]
- [`Option::as_ref`]
- [`Result::is_ok`]
- [`Result::is_err`]
- [`Result::as_ref`]
- [`Ordering::reverse`]
- [`Ordering::then`]

Cargo
-----

Rustdoc
-------
- [You can now link to items in `rustdoc` using the intra-doc link
  syntax.][74430] E.g. ``/// Uses [`std::future`]`` will automatically generate
  a link to `std::future`'s documentation. See ["Linking to items by
  name"][intradoc-links] for more information.
- [You can now specify `#[doc(alias = "<alias>")]` on items to add
  search aliases when searching through `rustdoc`'s UI.][75740]

Compatibility Notes
-------------------
- [Promotion of references to `'static` lifetime inside `const fn`
  now follows the same rules as inside a `fn` body.][75502] In
  particular, `&foo()` will not be promoted to `'static` lifetime
  any more inside `const fn`s.
- [Associated type bindings on trait objects are now verified to meet the bounds
  declared on the trait when checking that they implement the trait.][27675]
- [When trait bounds on associated types or opaque types are ambiguous, the
  compiler no longer makes an arbitrary choice on which bound to use.][54121]
- [Fixed recursive nonterminals not being expanded in macros during
  pretty-print/reparse check.][77153] This may cause errors if your macro wasn't
  correctly handling recursive nonterminal tokens.
- [`&mut` references to non zero-sized types are no longer promoted.][75585]
- [`rustc` will now warn if you use attributes like `#[link_name]` or `#[cold]`
  in places where they have no effect.][73461]
- [Updated `_mm256_extract_epi8` and `_mm256_extract_epi16` signatures in
  `arch::{x86, x86_64}` to return `i32` to match the vendor signatures.][73166]
- [`mem::uninitialized` will now panic if any inner types inside
  a struct or enum disallow zero-initialization.][71274]
- [`#[target_feature]` will now error if used in a place where it
  has no effect.][78143]
- [Foreign exceptions are now caught by `catch_unwind` and will
  cause an abort.][70212] Note: This behaviour is not guaranteed
  and is still considered undefined behaviour, see the [`catch_unwind`]
  documentation for further information.

Internal Only
-------------
These changes provide no direct user facing benefits, but represent significant
improvements to the internals and overall performance of rustc and
related tools.

- [Building `rustc` from source now uses `ninja` by default over `make`.][74922]
  You can continue building with `make` by setting `ninja=false` in
  your `config.toml`.
- [cg_llvm: `fewer_names` in `uncached_llvm_type`][76030]
- [Made `ensure_sufficient_stack()` non-generic][76680]

[78143]: rust-lang/rust#78143
[76680]: rust-lang/rust#76680
[76030]: rust-lang/rust#76030
[70212]: rust-lang/rust#70212
[27675]: rust-lang/rust#27675
[54121]: rust-lang/rust#54121
[71274]: rust-lang/rust#71274
[77386]: rust-lang/rust#77386
[77153]: rust-lang/rust#77153
[77055]: rust-lang/rust#77055
[76275]: rust-lang/rust#76275
[76310]: rust-lang/rust#76310
[76420]: rust-lang/rust#76420
[76158]: rust-lang/rust#76158
[75857]: rust-lang/rust#75857
[75585]: rust-lang/rust#75585
[75740]: rust-lang/rust#75740
[75502]: rust-lang/rust#75502
[74880]: rust-lang/rust#74880
[74922]: rust-lang/rust#74922
[74430]: rust-lang/rust#74430
[74194]: rust-lang/rust#74194
[73461]: rust-lang/rust#73461
[73166]: rust-lang/rust#73166
[intradoc-links]: https://doc.rust-lang.org/rustdoc/linking-to-items-by-name.html
[`catch_unwind`]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
[`Option::is_some`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_some
[`Option::is_none`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_none
[`Option::as_ref`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_ref
[`Result::is_ok`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok
[`Result::is_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err
[`Result::as_ref`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.as_ref
[`Ordering::reverse`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.reverse
[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then
[`slice::as_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr_range
[`slice::as_mut_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr_range
[`VecDeque::make_contiguous`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.make_contiguous
[`future::pending`]: https://doc.rust-lang.org/std/future/fn.pending.html
[`future::ready`]: https://doc.rust-lang.org/std/future/fn.ready.html
Undin added a commit to intellij-rust/intellij-rust that referenced this pull request Aug 28, 2021
Note, `unsafe` is semantically invalid in case of module/module declaration items. The corresponding change is made to improve error message.
See the corresponding change in rustc: rust-lang/rust#75857
Undin added a commit to intellij-rust/intellij-rust that referenced this pull request Aug 28, 2021
Note, `unsafe` is semantically invalid in case of module/module declaration items. The corresponding change is made to improve error message.
See the corresponding change in rustc: rust-lang/rust#75857
bors bot added a commit to intellij-rust/intellij-rust that referenced this pull request Aug 30, 2021
7751: GRAM&ANN: parse `unsafe` keyword in modules and annotate it as error r=vlad20012 a=Undin

These changes allow parsing mod items with `unsafe` keyword to be consistent with rustc (see rust-lang/rust#75857) and annotate `unsafe` keyword as an error in such cases on the semantic level.

![image](https://user-images.githubusercontent.com/2539310/131228287-fc3bfcbb-efd2-4f57-9466-a1d196477b3e.png)


Note, the corresponding change in rustc was made mainly to provide token tree to proc macros where `unsafe` keyword should be handled by proc macro itself. And in case of such proc macro, `unsafe` keyword shouldn't be annotated as an error. But after these changes, `unsafe` will be annotated as an error by the plugin. But it doesn't look like a new issue, since previously it was annotated as parser error.

For example, for the following code
```rust
//- lib.rs
use proc_macro::TokenStream;
use std::str::FromStr;

#[proc_macro_attribute]
pub fn my_attr(_attr: TokenStream, _item: TokenStream) -> TokenStream {
    return TokenStream::from_str("pub fn foo() { println!(\"Hello from macro!\")}").unwrap()
}

//- main.rs
#[rust_project::my_attr]
unsafe mod foo {}

fn main() {
    foo();
}
```

the plugin produces the corresponding annotations
| Before | After |
| - | - |
| ![image](https://user-images.githubusercontent.com/2539310/131228207-b9b0ca35-c6dc-4ea3-b91e-0b894cde1d41.png) | ![image](https://user-images.githubusercontent.com/2539310/131228220-4ef37560-ffee-447c-bde1-a87fa4cb44b6.png) |


Proper support for error annotations of such cases should be implemented separately, not only for `unsafe` keyword in modules and requires changes from #7194




changelog: Parse `unsafe` keyword in modules and provide error annotation for it


Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
bors bot added a commit to intellij-rust/intellij-rust that referenced this pull request Aug 30, 2021
7751: GRAM&ANN: parse `unsafe` keyword in modules and annotate it as error r=vlad20012 a=Undin

These changes allow parsing mod items with `unsafe` keyword to be consistent with rustc (see rust-lang/rust#75857) and annotate `unsafe` keyword as an error in such cases on the semantic level.

![image](https://user-images.githubusercontent.com/2539310/131228287-fc3bfcbb-efd2-4f57-9466-a1d196477b3e.png)


Note, the corresponding change in rustc was made mainly to provide token tree to proc macros where `unsafe` keyword should be handled by proc macro itself. And in case of such proc macro, `unsafe` keyword shouldn't be annotated as an error. But after these changes, `unsafe` will be annotated as an error by the plugin. But it doesn't look like a new issue, since previously it was annotated as parser error.

For example, for the following code
```rust
//- lib.rs
use proc_macro::TokenStream;
use std::str::FromStr;

#[proc_macro_attribute]
pub fn my_attr(_attr: TokenStream, _item: TokenStream) -> TokenStream {
    return TokenStream::from_str("pub fn foo() { println!(\"Hello from macro!\")}").unwrap()
}

//- main.rs
#[rust_project::my_attr]
unsafe mod foo {}

fn main() {
    foo();
}
```

the plugin produces the corresponding annotations
| Before | After |
| - | - |
| ![image](https://user-images.githubusercontent.com/2539310/131228207-b9b0ca35-c6dc-4ea3-b91e-0b894cde1d41.png) | ![image](https://user-images.githubusercontent.com/2539310/131228220-4ef37560-ffee-447c-bde1-a87fa4cb44b6.png) |


Proper support for error annotations of such cases should be implemented separately, not only for `unsafe` keyword in modules and requires changes from #7194




changelog: Parse `unsafe` keyword in modules and provide error annotation for it


Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
bors bot added a commit to intellij-rust/intellij-rust that referenced this pull request Aug 30, 2021
7751: GRAM&ANN: parse `unsafe` keyword in modules and annotate it as error r=vlad20012 a=Undin

These changes allow parsing mod items with `unsafe` keyword to be consistent with rustc (see rust-lang/rust#75857) and annotate `unsafe` keyword as an error in such cases on the semantic level.

![image](https://user-images.githubusercontent.com/2539310/131228287-fc3bfcbb-efd2-4f57-9466-a1d196477b3e.png)


Note, the corresponding change in rustc was made mainly to provide token tree to proc macros where `unsafe` keyword should be handled by proc macro itself. And in case of such proc macro, `unsafe` keyword shouldn't be annotated as an error. But after these changes, `unsafe` will be annotated as an error by the plugin. But it doesn't look like a new issue, since previously it was annotated as parser error.

For example, for the following code
```rust
//- lib.rs
use proc_macro::TokenStream;
use std::str::FromStr;

#[proc_macro_attribute]
pub fn my_attr(_attr: TokenStream, _item: TokenStream) -> TokenStream {
    return TokenStream::from_str("pub fn foo() { println!(\"Hello from macro!\")}").unwrap()
}

//- main.rs
#[rust_project::my_attr]
unsafe mod foo {}

fn main() {
    foo();
}
```

the plugin produces the corresponding annotations
| Before | After |
| - | - |
| ![image](https://user-images.githubusercontent.com/2539310/131228207-b9b0ca35-c6dc-4ea3-b91e-0b894cde1d41.png) | ![image](https://user-images.githubusercontent.com/2539310/131228220-4ef37560-ffee-447c-bde1-a87fa4cb44b6.png) |


Proper support for error annotations of such cases should be implemented separately, not only for `unsafe` keyword in modules and requires changes from #7194




changelog: Parse `unsafe` keyword in modules and provide error annotation for it


Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
Undin added a commit to intellij-rust/intellij-rust that referenced this pull request Sep 1, 2021
Note, `unsafe` is semantically invalid in case of extern block item. The corresponding change is made to improve error message.
See the corresponding change in rustc: rust-lang/rust#75857
yopox pushed a commit to Kobzol/intellij-rust that referenced this pull request Feb 27, 2023
Note, `unsafe` is semantically invalid in case of module/module declaration items. The corresponding change is made to improve error message.
See the corresponding change in rustc: rust-lang/rust#75857
yopox pushed a commit to Kobzol/intellij-rust that referenced this pull request Feb 27, 2023
Note, `unsafe` is semantically invalid in case of extern block item. The corresponding change is made to improve error message.
See the corresponding change in rustc: rust-lang/rust#75857
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-fcp This change is insta-stable, so needs a completed FCP to proceed. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider deferring parse error on sensibly placed unsafe keyword
7 participants