Re: [swift-users] inline best practices?

2017-03-02 Thread Slava Pestov via swift-users
Here’s an overview of @inline(__always):

- It is an annotation for the performance inliner, which only runs in -O 
builds. The performance inliner uses heuristics to figure out what to inline, 
so most of the time explicit annotations are not necessary, and sometimes it 
won’t inline something even if its @inline(__always) — for example, inlining of 
generics is not enabled in 3.1 yet, because of code size concerns. We might 
change this behavior to make @inline(__always) mandatory one day.

- Public inline always functions have the additional behavior that they can be 
inlined into other modules, with caveats.

- In Swift 3.0, if a public inline always function references private symbols 
and is referenced from another module, you’ll get linker errors or a compiler 
crashes. In 3.1, we added diagnostics for this as part of the resilience model, 
but it’s totally a work in progress.

- The compiled body (more precisely, the SIL IR) for public inline always 
functions are serialized into the .swiftmodule file when a module is built with 
WMO.

- When building a library with WMO off, serialized SIL is simply discarded, 
which is a bug we intend on fixing.

- The @_transparent attribute is another low-level attribute that was never 
officially supported but some people have used it anyway. Transparent functions 
are inlined during mandatory optimizations, so you get it even in -Onone, 
subject to the same limitations on SIL serialization, what they can reference, 
etc. Transparent has other quirks around debug info and other things too. 
There’s a chance @_transparent will go away entirely. Please do not use it.

- There’s an @_inlineable attribute in master that’s a weaker form if 
@inline(__always). It enables the same restrictions on symbol references as 
@inline(__always), without changing the behavior of the performance inliner. 
This is needed because most of the time it’s not inlining you care about with 
generics, but being able to specialize the function body.

- The work on the library evolution model and ABI is centered on filling in the 
gaps in these attributes, documenting their behavior precisely and getting it 
all through swift-evolution — but there’s still a lot of heavy lifting left 
before we’re ready for that.

So the best practice is basically what Jordan said. Don’t use 
@inline(__always), @_inlineable, or @_transparent. But if you’re interested in 
helping with the design and implementation of these attributes, let us know.

Slava

> On Mar 2, 2017, at 4:27 PM, Erica Sadun via swift-users 
>  wrote:
> 
> Any best practices for `@inline(__always)`? When it's short? When has very 
> few call sites? When the abstraction aids reading but hinders computation?
> 
> Thanks -- E
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Is this really a race condition?

2017-03-02 Thread Edward Connell via swift-users
Not at all, thank you for trying it out.
When I run my code on the Mac in Xcode with thread sanitizer on, I don't
get any warnings or problems at all. I only find problems on Linux. I have
noticed that for the same release, the compiler and libraries are not
identical between Mac and Linux. I am currently using what I believe is the
latest release for both

$ swift --version
Swift version 3.0.2 (swift-3.0.2-RELEASE)
Target: x86_64-unknown-linux-gnu



On Thu, Mar 2, 2017 at 3:32 PM, Zhao Xin  wrote:

> I am sorry if this bothers you. I just put the original code in Xcode and
> it works. Anyone knows why this works in Xcode or in macOS? I thought it
> should show the same warnings as Linux.
>
> Zhaoxin
>
> On Fri, Mar 3, 2017 at 2:51 AM, Edward Connell via swift-users <
> swift-users@swift.org> wrote:
>
>> Hi Guillaume,
>> There is still a race condition report, but I think maybe we are almost
>> there. I had to modify your example because it didn't quite build, and a
>> loop to do it twice since it randomly complains if you only do it once.
>> Btw, this is on Linux.
>> The warning is triggered when deinitialize is called. It wasn't in your
>> example, but it seems that it is required since the Elements are not a
>> trivial type like Int.
>>
>> Thanks, Ed
>>
>> for _ in 0..<2 {
>> let count = 1000
>> let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
>> items.initialize(to: nil, count: count)
>>
>> DispatchQueue.concurrentPerform(iterations: count) {
>> items[$0] = [UInt8](repeating: 7, count: 10)
>> }
>>
>> items.deinitialize(count: count)
>> items.deallocate(capacity: count)
>> }
>>
>> ==
>> WARNING: ThreadSanitizer: data race (pid=24076)
>>   Write of size 8 at 0x7d0c5fa0 by main thread:
>> #0 free  (libtsan.so.0+0x00025819)
>> #1 _TwXxOs31_ClosedRangeIndexRepresentation 
>> (libswiftCore.so+0x0027e071)
>>
>>   Previous write of size 8 at 0x7d0c5fa0 by thread T20:
>> #0 malloc  (libtsan.so.0+0x000254a3)
>> #1 swift_slowAlloc  (libswiftCore.so+0x002ee3e5)
>>
>>   Thread T20 (tid=24288, running) created by main thread at:
>> #0 pthread_create  (libtsan.so.0+0x00027577)
>> #1 manager_workqueue_additem /home/buildnode/disk2/workspac
>> e/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-
>> libdispatch/libpwq/src/posix/manager.c:815 (libdispatch.so+0x0007c6b1
>> )
>>
>> SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free
>> ==
>>
>>
>> ThreadSanitizer: reported 1 warnings
>>
>>
>>
>> On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell 
>> wrote:
>>
>>> Ahh! thank you. That makes sense.
>>>
>>> On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard <
>>> gless...@tffenterprises.com> wrote:
>>>

 > On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users <
 swift-users@swift.org> wrote:
 >
 > The thread sanitizer on Linux is reporting that I have race
 conditions in libswiftcore. I eliminated enough code down to this trivial
 example. Is there really a race condition here or are these bogus errors?
 >
 >   let count = 1000
 >   var items = [[UInt8]?](repeating: nil, count: count)
 >
 >   DispatchQueue.concurrentPerform(iterations: count) {
 >   items[$0] = [UInt8](repeating: 7, count: 10)
 >   }
 >
 > My real scenario is retrieving data asynchronously, so I just threw
 in a buffer assignment.

 The assignments to array elements are where the race lies.

 I don’t know about the libswiftcore part, but: assigning to a shared
 Array concurrently from multiple threads won't work, because of Array's
 copy-on-write behaviour. You could do

 let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
 items.initialize(to: nil, count: count)

 DispatchQueue.concurrentPerform(iterations: count) {
   items[$0].initialize([UInt8](repeating: 7, count: 10))
 }

 // you’ll be able to see here that they’re all initialized

 items.deallocate(capacity: count)

 Cheers,
 Guillaume Lessard


>>>
>>
>> ___
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] inline best practices?

2017-03-02 Thread Erica Sadun via swift-users
Any best practices for `@inline(__always)`? When it's short? When has very few 
call sites? When the abstraction aids reading but hinders computation?

Thanks -- E

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Is this really a race condition?

2017-03-02 Thread Zhao Xin via swift-users
I am sorry if this bothers you. I just put the original code in Xcode and
it works. Anyone knows why this works in Xcode or in macOS? I thought it
should show the same warnings as Linux.

Zhaoxin

On Fri, Mar 3, 2017 at 2:51 AM, Edward Connell via swift-users <
swift-users@swift.org> wrote:

> Hi Guillaume,
> There is still a race condition report, but I think maybe we are almost
> there. I had to modify your example because it didn't quite build, and a
> loop to do it twice since it randomly complains if you only do it once.
> Btw, this is on Linux.
> The warning is triggered when deinitialize is called. It wasn't in your
> example, but it seems that it is required since the Elements are not a
> trivial type like Int.
>
> Thanks, Ed
>
> for _ in 0..<2 {
> let count = 1000
> let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
> items.initialize(to: nil, count: count)
>
> DispatchQueue.concurrentPerform(iterations: count) {
> items[$0] = [UInt8](repeating: 7, count: 10)
> }
>
> items.deinitialize(count: count)
> items.deallocate(capacity: count)
> }
>
> ==
> WARNING: ThreadSanitizer: data race (pid=24076)
>   Write of size 8 at 0x7d0c5fa0 by main thread:
> #0 free  (libtsan.so.0+0x00025819)
> #1 _TwXxOs31_ClosedRangeIndexRepresentation  (libswiftCore.so+
> 0x0027e071)
>
>   Previous write of size 8 at 0x7d0c5fa0 by thread T20:
> #0 malloc  (libtsan.so.0+0x000254a3)
> #1 swift_slowAlloc  (libswiftCore.so+0x002ee3e5)
>
>   Thread T20 (tid=24288, running) created by main thread at:
> #0 pthread_create  (libtsan.so.0+0x00027577)
> #1 manager_workqueue_additem /home/buildnode/disk2/
> workspace/oss-swift-3.0-package-linux-ubuntu-16_04/
> swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815 (libdispatch.so+
> 0x0007c6b1)
>
> SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free
> ==
>
>
> ThreadSanitizer: reported 1 warnings
>
>
>
> On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell 
> wrote:
>
>> Ahh! thank you. That makes sense.
>>
>> On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard <
>> gless...@tffenterprises.com> wrote:
>>
>>>
>>> > On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users <
>>> swift-users@swift.org> wrote:
>>> >
>>> > The thread sanitizer on Linux is reporting that I have race conditions
>>> in libswiftcore. I eliminated enough code down to this trivial example. Is
>>> there really a race condition here or are these bogus errors?
>>> >
>>> >   let count = 1000
>>> >   var items = [[UInt8]?](repeating: nil, count: count)
>>> >
>>> >   DispatchQueue.concurrentPerform(iterations: count) {
>>> >   items[$0] = [UInt8](repeating: 7, count: 10)
>>> >   }
>>> >
>>> > My real scenario is retrieving data asynchronously, so I just threw in
>>> a buffer assignment.
>>>
>>> The assignments to array elements are where the race lies.
>>>
>>> I don’t know about the libswiftcore part, but: assigning to a shared
>>> Array concurrently from multiple threads won't work, because of Array's
>>> copy-on-write behaviour. You could do
>>>
>>> let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
>>> items.initialize(to: nil, count: count)
>>>
>>> DispatchQueue.concurrentPerform(iterations: count) {
>>>   items[$0].initialize([UInt8](repeating: 7, count: 10))
>>> }
>>>
>>> // you’ll be able to see here that they’re all initialized
>>>
>>> items.deallocate(capacity: count)
>>>
>>> Cheers,
>>> Guillaume Lessard
>>>
>>>
>>
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Using withUnsafePointer on char arrays within C structs

2017-03-02 Thread Hooman Mehr via swift-users
Yes, the easiest way is to rely on compiler magic for ObjC/C interoperability, 
but it is also important to know what is really happening.

My preferred version of the compiler magic is this actually:

func allZerosUUID() -> String {

return NSUUID(uuidBytes: [UInt8](repeating: 0, count: 32)).uuidString
}

Which is effectively this:

func allZerosUUID() -> String {

let allZeros = [UInt8](repeating: 0, count: 32)

return NSUUID(uuidBytes: allZeros).uuidString
}

(Note the use of let and absence of &).

> On Mar 2, 2017, at 1:33 PM, Russell Finn  wrote:
> 
> I agree that the use of `withUnsafeBufferPointer` to get to the contents of 
> an array makes more sense than `withUnsafePointer`, once you discover the 
> concept of a "buffer pointer" (which a new Swift programmer may not do at 
> first).
> 
> However, I note that the following code:
> 
> func allZerosUUID() -> String {
> var allZeros = [UInt8](repeating: 0, count: 32)
> return NSUUID(uuidBytes: )
> }
> 
> also compiles without error and returns the intended value. This appears to 
> be supported by the "Constant Pointers" section of the "Interacting with C 
> APIs" chapter of "Using Swift with Cocoa and Objective-C":  "When a function 
> is declared as taking an `UnsafePointer` argument, it can accept ... a 
> `[Type]` value, which is passed as a pointer to the start of the array."
> 
> I suspect the availability of `` in this context, coupled with an 
> awareness of the existence of `withUnsafePointer(to:)`, is what led my 
> co-worker down the wrong road (and to a puzzling error message); but since we 
> have now discovered two more appropriate ways to write the code in question, 
> perhaps it's not worth worrying about too much.
> 
> Thanks to everyone for the discussion.
> 
> 
> On Wed, Mar 1, 2017 at 7:36 PM, Hooman Mehr  > wrote:
> Your co-worker needs to get passed the learning curve of these “unsafe” APIs 
> and note that Swift arrays are complex data structures.  does not 
> give you a pointer to a bunch of zero bytes, but a pointer to a struct that 
> contains the private implementation details of allZeros array. 
> 
> Here is the correct way to do it:
> 
> func allZerosUUID() -> String {
> 
> let allZeros = [UInt8](repeating: 0, count: 32)
> 
> return allZeros.withUnsafeBufferPointer { NSUUID(uuidBytes: 
> $0.baseAddress).uuidString }
> }
> 
> 
>> On Mar 1, 2017, at 2:35 PM, Russell Finn via swift-users 
>> > wrote:
>> 
>> Thanks to Joe and Quinn for their answers. I have a related followup — a 
>> co-worker learning Swift wrote the following function:
>> 
>> func allZerosUUID() -> String {
>> var allZeros = [UInt8](repeating: 0, count: 32)
>> return withUnsafePointer(to: ) { zerosPtr in
>> return NSUUID(uuidBytes: zerosPtr).uuidString
>> }
>> }
>> 
>> but was puzzled that Xcode 8.2.1 gave an error "Cannot convert value of type 
>> 'UnsafePointer<_>' to expected argument type 'UnsafePointer!'" on the 
>> line with the NSUUID initializer.  Their expectation was that `zerosPtr` 
>> would be of type `UnsafePointer` because `allZeros` is of type 
>> `[UInt8]`.  
>> 
>> They discovered that they could work around this by adding a call to 
>> `withMemoryRebound`:
>> 
>> func allZerosUUID() -> String {
>> var allZeros = [UInt8](repeating: 0, count: 32)
>> return withUnsafePointer(to: ) { zerosPtr in
>> zerosPtr.withMemoryRebound(to: UInt8.self, capacity: 
>> allZeros.count) { zerosPtr in
>> return NSUUID(uuidBytes: zerosPtr).uuidString
>> }
>> }
>> }
>> 
>> but felt that this should be unnecessary. Perhaps I'm missing something 
>> simple, but I was unable to explain this compiler behavior; can anyone on 
>> the list do so?
>> 
>> (Yes, I did point out that they could pass `` directly to 
>> `NSUUID(uuidBytes:)`.)
>> 
>> Thanks — Russell
>> 
>> ___
>> swift-users mailing list
>> swift-users@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-users 
>> 
> 
> 

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Using withUnsafePointer on char arrays within C structs

2017-03-02 Thread Russell Finn via swift-users
I agree that the use of `withUnsafeBufferPointer` to get to the contents of
an array makes more sense than `withUnsafePointer`, once you discover the
concept of a "buffer pointer" (which a new Swift programmer may not do at
first).

However, I note that the following code:

func allZerosUUID() -> String {
var allZeros = [UInt8](repeating: 0, count: 32)
return NSUUID(uuidBytes: )
}

also compiles without error and returns the intended value. This appears to
be supported by the "Constant Pointers" section of the "Interacting with C
APIs" chapter of "Using Swift with Cocoa and Objective-C":  "When a
function is declared as taking an `UnsafePointer` argument, it can
accept ... a `[Type]` value, which is passed as a pointer to the start of
the array."

I suspect the availability of `` in this context, coupled with an
awareness of the existence of `withUnsafePointer(to:)`, is what led my
co-worker down the wrong road (and to a puzzling error message); but since
we have now discovered two more appropriate ways to write the code in
question, perhaps it's not worth worrying about too much.

Thanks to everyone for the discussion.


On Wed, Mar 1, 2017 at 7:36 PM, Hooman Mehr  wrote:

> Your co-worker needs to get passed the learning curve of these “unsafe”
> APIs and note that Swift arrays are complex data structures.  does
> not give you a pointer to a bunch of zero bytes, but a pointer to a struct
> that contains the private implementation details of allZeros array.
>
> Here is the correct way to do it:
>
> func allZerosUUID() -> String {
>
> let allZeros = [UInt8](repeating: 0, count: 32)
>
> return allZeros.withUnsafeBufferPointer { NSUUID(uuidBytes: $0.
> baseAddress).uuidString }
> }
>
>
> On Mar 1, 2017, at 2:35 PM, Russell Finn via swift-users <
> swift-users@swift.org> wrote:
>
> Thanks to Joe and Quinn for their answers. I have a related followup — a
> co-worker learning Swift wrote the following function:
>
> func allZerosUUID() -> String {
> var allZeros = [UInt8](repeating: 0, count: 32)
> return withUnsafePointer(to: ) { zerosPtr in
> return NSUUID(uuidBytes: zerosPtr).uuidString
> }
> }
>
> but was puzzled that Xcode 8.2.1 gave an error "Cannot convert value of
> type 'UnsafePointer<_>' to expected argument type 'UnsafePointer!'"
> on the line with the NSUUID initializer.  Their expectation was that
> `zerosPtr` would be of type `UnsafePointer` because `allZeros` is of
> type `[UInt8]`.
>
> They discovered that they could work around this by adding a call to
> `withMemoryRebound`:
>
> func allZerosUUID() -> String {
> var allZeros = [UInt8](repeating: 0, count: 32)
> return withUnsafePointer(to: ) { zerosPtr in
> zerosPtr.withMemoryRebound(to: UInt8.self, capacity:
> allZeros.count) { zerosPtr in
> return NSUUID(uuidBytes: zerosPtr).uuidString
> }
> }
> }
>
> but felt that this should be unnecessary. Perhaps I'm missing something
> simple, but I was unable to explain this compiler behavior; can anyone on
> the list do so?
>
> (Yes, I did point out that they could pass `` directly to
> `NSUUID(uuidBytes:)`.)
>
> Thanks — Russell
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Is this really a race condition?

2017-03-02 Thread Edward Connell via swift-users
Hi Guillaume,
There is still a race condition report, but I think maybe we are almost
there. I had to modify your example because it didn't quite build, and a
loop to do it twice since it randomly complains if you only do it once.
Btw, this is on Linux.
The warning is triggered when deinitialize is called. It wasn't in your
example, but it seems that it is required since the Elements are not a
trivial type like Int.

Thanks, Ed

for _ in 0..<2 {
let count = 1000
let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

items.deinitialize(count: count)
items.deallocate(capacity: count)
}

==
WARNING: ThreadSanitizer: data race (pid=24076)
  Write of size 8 at 0x7d0c5fa0 by main thread:
#0 free  (libtsan.so.0+0x00025819)
#1 _TwXxOs31_ClosedRangeIndexRepresentation 
(libswiftCore.so+0x0027e071)

  Previous write of size 8 at 0x7d0c5fa0 by thread T20:
#0 malloc  (libtsan.so.0+0x000254a3)
#1 swift_slowAlloc  (libswiftCore.so+0x002ee3e5)

  Thread T20 (tid=24288, running) created by main thread at:
#0 pthread_create  (libtsan.so.0+0x00027577)
#1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x0007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free
==


ThreadSanitizer: reported 1 warnings



On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell  wrote:

> Ahh! thank you. That makes sense.
>
> On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard <
> gless...@tffenterprises.com> wrote:
>
>>
>> > On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users <
>> swift-users@swift.org> wrote:
>> >
>> > The thread sanitizer on Linux is reporting that I have race conditions
>> in libswiftcore. I eliminated enough code down to this trivial example. Is
>> there really a race condition here or are these bogus errors?
>> >
>> >   let count = 1000
>> >   var items = [[UInt8]?](repeating: nil, count: count)
>> >
>> >   DispatchQueue.concurrentPerform(iterations: count) {
>> >   items[$0] = [UInt8](repeating: 7, count: 10)
>> >   }
>> >
>> > My real scenario is retrieving data asynchronously, so I just threw in
>> a buffer assignment.
>>
>> The assignments to array elements are where the race lies.
>>
>> I don’t know about the libswiftcore part, but: assigning to a shared
>> Array concurrently from multiple threads won't work, because of Array's
>> copy-on-write behaviour. You could do
>>
>> let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
>> items.initialize(to: nil, count: count)
>>
>> DispatchQueue.concurrentPerform(iterations: count) {
>>   items[$0].initialize([UInt8](repeating: 7, count: 10))
>> }
>>
>> // you’ll be able to see here that they’re all initialized
>>
>> items.deallocate(capacity: count)
>>
>> Cheers,
>> Guillaume Lessard
>>
>>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Proper Way to make Errors in Swift 3

2017-03-02 Thread Ronak via swift-users
Hi everyone,

It looks like I’m still having issues exposing a CustomNSError to Objective-C. 
I am generating errors of this type in Swift and then trying to bridge them in 
one direction over to Objective-C.
From Objective-C, this Error type is being exposed as a _SwiftValue.

Do I have to mark this error as @objc and switch to using a raw enum? If so, I 
fail to see the benefit of using CustomNSError or any of the new error related 
protocols from Swift -> Objective-C.

Here’s my implementation:

public enum MyError: CustomNSError, Equatable {

  case one([String : Any])

  case two([String : Any])

  case three([String : Any])

  /// The domain of the error.
  public static var errorDomain: String {
return “MyError"
  }

  /// The error code within the given domain.
  public var errorCode: Int {
switch self {
case .one:
  return 5
case .two:
  return 50001
case .three:
  return 50002
}
  }

  /// The user-info dictionary.
  public var errorUserInfo: [String : Any] {
var userInfo = [String: Any]()
if case let .one(info) = self {
  userInfo = info
} else if case let .two(info) = self {
  userInfo = info
} else if case let .three(info) = self {
  userInfo = info
}

return userInfo
  }
}

Thanks

Ronak

> On Sep 29, 2016, at 5:46 PM, Ronak via swift-users  
> wrote:
> 
> Ahh..thanks for the reply Zach. I didn’t actually see your reply until now.
> 
> I’ll see how I can adjust my code.
> 
> Thanks for this!
> 
> 
>> On Sep 29, 2016, at 4:38 PM, Zach Waldowski > > wrote:
>> 
>> Error types themselves shouldn’t generally cross into Objective-C, because 
>> you don’t get interop; for that, we have Error, which crosses the bridge as 
>> NSError.
>> 
>> If it’s instructive to think of it this way, both Objective-C and Swift 
>> should define errors in their best native way, and use NSError. That’s, at 
>> least, the use case for CustomNSError and LocalizedError.
>> 
>> If you’re primarily exporting errors from Objective-C to be “seen” in Swift, 
>> you want to look into the ns_error_domain attribute on the C side. This 
>> generates a good deal of the enum Code: Int boilerplate coming in to Swift, 
>> but it’s obnoxious to create those errors from Swift.
>> 
>> If you’re primarily exporting errors from Swift to Objective-C, you can make 
>> any Swift type implement Error and CustomNSError, which can then cross the 
>> bridge.
>> 
>> The happy path of full error interop in both directions is a little more 
>> complicated. Generally you have to start with one of the above approach and 
>> “mirror” some values in the other language. Consider the following as a 
>> slightly over-wrought example of having your cake and eating it too:
>> 
>> extern NSString *const MyErrorDomain NS_REFINED_FOR_SWIFT;
>> extern NSString *const MyErrorUserInfoStringKey NS_REFINED_FOR_SWIFT;
>> 
>> typedef NS_ENUM(NSInteger, MyErrorCode) {
>> MyErrorCodeOne,
>> MyErrorCodeTwo,
>> MyErrorCodeThree,
>> } NS_REFINED_FOR_SWIFT;
>> 
>> enum MyError: CustomNSError {
>> 
>> case one(String)
>> case two
>> case three
>> 
>> static var errorDomain: String {
>> return __MyErrorDomain
>> }
>> 
>> var errorCode: Int {
>> switch self {
>> case .one:
>> return __MyErrorCode.one.rawValue
>> case .two:
>> return __MyErrorCode.two.rawValue
>> case .three:
>> return __MyErrorCode.three.rawValue
>> }
>> }
>> 
>> var errorUserInfo: [String: Any] {
>> var userInfo = [String: Any]()
>> if case let .one(string) = self {
>> userInfo[__MyErrorUserInfoStringKey] = string
>> }
>> return userInfo
>> }
>> 
>> }
>> 
>>> On Sep 29, 2016, at 1:17 PM, Ronak via swift-users >> > wrote:
>>> 
>>> Hello all,
>>> 
>>> We are proceeding to update all of our Swift code to Swift 3 now and had a 
>>> few questions about the proper way to implement Errors. We need these 
>>> entities to be available in Objective-C and they are actively being used in 
>>> Swift classes marked as @objc.
>>> 
>>> I read: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
>>>  
>>> 
>>>  completely and came up with this implementation:
>>> 
>>> 
>>> /// The enumeration of the possible error codes in the Foundation error 
>>> domain
>>> @objc public class FoundationError: NSObject, CustomNSError {
>>> 
>>> /// The underlying error code
>>> private let code: FoundationError.Code
>>> 
>>> /// The type of an error code.
>>> @objc public enum Code: Int {
>>> 
>>> /// An ARCOperationCondition failed during evaluation
>>> case operationConditionFailed = 1
>>> 
>>>