Swift *less* safe than C for imported API that uses opaque struct pointers

We should be able to synthesize opaque types as structs with inaccessible initializers, and use the existing UnsafePointer types. That would work better in situations where you have some modules that can see the implementation of '_acl', and some that can't.

-Joe

···

On Jun 22, 2016, at 11:20 AM, Timothy J. Wood via swift-evolution <swift-evolution@swift.org> wrote:

Currently, APIs that get imported with COpaquePointer make Swift *less* safe than C. Fixing this seems like a breaking change, since it would change the meaning of existing code that uses COpaquePointer.

As a motivating example consider:

import Darwin

var state = copyfile_state_alloc()
print("state = \(state.dynamicType) \(state)")

let acl = acl_init(1)
print("acl = \(acl.dynamicType) \(acl)")

state = acl
print("state = \(state.dynamicType) \(state)")

I’m just using these types since they use opaque structs and are easy to create in this sample, but this pattern is fairly common in other C APIs that try to encapsulate their implementation.

This compiles and builds, silently accepting the bogus code:

DEVELOPER_DIR=/Applications/Xcode-8.0b1.app/Contents/Developer swift c-unsafety.swift
state = Optional<OpaquePointer> Optional(0x00007f9db481b3d0)
acl = Optional<OpaquePointer> Optional(0x00007f9db2944c00)
state = Optional<OpaquePointer> Optional(0x00007f9db2944c00)

The equivalent C version:

copyfile_state_t state = state = copyfile_state_alloc();
acl_t acl = acl_init(1);
state = acl;

produces a warning:

c-unsafety.c:10:8: warning: incompatible pointer types assigning to 'copyfile_state_t' (aka 'struct _copyfile_state *') from 'acl_t' (aka 'struct _acl *')

Would it be feasible to import these sorts of pointers in a safe(r) way by making COpaquePointer generic and faking up a struct tag type? So, these might get imported with something equivalent to:

struct _acl {}
typealias acl_t = COpaquePointer<_acl>