Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/dropck.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ compiler is not checking the implicit assertion that no potentially expired data

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
lifetime `'b` and that the only uses of `T` will be drops, but omit
Copy link
Member

Choose a reason for hiding this comment

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

I don't think the change here is correct as described in RFC: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md#the-eyepatch-attribute

When used on a type, e.g. #[may_dangle] T, the programmer is asserting the only uses of values of that type will be to move or drop them. Thus, no fields will be accessed nor methods called on values of such a type (apart from any access performed by the destructor for the type when the values are dropped). This ensures that no dangling references (such as when T is instantiated with &'a u32) are ever accessed in the scenario where 'a has the same lifetime as the value being currently destroyed (and thus the precise order of destruction between the two is unknown to the compiler).

In your example, the moved value will be dropped by Options::take, not us, while we have to take responsibility of drop here instead. When we use something like ManualDrop, it would be sound.

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure what you mean. Miri still detects UB in this code:

#![feature(dropck_eyepatch)]
#![allow(unused)]

struct Thing<T>(Option<T>);

unsafe impl<#[may_dangle] T> Drop for Thing<T> {
    fn drop(&mut self) {
        std::mem::forget(self.0.take());
    }
}

fn main() {
    let thing;
    {
        let a = 1;
        thing = Thing(Some(&a));
    }
    // thing is dropped here
}

Copy link
Member

Choose a reason for hiding this comment

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

It's unsound because drop is occured while we have to ensure moved value will not be used (i.e. dropped by destructor). Just move something is still sound.

Copy link
Author

Choose a reason for hiding this comment

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

I don't understand which Drop you're talking about. Could you write code that demonstrates this?

the attribute from `'a` and `U`, because we do access data with that lifetime
and that type:

Expand Down