Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign updropck can be bypassed via a trait object method #26656
Comments
This comment has been minimized.
This comment has been minimized.
|
triage: I-nominated |
rust-highfive
added
the
I-nominated
label
Jun 29, 2015
alexcrichton
added
the
T-compiler
label
Jun 29, 2015
arielb1
changed the title
dropck can be bypassed via a trait method
dropck can be bypassed via a trait object method
Jun 29, 2015
This comment has been minimized.
This comment has been minimized.
|
Hmm, so I don't think that the problem has to do with |
This comment has been minimized.
This comment has been minimized.
|
After thinking on this last night, I laid it out in my head this way. There is a properly very similar to variance, let's call it " For convenience, we also write Given some type declared like
In addition there are some ground rules:
Now the dropck can use these rules to decide when it should enforce stricter rules. In particular, if an lvalue of type The key point is that this property may access is independent from whether a value has a destructor. The intution is "if a destructor got ahold of a value of type |
This comment has been minimized.
This comment has been minimized.
|
Some implications of this, presuming this property is inferred in a similar fashion to variance:
|
This comment has been minimized.
This comment has been minimized.
|
Personally I think of the issue as being more related to liveness - every lifetime parameter to a function (or impl) is required to be alive when the function (that can access that impl) is called, but (because of dropck) type parameters passed to a function may not be alive. This is preserved by normal selection (as it can't dig into the dead type and find the dead lifetime), but trait objects (and equivalently, instantiations of generic functions) can "refer to" an impl that witnesses the liveness of the lifetime, and should be treated as such. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 I don't disagree with all that. It is certainly intentional that dropck allows access to "potentially dead data" in some cases. The original formulation did not, but we found it was very strict. The goal of the "may observe" relation I was discussing is to specify precisely when it is ok to allow access to potentially dead data, because we can be sure that the data will not be used. /me kind of misses the days when data with dtors was always |
This comment has been minimized.
This comment has been minimized.
|
Heh, dtors could always refer to dead types (with |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 yes, they were only ever |
This comment has been minimized.
This comment has been minimized.
|
okay clearly the Sound Drop RFC needs some updating. The observation that parametricity is not a sufficient condition is important. I will try to incorporate the comments above into a PR on the rfcs repo (either a new RFC or an amendment to Sound Drop, depending on how bad the damage is). |
This comment has been minimized.
This comment has been minimized.
|
triage: P-high (soundness issue) |
rust-highfive
added
P-high
and removed
I-nominated
labels
Jul 9, 2015
nikomatsakis
assigned
pnkfelix
Jul 9, 2015
pnkfelix
added
the
A-destructors
label
Jul 15, 2015
This comment has been minimized.
This comment has been minimized.
|
The more I think about this, the more I would prefer to back away from the current (unsound, as demonstrated here) parametricity-based reasoning and lean on something simpler (e.g., an unsafe annotation), at least for the time being, if not forever. |
This comment has been minimized.
This comment has been minimized.
|
For the public record My opinion is that if bugs like this and #26657 were the only known issues with dropck, then I would prefer to try to improve the reasoning performed by dropck, rather than rely on user-provided annotations that are likely to be misunderstood and abused, yielding bugs that are hard to witness (i.e. that I expect naive testing to miss). However, given that there are also issues with the proposed specialization RFC, I am now investigating adding an unsafe annotation along the lines noted above. (Still, it would be nice if in parallel with paring back on dropck for the short term, if we also tried to be forward-thinking and not add features that will make it impossible to put back parametricity based reasoning in the future. Okay, that's enough out of me.) |
This comment has been minimized.
This comment has been minimized.
|
It took me a while to understand why trait objects even help in circumventing dropck... my current conclusion is that in EDIT: I also wonder how Rust chooses the lifetime for EDIT2: Coming back to my point above: Rust only assumes |
This comment has been minimized.
This comment has been minimized.
|
@RalfJung my go-to example when thinking about this is a struct that carries both some object and a callback on that object: struct S<T> { x: Option<T>, f: fn (T) }To my mind, The above properties are not violations of parametricity. (it is what I see as a celebration of parametricity: it allows one to make very strong statements about what clients can do with instances of With our current buggy dropck, however, one is allowed to pass the
|
This comment has been minimized.
This comment has been minimized.
|
@pnkfelix That's a great example, thanks a lot! I think I understand now. |
This comment has been minimized.
This comment has been minimized.
|
Right. And this can be fixed (after @nikomatsakis's patch) by making On the other hand, ordinary parametricity isn't really the important condition for dropck. Rust code is always perfectly parametric about lifetimes. One theoretical way to make dropck work with specialization is to change the "vtables" during destruction, C++-style, which is basically a gaping violating of parametricity. Even without that, you can safely:
|
arielb1
added
the
I-unsound 💥
label
Oct 1, 2015
This comment has been minimized.
This comment has been minimized.
|
/me has been officially nagged by @nikomatsakis to put up a PR for the implementation of RFC rust-lang/rfcs#1238 |
nikomatsakis
added
E-needstest
and removed
P-high
labels
Oct 29, 2015
nikomatsakis
unassigned
pnkfelix
Oct 29, 2015
This comment has been minimized.
This comment has been minimized.
|
This is basically fixed, but we don't have a specific regression test. |
bstrie
added
the
I-nominated
label
Nov 29, 2015
This comment has been minimized.
This comment has been minimized.
|
Nominating as this is a soundness bug that has yet to have a priority assigned. |
pnkfelix
self-assigned this
Dec 3, 2015
arielb1
removed
the
I-nominated
label
Dec 3, 2015
This comment has been minimized.
This comment has been minimized.
|
@bstrie this has been fixed, we're just waiting on a regression test. |
arielb1 commentedJun 29, 2015
STR
This fails the assertion. cc @pnkfelix. I think the problem here is that
Box<Trigger<B>+'static>does not require thatB: 'static(cc @nikomatsakis).