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

Adding unsafe modules and unsafe blocks outside functions. #2148

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions text/0000_unsafe_modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
- Feature Name: unsafe_modules
- Start Date: 2017-09-12
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

# Summary
Allow unsafe at more positions.

# Motivation

When writing unsafe code it's annoying having to write unsafe everywhere. Normally that's a good thing, but sometimes, especially for prototyping, it would sometimes be preferable to be able to declare unsafe for larger blocks.
Maybe it's also helpful for low level code with huge amount of unsafe functions or c interaction.

# Guide-level explanation

Unsafe blocks can also be written outside of functions:
```
unsafe {
fn x() {...}
trait X {...}
...
}
```

This will make the elements defined inside the block unsafe.
It will be equivalent to following code:
```
unsafe fn x() {...}
unsafe trait X {...}
unsafe ...
```

Even modules can be declared as unsafe like this:
```
unsafe mod test {
fn x() {...}
trait X {...}
...
}
```

This is almost equivalent to following:
```
mod test {
unsafe {
fn x() {...}
trait X {...}
...
}
}
```
But unsafe modules have an additional property.
Using such a module is also unsafe:
```
unsafe use test;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this surprising, because use doesn't need unsafe to import other unsafe things:

mod foo { pub unsafe fn bar() {} }
use foo::bar; // no unsafe

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still perhaps understandable...? With normal modules the entire module isn't necessarily for unsafe stuff. And unsafe use can be good for greppability. Then again, you still have to be in "unsafe mode" to use the functions inside the module, and you can grow for that.

Copy link
Member

@scottmcm scottmcm Sep 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that "this could just be implemented by some syntactic transformations" isn't true, though. It's a new concept that users need to know, but I'm not convinced there's value in it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wasn't sure if unsafe use is useful. But you don't even need to use unsafe functions from safe modules, and just use them at other positions. Maybe just importing things from inside the module as unsafe would make sence? But I think I should remove unsafe use from the RFC entirely. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say just remove it, especially since it opens a bunch of questions about what paths involving the module would require. For example:

unsafe mod foo {
    pub struct Bar;
}
use foo::Bar; // do I need `unsafe use` here?

(Thanks to Havvy for inspiration that led to this example.)

fn main() {
unsafe {
test::x();
}
}
```



# Reference-level explanation
This could just be implemented by some syntactic transformations.

# Drawbacks
The use of unsafe may be encouraged.

# Rationale and Alternatives
It may also be possible to add a compiler option to allow unsafe code without declaration. But this option should offer more control about, what is unsafe.
Modules may also declared as unsafe using a feature macro like `#[unsafe]` before the module name or inside the module as `#![unsafe]`. Problem: This is syntactically irregular. Then it would be desirable, that you even declare unsafe functions as following:
```
#[unsafe]
fn x() {...}
```

# Unresolved questions
Should `use` really be `unsafe`?
If it's unsafe to use the module, should calling the functions still be unsafe or will an additional `unsafe` block be needed for calling?
Should whole crates or other things also be able to be declared as unsafe?
How should elements inside the block be handled, if they cannot be declared as unsafe (like variables).
If unsafe fields will be implemented, will it be still required to declare them unsafe explicitely?