Conversation
|
r? @jieyouxu rustbot has assigned @jieyouxu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
I expect this needs crater, so: @bors try |
This comment has been minimized.
This comment has been minimized.
prevent deref coercions in `pin!`
092ecb8 to
8f93fc9
Compare
|
Just realized I could format things more cleanly (diff). This shouldn't affect the correctness of the try build. |
|
A more explicit approach could be to do something like: super let mut pinned = $value;
#[allow(unreachable_code)]
'p: {
fn unreachable_type_constraint<'a, T>(_: T) -> Pin<&'a mut T> {
unreachable!()
}
break 'p unsafe { Pin::new_unchecked(&mut pinned) };
unreachable_type_constraint(pinned)
} |
|
So that's how to add types to macros! Funky idiom, but I do prefer the explicitness of actually having types, yeah. I think that'd be less likely to break inference too if anything's started relying on it; iirc type expectations are propagated from the block to the break expression (via the block's coercion target type). But it's fine because we'll encounter an error instead of silently adding a coercion if things don't match up.. I think. Would you prefer to make your own PR @eggyal, or should I just work that into this one? I'm not a library reviewer so I can't say which would be preferable from that perspective, but from the perspective I do have, I think adding a type constraint is a better fix. |
|
By all means work it into this one. This idiom was originally suggested to me by lcnr some years ago, so I claim no credit for it! |
|
this change requires someone from libs team to be approved, so i'm reassigning r? libs |
8f93fc9 to
524b11d
Compare
|
Went ahead with the unreachable type constraint version of this (diff). There's unfortunately a bit of a diagnostics regression due to the extra type checking. I still think it's worth the lower likelihood of breakage, but it's a tradeoff. I'll be firing off a fresh try build, but if the diagnostics are a sticking point, maybe it'd be worth comparing crater results for both approaches? |
|
@bors try |
This comment has been minimized.
This comment has been minimized.
prevent deref coercions in `pin!`
|
I'll crater the type constraint approach first since that's my preferred quick fix at the moment. Also going to try re-running pr-check-2. It never restarted after being canceled it looks like? |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
I'm not yet convinced that this approach is 100% sound. Although I think it would be a good idea to do this fix even if it's not 100% sound, since any soundness exploit of this would be significantly more convoluted than the current exploit. Given a value
I am not sure whether there exist types Edit: Added two more bullet points Edit 2: Changed a requirement into the Unpin requirement. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Ooh, I hadn't considered that. Even if this is 100% sound, that means the argument for it is subtle enough that I'm not sure I'd want to rely on it over something simpler. Maybe going back to an inference-limiting approach (or combining approaches) would be best? That way we can be sure there's no coercions in the first place. For ease of comparison, the trick in my original version of this PR was let pinned_ref = unsafe { $crate::pin::Pin::new_unchecked(&mut pinned) };
pinned_refSince the type of If that's too subtle, I think there are other ways to limit inference/coercions too. This is probably even hackier, but to have an example, a trick I've used for preventing coercions in tests is defining |
| fn unreachable_type_constraint<'a, T>(_: T) -> $crate::pin::Pin<&'a mut T> { | ||
| unreachable!() | ||
| } |
There was a problem hiding this comment.
This ought to be factored out in some macro-internals module of ::core, to reduce compiler overhead (we shouldn't be defining an ad-hoc fn for every pin! invocation).
- Tangentially, we may be able to avoid the
unreachable_codewarning and the'p-labelled block with anif false { unreachable_type_constraint(pinned) } else { Pin::new_unchecked(&mut pinner) }, although this touches on a matter of taste and preference (there is some appeal in thatexpect, after all)
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
Footnotes
|
|
Wait what? Why did crater not catch https://github.com/restatedev/restate/blob/a472bad4e12427012f6215947edd35561d62d0b3/crates/vqueues/src/scheduler/drr.rs#L563 ? |
The create does not appear to be on crates.io (it has |
View all comments
Fixes #153438 using a (hopefully temporary!) typed macro idiom to ensure that when
pin!produces aPin<&mut T>, its argument is of typeT. See #153438 (comment) for my ideas on how this could be changed in the future.