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

Update nomicon to describe #[may_dangle] #39196

Merged
merged 1 commit into from Feb 3, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 24 additions & 6 deletions src/doc/nomicon/dropck.md
Expand Up @@ -199,24 +199,42 @@ assert (unsafely) that a generic type's destructor is *guaranteed* to
not access any expired data, even if its type gives it the capability
to do so.

That attribute is called `unsafe_destructor_blind_to_params`.
That attribute is called `may_dangle` and was introduced in [RFC 1327]
(https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md).
To deploy it on the Inspector example from above, we would write:

```rust,ignore
struct Inspector<'a>(&'a u8, &'static str);

impl<'a> Drop for Inspector<'a> {
#[unsafe_destructor_blind_to_params]
unsafe impl<#[may_dangle] 'a> Drop for Inspector<'a> {
fn drop(&mut self) {
println!("Inspector(_, {}) knows when *not* to inspect.", self.1);
}
}
```

This attribute has the word `unsafe` in it because the compiler is not
checking the implicit assertion that no potentially expired data
Use of this attribute requires the `Drop` impl to be marked `unsafe` because the
compiler is not checking the implicit assertion that no potentially expired data
(e.g. `self.0` above) is accessed.

The attribute can be applied to any number of lifetime and type parameters. In
the following example, we assert that we access no data behind a reference of
lifetime `'b` and that the only uses of `T` will be moves or drops, but omit
the attribute from `'a` and `U`, because we do access data with that lifetime
and that type:

```rust,ignore
use std::fmt::Display;

struct Inspector<'a, 'b, T, U: Display>(&'a u8, &'b u8, T, U);

unsafe impl<'a, #[may_dangle] 'b, #[may_dangle] T, U: Display> Drop for Inspector<'a, 'b, T, U> {
fn drop(&mut self) {
println!("Inspector({}, _, _, {})", self.0, self.3);
}
}
```

It is sometimes obvious that no such access can occur, like the case above.
However, when dealing with a generic type parameter, such access can
occur indirectly. Examples of such indirect access are:
Expand Down Expand Up @@ -263,7 +281,7 @@ some other method invoked by the destructor, rather than being written
directly within it.

In all of the above cases where the `&'a u8` is accessed in the
destructor, adding the `#[unsafe_destructor_blind_to_params]`
destructor, adding the `#[may_dangle]`
attribute makes the type vulnerable to misuse that the borrower
checker will not catch, inviting havoc. It is better to avoid adding
the attribute.
Expand Down