on Mon Jun 27 2016, Andrew Trick <atrick-AT-apple.com> wrote: > I agree, this syntax works best, all considered: > > UnsafeRawPointer.cast(to: UnsafePointer<B>.Type) > >> On Jun 26, 2016, at 11:39 PM, Dave Abrahams <[email protected]> wrote: >> is better. But I hate that the language doesn't give us a way to say >> “don't deduce generic parameters here.” This is the only syntax that >> feels right, IMO: >> >> let p = UnsafePointer<Int>(r) > > FWIW: I prefer to avoid the angle brackets, but it's not a battle that > needs to be fought over this feature.
Then you should lobby for removing them from the language :-). The way we do lossless conversions in Swift is with a label-less init that takes a single parameter. When you do that, you spell out the target type and follow it with parens. It doesn't make sense that it should work differently for UnsafePointer<Int> than it does for Int. > When experimenting with cast syntax, I found that passing type > parameters as function arguments was much more readable than using > generic type parameters, which I think obscure the signature. This > will be especially true when '.self' goes away. > >>> Option (3) UnsafeRawPointer.unsafeCast<T>(to: T.Type) -> >>> UnsafePointer<T> >> >> r.unsafeCast(to: Int.self) >> >> I don't see adding “unsafe” to the name of the operation as adding >> anything. It isn't any more unsafe than other UnsafeRawPointer >> operations. Also, it reads like we're casting the raw pointer to an >> Int, rather than to an UnsafePointer<Int>. > > Casting from a raw pointer to a typed pointer is only more dangerous > than other raw pointer operations because it is the first step in this > sequence of operations, which is undefined: > > ptrA = rawPtr.cast(to: UnsafePointer<A>.self) > ptrA.initialize(with: A()) > ptrA.deinitialize() > > ptrB = rawPtr.cast(to: UnsafePointer<B>.self) > ptrB.initialize(with: B()) But it's trivial to get undefined behavior without any of that. Just: _ = rawPtr.load(UnsafePointer<NonTrivialType>.self) boom. >> Also, how do you get an >> UnsafeMutablePointer? > > UnsafeRawPointer casts to UnsafePointer<T> > UnsafeMutableRawPointer casts to UnsafeMutablePointer<T> OK. >>> >>> Examples: >>> >>> --- >>> Case 1: casting a raw pointer as an argument >> >> >> >> foo(rawPtr.cast(to: UnsafePointer<A>.self)) >> >>> --- >>> Case 2: "recasting" a typed pointer argument >>> >>> >> >> foo(UnsafeRawPointer(ptrB).cast(to: UnsafePointer<A>.self)) >> >> I don't believe in making these “double-hops” concise. >> >>> --- >>> Case 3: Optional argument (only Option 3 is affected) >>> >> >> nullableFoo(UnsafeRawPointer(ptrB)?.cast(to: UnsafePointer<A>.self)) >> >> You do the above with a failable init on UnsafeRawPointer that takes an >> optional UnsafePointer. >> >>> --- >>> Case 4: Return values >>> >> >> return UnsafeRawPointer(foo()).cast(to: UnsafePointer<B>.self) >> >> -- >> -Dave > > Yes, that works. > > -Andy -- Dave _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
