Skip to content

Commit 7cc6692

Browse files
committed
edits and feedback
1 parent 263a510 commit 7cc6692

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

text/0000-unsafe-attributes.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub fn write(...) { ... }
3838
this will cause Rust to generate a globally visible function with the
3939
linker/export name `write`. As consequence of that, other code that wants to
4040
call the
41-
[C `write` function](https://man7.org/linux/man-pages/man2/write.2.html) might
41+
[POSIX `write` function](https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html) might
4242
end up calling this other `write` instead. This can easily lead to Undefined
4343
Behavior:
4444
- The other `write` might have the wrong signature, so arguments are passed
@@ -59,6 +59,14 @@ dangerous and needs manual checking, `unsafe(no_mangle)` acknowledges that
5959
pub fn my_own_write(...) { ... }
6060
```
6161

62+
Note that when writing a library crate, it is in general not possible to make
63+
claims like "there is no other global function of this name". This is a
64+
fundamental limitation of the global linking namespace, and not something Rust
65+
currently is able to overcome. Libraries that make such assumptions should
66+
ideally document somewhere publicly that they consider some namespace, i.e.
67+
every function starting with `_mycrate__`, to be reserved for their exclusive
68+
use.
69+
6270
# Reference-level explanation
6371
[reference-level-explanation]: #reference-level-explanation
6472

@@ -72,10 +80,10 @@ are considered "unsafe" attributes. An unsafe attribute must only be used inside
7280
```
7381

7482
For backwards compatibility reasons, using these attributes outside of
75-
`unsafe(...)` is just a lint, not a hard error. Initially, this lint will be
76-
allow-by-default. Unsafe attributes that are added in the future can
77-
hard-require `unsafe` from the start since the backwards compatibility concern
78-
does not apply to them.
83+
`unsafe(...)` is just a lint, not a hard error. The lint is called
84+
`unsafe_attr_outside_unsafe`. Initially, this lint will be allow-by-default.
85+
Unsafe attributes that are added in the future can hard-require `unsafe` from
86+
the start since the backwards compatibility concern does not apply to them.
7987

8088
Syntactically, for each unsafe attribute `attr`, we now also accept
8189
`unsafe(attr)` anywhere that `attr` can be used. `unsafe` cannot be nested,
@@ -86,6 +94,21 @@ outside of `unsafe(...)` blocks. (That lint currently has special handling to
8694
deny these attributes. Once there is a general notion of 'unsafe attributes' as
8795
proposed by this RFC, that special handling should no longer be needed.)
8896

97+
The `unsafe(...)` attribute block is required even for functions declared inside
98+
an `unsafe` block. That is, the following is an error:
99+
100+
```rust
101+
fn outer() {
102+
unsafe {
103+
#[no_mangle]
104+
fn write() {}
105+
}
106+
}
107+
```
108+
109+
This matches the fact that expression-level unsafety is not inherited for items
110+
declared inside other items.
111+
89112
# Drawbacks
90113
[drawbacks]: #drawbacks
91114

@@ -161,7 +184,7 @@ attributes.
161184
`unsafe { ... }`.)
162185
- **Unsafe derive.** We could use `#[unsafe(derive(Trait))]` to derive an
163186
`unsafe impl` where the deriving macro itself cannot check all required safety
164-
conditions.
187+
conditions (i.e., this is 'unsafe to derive').
165188
- **Unsafe tool attributes.** Same as above, but for tool attributes.
166189
- **Unsafe attributes on statements.** For now, the only unsafe attributes we
167190
have don't make sense on the statement level. Once we do have unsafe statement

0 commit comments

Comments
 (0)