Skip to content

Restore operator T() on Field* and allow operator(*|->) on Ref/RefMut - #137

Open
RaitoBezarius wants to merge 2 commits into
hkalbasi:mainfrom
RaitoBezarius:fix-field-conversion-ops
Open

Restore operator T() on Field* and allow operator(*|->) on Ref/RefMut#137
RaitoBezarius wants to merge 2 commits into
hkalbasi:mainfrom
RaitoBezarius:fix-field-conversion-ops

Conversation

@RaitoBezarius

Copy link
Copy Markdown

Fixes #133.

Each commit presents its rationale.

TL;DR:

  • Add operator* and operator-> (const/non-const) for Ref/RefMut
  • Add operator T() on FieldRef/FieldMut/FieldOwned using operator* on Ref/RefMut
  • Added some regression testing for my usecases

Raito Bezarius added 2 commits August 25, 2026 13:37
The primitive specializations of Ref/RefMut always provided operator*,
but the per-type specializations generated for user-defined types did
not, leaving no way to access the pointee of a Ref<UserType> other than
calling zngur-declared methods on it.

We emit operator*/operator-> for those specializations too,
returning a reference aliasing the underlying Rust memory without
taking ownership. Copying the value out works when the type is Copy,
since its copy constructor performs the deep copy; non-Copy types keep
their ownership discipline with respect to the deleted copy constructors
on the C++ side.

Signed-off-by: Raito Bezarius <raito@lix.systems>
The FieldOwned/FieldRef/FieldRefMut primary templates define a
conversion to T, but the per-type explicit specializations generated
for each user-defined type silently dropped it. Types with a
specialization (e.g. Bool) therefore lost the conversion that
primitive field types had.

Only Copy types can support the conversion: it copies the value out of
the parent object, which is impossible for non-Copy types whose copy
constructor is deleted.

The definition is emitted out-of-line near the end of the header because
the specializations are generated before the type and Ref definitions it
needs.

Regression tests cover Bool, Copy structs and Copy generic
instantiations (Option<&T>, Option<T: Copy>).

Fixes hkalbasi#133.

Signed-off-by: Raito Bezarius <raito@lix.systems>
@hkalbasi

Copy link
Copy Markdown
Owner

Thanks for the PR! I think adding a general propose T& operator*() is impossible due to layout deferences between C++ type and Rust type. What is possible is a T operator*() for Copy types (and the current implementation is UB for anything non trivial). Similarly, we can't have a normal -> operator and what we actually do is repeating all methods and fields of the T on Ref<T> too (which also helps in having . instead of -> which is more like Rust and C++ references). The field Copy implementation looks good to me.

@RaitoBezarius

Copy link
Copy Markdown
Author

Thanks for the PR! I think adding a general propose T& operator*() is impossible due to layout deferences between C++ type and Rust type. What is possible is a T operator*() for Copy types (and the current implementation is UB for anything non trivial). Similarly, we can't have a normal -> operator and what we actually do is repeating all methods and fields of the T on Ref<T> too (which also helps in having . instead of -> which is more like Rust and C++ references). The field Copy implementation looks good to me.

I will drop the implementations and rework it accordingly, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copy type field access is blocked

2 participants