-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Investigate the soundness of tagged Objective-C objects behind references #235
Comments
Note that we never actually attempt to dereference tagged objects in Rust code, we only send them to Objective-C via. |
Perhaps I suspect this pattern of wanting certain references to be able to store maybe-tagged pointers is not uncommon, e.g. the Need to open issue / search for similar at the unsafe code guidelines! EDIT: done |
Alternatively we change our entire API surface to use something like: extern "C" {
type Opaque;
}
pub struct NSObject<'a> {
ptr: NonNull<Opaque>,
p: PhantomData<&'a ()>,
}
// Usage
let n: Id<NSObject<'static>, Owned>;
let n_ref: &NSObject<'_> = &*n; // Deref
let n_mut: &mut NSObject<'_> = &mut *n; // DerefMut
extern "C" {
fn my_fn(obj: NSObject<'a>) {} // What is the mutability of `obj` here???
} Unsure how exactly this would work! |
We'd probably need |
Related: |
I tried making an example that can be run under Miri, see this gist. For now, it seems like Miri treats zero-sized types specially enough that patterns the ones we use is allowed (or, at least not disallowed). |
I've spent a lot of time in the past ensuring that the usual stacked borrows rules are upheld (for example ensuring that
&NSObject
and&mut NSObject
never coexist), but I haven't actually ensured that even creating the reference to&NSObject
is sound in the first place!Our current definition of all object types is roughly:
That is, a ZST (zero-sized type) with
UnsafeCell
to mark it as mutable behind shared references (since we don't know how a specific instance is implemented).This is then used roughly as follows:
Importantly, we use a reference to
NSObject
. This means that we must uphold certain properties that raw pointers don't need to!Reading the documentation, in particular the fact that references must be aligned and dereferenceable is concerning: It is common for Objective-C to use "tagged classes", which essentially means that
&NSObject
may be a tagged pointer and not an actual pointer (examples:NSString
&NSNumber
).Currently, the fact that
NSObject
is a ZST makes rustc not output thedereferenceable
LLVM attribute, but it still outputsalign 1
which is problematic (of course, things needs to be allowed by the language, not just allowed by current LLVM output, but it's a useful metric).Need to find a solution to this!
The text was updated successfully, but these errors were encountered: