-
-
Notifications
You must be signed in to change notification settings - Fork 150
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
Consider using pointers and &raw operator in object_downcast implementation #62
Comments
I tried to derive a minimal example on the playground. @dtolnay, would you say the linked code is a faithful representation of Running it under
|
Yeah this is worth fixing, good catch. Ideally vtable's object_downcast would be defined only in terms of pointers and never touch a reference, but that may need |
I was thinking you could pass in raw pointer instead of a Miri doesn't complain after switching the playground example to |
In your new playground link |
I think that's because Looking at the RFC, am I right in saying |
Yes the operator is for raw-pointer-to-struct ⟶ raw-pointer-to-field, which isn't currently exposed without passing through a reference. I would prefer not to accept the change from the playground link unless we better understand why it makes a difference to Miri. My guess is that neither playground is strictly conforming to the stacked borrow rules (both do effectively the exact same sequence of casts) but Miri is suppressing warnings on the latter playground as a concession to practicality because it is such a widespread pattern for now, in which case I feel fine sticking with the current code which does the same widespread thing. It could be that the best workaround is to split the vtable to have distinct object_downcast_ref and object_downcast_mut function pointers with the same behavior but & vs &mut in the right place. I don't love it because it feels bloaty, but it would probably pass Miri. |
Splitting I guess to answer the question posed in this issue's title, our best answer is "I dunno", isn't it? In practice this code is okay, as in the Are we able to get a second opinion? |
😐 I am becoming inclined to just leave it. As you wrote, the public API is sound and I definitely don't see this getting miscompiled. It's just going to be a thing to keep an eye on as the unsafe code guidelines get pinned down further, so I'll keep the issue open. We can switch to &raw when it stabilizes. I am hesitant to separate the vtable to two methods because it would be adding many more lines of unsafe code to the crate, and a bloatier vtable, for questionable benefit. |
A better fix would be to use `&raw` throughout the downcast implementation since all the logic is exactly the same in both cases, but that is not stable yet. #62
I'm having a look at the way the
ErrorVTable
is implemented and I noticed theobject_downcast()
method is used to go from&self.inner
to an&mut E
.I know
Error::downcast_mut()
requires a&mut self
so in the grand scheme of things this should still be safe, but in the two highlighted lines we get a mutable reference from an immutable reference without going throughUnsafeCell
, however the docs explicitly state:Is this use of pointer casting sound as far as Rust's memory model is concerned? I know the nomicon says it's UB to
transmute()
a&T
to an&mut T
, but does the same rule hold for pointer casts and field access?(The original reasoning I used when looking at this code)
The text was updated successfully, but these errors were encountered: