Manually cast heapless::Vec to slice for select_slice#898
Conversation
eda635e to
9013e23
Compare
9013e23 to
b9ef9fc
Compare
The current implementation of `pin!` automatically does type coercion with references. We rely on this when using `select_slice`. However, this behavior is unsound because there's no guarantee that the result of this coercion is actually pinned. Pre-emptively Use `map_unchecked_mut` to manually perform this cast since it is safe in our case and because this fix will eventually land on main (currently present on nightly 1.97). See rust-lang/rust#153438 and rust-lang/rust#153457.
b9ef9fc to
3346721
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates several select_slice call sites that build a heapless::Vec of futures, replacing an implicit pin/coercion pattern with an explicit Pin::map_unchecked_mut cast to a pinned slice to avoid relying on known-unsound coercion behavior in pin! (per rust-lang issue #153438).
Changes:
- Replace
select_slice(pin!(...))usage withpin!(futures)+unsafe { pinned.map_unchecked_mut(|f| f.as_mut()) }to obtain a pinned slice explicitly. - Add inline comments documenting the pinning and safety rationale near the unsafe conversion.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| type-c-service/src/service/event_receiver.rs | Updates port event receiver selection to use an explicit pinned-slice conversion for select_slice. |
| power-policy-service/src/psu.rs | Updates PSU event selection to use an explicit pinned-slice conversion for select_slice. |
| power-policy-service/src/charger.rs | Updates charger event selection to use an explicit pinned-slice conversion for select_slice. |
|
I'm not sure whether this is sound or not. See list item 3 (Structural Notice of Destruction) at https://doc.rust-lang.org/nightly/std/pin/index.html#choosing-pinning-to-be-structural-for-field. |
@theemathas Thanks for taking a look, I appreciate it. My understanding is that there shouldn't be any invalidation issues with |
|
Ah right, heapless is using a single drop_in_place call for the whole vec, so I think it's fine. Sorry for the noise. |
|
The important part is that if one future's drop panics, the other futures still must be dropped. I think drop_in_place on a slice does that. |
No worries, this is definitely a part of Rust that I don't engage with very often so I'm happy to have another set of eyes on it. |
The current implementation of
pin!automatically does type coercion with references. We rely on this when usingselect_slice. However, this behavior is unsound because there's no guarantee that the result of this coercion is actually pinned. Pre-emptively Usemap_unchecked_mutto manually perform this cast since it is safe in our case and because this fix will eventually land on main (currently present on nightly 1.97).See rust-lang/rust#153438 and rust-lang/rust#153457.