I'm starting to understand. The implementation of RawRepresentable's probably 
looks like this:

init?(rawValue: String) {
    switch rawValue {
    case "firstValue": self = .FirstCase
    case "secondValue": self = .SecondCase
    default: return nil
    }
}

In that case (no pun intended), the switch cases are converted to 
SomeStringLiteralConvertibleType and then pattern matched.

But shouldn't the implementation of switch refrain from any complicated casting 
when the types correspond?

David.

> On 06 Jan 2016, at 10:20, David Hart via swift-evolution 
> <swift-evolut...@swift.org> wrote:
> 
> To bring a little bit more context: I copied this Regex library in my project 
> which had StringLiteralConvertible and implemented the pattern matching 
> operator and all of a sudden, ALL init(rawValue: String) calls of completely 
> unrelated enums started returning unexpected values. If I did not have unit 
> tests, I probably would not have found out about it for a while.
> 
> I understand the mechanism which calls StringLiteralConvertible's 
> init(stringLiteral) under the hood:
> 
> let a: SomeStringLiteralConvertibleType = "hello"
> 
> I also understand the magic in the pattern matching operator. But I don't 
> understand why when associating them together:
> 
> func ~=(lhs: SomeStringLiteralConvertibleType, rhs: String) -> Bool {
>     return false
> }
> 
> Then creates his behaviour in all Enums with String raw values:
> 
> enum MyEnum: String {
>     case Super = "super"
> }
> 
> let a = MyEnum(rawValue: "super") // nil
> 
> I can't figure out if this is just a confusing behaviour of Swift, in which 
> case I want to write a proposal to make it less confusing, or if it is a big 
> with Swift, in which case I should open a bug report.
> 
> David
> 
>> On 05 Jan 2016, at 18:26, David Hart via swift-users <swift-users@swift.org> 
>> wrote:
>> 
>> How is it that Swift allows code like this:
>> 
>> struct Sneaky: StringLiteralConvertible {
>>      init(stringLiteral value: String) {}
>>      init(extendedGraphemeClusterLiteral value: String) {}
>>      init(unicodeScalarLiteral value: String) {}
>> }
>> 
>> func ~=(sneaky: Sneaky, string: String) -> Bool {
>>      return false
>> }
>> 
>> enum NormalEnum: String {
>>      case Super = "super"
>>      case Mario = "mario"
>> }
>> 
>> let value = NormalEnum(rawValue: "super”) // return nil!!!!
>> 
>> It hit completely by surprise today because of of a Regex library:
>> 
>> struct Regex: StringLiteralConvertible {
>>      init(stringLiteral value: String) {}
>>      init(extendedGraphemeClusterLiteral value: String) {}
>>      init(unicodeScalarLiteral value: String) {}
>> 
>>      //...
>> }
>> 
>> func ~=(regex: Regex, string: String) -> Bool {
>>      return regex.matches(string)
>> }
>> 
>> If I was not already a Swift enthusiast, this behaviour would have left me 
>> completely dumbfounded.
>> What can we do about it?
>> 
>> David.
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolut...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to