BitwiseCopyable does not suppress "may contain object reference" warning

I am getting Forming 'UnsafeRawPointer' to a variable of type '[V]'; this is likely incorrect because 'V' may contain an object reference. when trying to pass an array to C. V is constrained to a protocol which is itself constrained to BitwiseCopyable.

BitwiseCopyable makes putting classes in my type impossible, so I don't think this warning is correct.

Please show the snippet.

You can easily reproduce it with this

@_extern(c)
func takesArray(_ ptr: UnsafeRawPointer, _ count: CInt)

protocol A: BitwiseCopyable {}

func passesArray<V: A>(vs: [V]) {
    takesArray(vs, CInt(vs.count)) // Warning: Forming 'UnsafeRawPointer' to a variable of type '[V]'; this is likely incorrect because 'V' may contain an object reference.
}

The warning just telling you that you must be super extra careful with the bytes you got. Plotting the bytes out? That's fine. But many things are not fine, as the following example shows:

let scratchArea = malloc(100)!

func readBytes(_ v: UnsafeMutableRawPointer, _ count: Int) {
    memcpy(v, scratchArea, count)
}
func writeBytes(_ v: UnsafeRawPointer, _ count: Int) {
    memcpy(scratchArea, v, count)
}
class C {}
struct S { var x: C? }
var c: C? = C()
var s1 = S(x: c)
var s2 = S(x: nil)
let size = MemoryLayout.size(ofValue: s1)
print(s1) // S(x: Optional(C))
print(s2) // S(x: nil)
writeBytes(&s1, size) // 🔶 Forming 'UnsafeMutableRawPointer' to a variable of type 'S'; this is likely incorrect because 'S' may contain an object reference.
readBytes(&s2, size)  // 🔶 Forming 'UnsafeMutableRawPointer' to a variable of type 'S'; this is likely incorrect because 'S' may contain an object reference.
print(s2) // S(x: Optional(C))
print(c)  // Optional(C)
c = nil
s1.x = nil
print(s2) // 💣 CRASH! BOOM! BANG!

Yes but I don't see how this is related — your S is not BitwiseCopyable

class C {}
struct S: BitwiseCopyable {
    var x: C? // Error: Stored property 'x' of 'BitwiseCopyable'-conforming struct 'S' has non-bitwise-copyable type 'C?'
}

In my example it can't contain an object reference because it's constrained to be BitwiseCopyable.

That's what I meant, the warning is usually correct but it no longer makes sense when the type just can't contain a class.

1 Like

cc @Andrew_Trick @kavon seems like we should lift this restriction when we know the type in question is BitwiseCopyable now that the proposal's been accepted, unless I'm missing something?

3 Likes

That's right. BitwiseCopyable should be the recommended way to silence those warnings:

main PR: Suppress pointer conversion warnings for BitwiseCopyable elements. by atrick · Pull Request #73687 · apple/swift · GitHub

Now we can finally restart the evolution proposal:

5 Likes