zr/opaque.rs
1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::cell::UnsafeCell;
6use core::marker::{PhantomData, PhantomPinned};
7use core::mem::MaybeUninit;
8
9/// A wrapper for types that are opaque to Rust.
10///
11/// This is used to wrap C++ objects that Rust should not access directly.
12/// It provides a raw pointer to the inner data for use in FFI, while ensuring
13/// LLVM knows the object has interior mutability (`UnsafeCell`) and may be
14/// self-referential / address-sensitive (`PhantomPinned`, inhibiting `noalias`
15/// on mutable references to enclosing structs).
16#[repr(transparent)]
17pub struct Opaque<T>(MaybeUninit<UnsafeCell<T>>, PhantomData<PhantomPinned>);
18
19impl<T> Opaque<T> {
20 /// Creates a new `Opaque` value.
21 pub const fn new(value: T) -> Self {
22 Self(MaybeUninit::new(UnsafeCell::new(value)), PhantomData)
23 }
24
25 /// Creates an uninitialized `Opaque` value.
26 pub const fn uninit() -> Self {
27 Self(MaybeUninit::uninit(), PhantomData)
28 }
29
30 /// Returns a raw pointer to the opaque data.
31 pub const fn get(&self) -> *mut T {
32 let ptr = self.0.as_ptr();
33 UnsafeCell::raw_get(ptr)
34 }
35}
36
37impl<T> Default for Opaque<T> {
38 fn default() -> Self {
39 Self::uninit()
40 }
41}
42
43/// A zero-sized type representing an opaque C++ object facade.
44///
45/// This is used as a field in Rust facade structs that represent C++ objects
46/// of unknown size. It keeps the facade struct `Sized` (size 0) so it can be
47/// used in FFI (thin pointers) and with generic containers like `RefPtr`,
48/// while ensuring LLVM knows the object has interior mutability and is `!Unpin`.
49#[repr(C)]
50#[derive(Default)]
51pub struct OpaqueFacade {
52 _unused: UnsafeCell<()>,
53 _pinned: PhantomData<PhantomPinned>,
54}