owned this note
owned this note
Published
Linked with GitHub
# Reading notes: RFC 3318, Field Projection
Link to document: https://github.com/y86-dev/rfcs/blob/field-projection/text/3318-field-projection.md
###### tags: `reading-club`
Leave questions, observations, discussion topics below.
---
## Topic
name: prompt
---
## Composability
(might be addressed in RFC text, not yet sure)
pnkfelix: Can the projections described here be composed with themselves, such that e.g. `&MaybeUninit<Cell<Struct>>` can be projectred to `&MaybeUninit<Cell<Field>>`? Or does this only go "one level deep" ?
vincenzopalazzo: this is unclear also to me, and it is unclear also how the solution proposed in the RFC works at implementation level
https://github.com/y86-dev/rfcs/blob/field-projection/text/3318-field-projection.md#reference-level-explanation and "Supported pointers"
Distinction between `P` pointer types and `Wrapper` types (both happen to include `Pin`)
tmandry: Don't see a reason why not I guess
## How to express non-magic-projecting access?
(might be addressed in RFC text, not yet sure)
pnkfelix: If one of the types in question already a struct, do we need to continue to support the previous access? If so, how is that expressed ... via a new operator? Or by some thing analogous to UFCS, but now for field access rather than method calls? (E.g. how does one express what would today be denoted by `.inner` for a given `#[repr(transparent)]` type)
pnkfelix: I could imagine support for the previous kind of access might still be expressable via `match`... oh lets ask about that too ... Update: RFC as written does not allow for the old semantics to be expressed via `let` and presumably via `match` either, see below
pnkfelix: Maybe the intention is that you can get access to the original fields by first turning your `&Wrapper` into a `*const Wrapper` and then the `.`-projection operator acts on the `Wrapper` type, not on the projected type?
Field access has higher priority than projection:
https://github.com/y86-dev/rfcs/blob/field-projection/text/3318-field-projection.md#deref-and-derefmut
pnkfelix: But then if I try to access some field `inner` (and that's in `Pin`) then we have privacy-dependent name resolution? Maybe we want/have this anyway.
tmandry: Probably should be called out in the RFC.
## does this impact `match`/`let` semantics (answer: yes)
Update: The intention *is* that this will affect bindings; `let` is demonstrated in the RFC text, and presumably `match` is affected as well.
pnkfelix: I can understand how `foo.field` ends up projecting out the internals of `field` within `foo`. But does that also mean that this is impacted:
```rust=
let foo: &Cell<Struct> = ...;
match foo {
Struct { field } => ...
// does this *start working*, where `field` now has type `&Cell<Field>` ?
}
```
https://github.com/y86-dev/rfcs/blob/field-projection/text/3318-field-projection.md#bindings
pnkfelix: "Enum bindings cannot be supported with the wrappers MaybeUninit\<T> and Cell\<T>". What's the actual constraint here?
eholk: They don't explain what to do about the UB here.
pnkfelix: Seems like you get clear benefits from `.` and (things you can put on rhs of a let), don't know why they attempted to do matches in the first go-round.
pnkfelix: Seems simplest to punt, but then again, maybe it's so valuable to match on an enum etc that we should work it out.
## Implementation details
(vincenzopalazzo) Why project one filed if you can prepare the code to project with an infinite struct filed?
The code could be
```rust
#[project(Pin)]
struct MyStruct {
buf: [u8; 64],
ptr: *const u8,
_pin: PhantomPinned,
}
// gen by the macros
trait ProjectPinForMyStruct {
fn buf_as_pin(&self) -> Pin<[u8; 64]>; // not sure that compile :)
fn ptr_as_pin(&self) -> Pin<....>
}
impl ProjectPinForMyStruct for MyStruct {
fn buf_as_pin(&self) -> Pin<[u8; 64]>; // not sure that compile :)
fn ptr_as_pin(&self) -> Pin<....>
... so on
}
```
pnkfelix: (Something about disjoint fields, sorry bad notes)
eholk: It also talks about [Arc projection](https://github.com/y86-dev/rfcs/blob/field-projection/text/3318-field-projection.md#out-of-scope-arc-projection)
## Relation to dyn*
tmandry: The `NoMetadataPtr` trait and some operations proposed for projection look kind of like `dyn*` if you squint. Is there some kind of relationship here or is that just surface-level resemblance?
eholk: I was wondering the same thing.
pnkfelix: dyn* is not google-able :)
eholk: I almost called in `dyn⭐` when I was making the parsing change
tmandry: `dyn* Future` is pointer+vtable-sized object that implements `Future`; has a conversion trait like `IntoRawPointer` that looks just like `NoMetadataPtr`.
tmandry: One possible difference is that `dyn*` _can_ represent `Box` (pnkfelix: also `Arc`) and ownership, whereas this is about borrowed data exclusively
pnkfelix: More utility for this is projection of field where you erase the knowledge of original struct?
tmandry: I guess I don't see a reason why they can't be the same trait.
eholk: If you squint, dyn* might be able to represent a lot of these projection.