Regards (From mobile)
> On Jun 27, 2016, at 8:39 AM, Dave Abrahams <dabrah...@apple.com> wrote: > > > on Fri Jun 24 2016, Andrew Trick <atrick-AT-apple.com> wrote: > >>> On Jun 24, 2016, at 11:22 AM, Andrew Trick via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> >>>> On Jun 24, 2016, at 11:17 AM, L. Mihalkovic >>>> <laurent.mihalko...@gmail.com >>>> <mailto:laurent.mihalko...@gmail.com>> wrote: >>>> >>>> I like the watch-what-you-wish-for warning of unsafeCast. >>> >>> I’ll try porting stdlib to the “UnsafeRawPointer.unsafeCast(to: >>> T.Type)” syntax and see how bad it is. >> >> I don't think there's a clear winner here. Let me enumerate some >> options. >> >> Option (1) UnsafePointer<T>(cast: UnsafeRawPointer) > > The problem with this one is that T can be deduced based on type > context. I think we ought to move away from that for operations like > this one. > >> Option (2) UnsafePointer<T>(_: UnsafeRawPointer, to: T.self) > > I think you mean T.Type, not T.self, because this looks like a declaration. > > To evaluate, you have to look at the use-site: > > let p = UnsafePointer(r, to: Int.self) > > I don't find “to” to be descriptive enough. Maybe toType > > let p = UnsafePointer(r, pointee: Int.self) I find pointee a total aberation :) > > 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) > >> 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. It is unsafe in the sense that there are no guarantees that it is a sensible thing to do. I guess that means it is more 'noguaranteeexplicitorimpliedapplied' in the sense that it will like mechanically work, even if it produce an aberation as a result > Also, it reads like we're casting the raw pointer to an > Int, rather than to an UnsafePointer<Int>. Really good one... But then instead of 'to' or 'pointee', something along the lines of 'wrappedType', which lookes a little less balerina-ish than pointee..... > Also, how do you get an > UnsafeMutablePointer? > >> Option (4) unsafeCast(rawPointer: UnsafeRawPointer, to: T.self) -> >> UnsafePointer<T> > > This one won't read correctly for the same reasons as #3. > > r.cast(to: UnsafePointer<Int>.self) > > works better for me than any of the alternatives given our inability to > get the One True Syntax. > >> --- >> Option (3) is the most explicit and searchable, and forces >> UnsafeRawPointer to be spelled out in the conversion (unless you >> already have a raw pointer). > > Huh? I'm confused here. What you wrote looks like it's intended to be > a regular method, in which case of course invoking it would require a raw > pointer and wouldn't force you to write UnsafeRawPointer out anywhere. > > The only way it could force you to write UnsafeRawPointer would be if it > was a static method, but in that case it has too few arguments. > >> I like this because conceptually, you need to cast to a raw pointer >> before casting to a new pointee type, and casting a raw pointer to a >> typed pointer carries important semantics beyond simply converting to >> a typed pointer. The main problem with Option (3) is that optional raw >> pointers can't be converted naturally (without using `map`). > > r ?? someExpressionUsing(r!) > > best I can do. > >> Another thing I'm a little nervous about is confusing a cast of the >> pointer value with a cast of the pointee type: >> >> `unsafeBitCast(rawPtr, to: Int.self)` >> >> is very different from >> >> `rawPtr.unsafeCast(to: Int.self)` >> >> Does this need to be clarified? > > Yes! > >> If so, we can go back to the `toPointee` label that I proposed >> earlier. >> >> With that in mind, Option(4) is starting to look pretty good. >> >> Examples: >> >> --- >> Case 1: casting a raw pointer as an argument > > Use sites! (yay)... > >> func foo(_: UnsafePointer<A>) >> >> let rawPtr = UnsafeRawPointer(...) >> >> (1) foo(UnsafePointer(cast: rawPtr)) >> >> (2) foo(UnsafePointer(rawPtr, to: A.self)) >> >> (3) foo(rawPtr.unsafeCast(to: A.self)) >> >> (4) foo(unsafeCast(rawPointer: rawPtr, to: A.self)) > > > foo(rawPtr.cast(to: UnsafePointer<A>.self)) > >> --- >> Case 2: "recasting" a typed pointer argument >> >> Note that typed pointer arguments are implicitly cast to raw pointer >> arguments, so the conversion from PtrB to raw is implicit. >> >> func foo(_: UnsafePointer<A>) >> >> let ptrB = UnsafePointer<B>(...) >> >> (1) foo(UnsafePointer(cast: ptrB)) >> >> (2) foo(UnsafePointer(ptrB, to: A.self)) >> >> (3) foo(UnsafeRawPointer(ptrB).unsafeCast(to: A.self)) >> >> (4) foo(unsafeCast(rawPointer: ptrB, to: A.self)) > > 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) >> >> func nullableFoo(_: UnsafePointer<Int>?) >> >> let ptrB: UnsafePointer<UInt>? = ... >> >> (1) nullableFoo(UnsafePointer(cast: ptrB)) >> >> (2) nullableFoo(UnsafePointer(ptrB, to: A.self)) >> >> (3) nullableFoo(UnsafeRawPointer(ptrB).map { $0.unsafeCast(to: A.self) }) >> >> (4) nullableFoo(unsafeCast(rawPointer: ptrB, to: A.self)) > > 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 >> >> func foo() -> UnsafePointer<A> >> >> func caller() -> UnsafePointer<B> { ... >> >> (1) return UnsafePointer(cast: foo()) >> >> (2) return UnsafePointer(foo(), to: B.self) >> >> (3) let rawPtr = UnsafeRawPointer(foo()) >> return rawPtr.unsafeCast(to: B.self) >> >> (4) return unsafeCast(rawPointer: foo(), to: B.self) > > return UnsafeRawPointer(foo()).cast(to: UnsafePointer<B>.self) > > IMO-ly y'rs, > > -- > -Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution