Ban inout-to-UnsafePointer conversion for operator arguments

This code currently type checks, and it totally shouldn't:

struct S {
  static func +(lhs: S, rhs: UnsafePointer<Int>) -> Bool { return false }
}

var x: Int = 3

S() + &x
4 Likes

I was looking at this recently and have a change to ban this:

func foo<T>(first: T, second: T) { ... }
let p: UnsafeMutablePointer<Int>
var x: Int

foo(&x, p)

I didnā€™t look at completely banning the inout-to-pointer conversion for operators. I know of one place that I have seen it used, and itā€™s very sketchy - for ==, e.g. imagine foo above is infix ==.

Agreed. We need to move away from tuples for argument labels. The & syntax should be "lexically" part of the normal function call syntax.

3 Likes

Yes, this was "never" supposed to work.

ā€¦but all of that said, it's a source compatibility issue now, so the best we can do in Swift 3/4 modes is to warn on it.

Proof of concept implementation: ā˜£ļø ā˜ ļø For Swift 5 and later, disallow certain argument conversions for operā€¦ by rudkx Ā· Pull Request #15543 Ā· apple/swift Ā· GitHub

I think @rudkx's change merits discussion, but mine is probably bogus. After thinking it through, I think my proposal regarding operators isn't really going to simplify the type checker in any meaningful way. We came up with a better way of simplifying the representation of inout in the AST that doesn't impact the language.

I'd really love to see this fixed at least in Swift 5 mode. It will allow further cleanups of the sad applyexpr representation.

2 Likes