Enum-like struct doesn't compile with switch statement

I have the following struct:

public struct MessageType: RawRepresentable, Equatable, Hashable, Comparable {

    //  RawRepresentable
    public typealias RawValue = String
    public var rawValue: String

    //  Equatable
    public static func ==(lhs: MessageType, rhs: MessageType) -> Bool {
        return lhs.rawValue == rhs.rawValue
    }
        
    //  Hashable
    public var hashValue: Int {
        return rawValue.hashValue
    }

    //  Comparable
    public static func <(lhs: MessageType, rhs: MessageType) -> Bool {
        return lhs.rawValue < rhs.rawValue
    }
        
    public init(rawValue aRawValue: String) {
        self.rawValue = aRawValue
    }

    public static let unknown = MessageType(rawValue: "unknown")
}

which is extended in various source files like this:

extension MessageType {
    public static let serverStarted = MessageType(rawValue: "serverStarted")
    public static let serverStopped = MessageType(rawValue: "serverStopped")
}

I then use it like this:

public struct Message {
    public var type: MessageType
}

public class MessageReceiver {
    public func processMessage(_ aMessage: Message) {
        switch aMessage.type {
            case .serverStarted:
                return  //  ... or do something
            default:
                return
        }
    }
}

Unfortunately, the switch statement only compiles in XCode, so in Fire I have to use this:

if aMessage.type == .serverStarted {
    //  Do something...
}

Also, Fire forces me to redeclare public init(rawValue aRawValue: String), whereas XCode is happy without it.

Update

There is also an issue with type inference, so I prepared a test project with all issues.

EnumLikeStructTest.zip

Oh, and constructor issue described above somehow went away, I don’t know how and why. :thinking:

Update 2

The constructor was actually required by XCode, I updated the test project.

EnumLikeStructTest.zip (451.8 KB)

Ok? Kinda tough to comment without either a complete project or at least knowing the error message Elements gives you.

define “force you”?

—marc

ps: all of these are issues for the Silver compiler, not Fire the IDE.

Same for this: can you elaborate on what “an issue” means, precisely? your project compiles clean here, no errors no warnings, so it doesn’t illustrate any of the problems you mention here…

But Marc, test project with all the issues is attached under Update 2, before the last two of your messages. AFAIK it covers everything I mentioned.

No it doesnt:

 Solution 'EnumLikeStructTest' built successfully.

Ah, got it now. I keep forgetting I don’t have the latest issue. Mine is 2385 (last release) and beta is 2391, I think.

Look, I really don’t want to nag here and the tone of your replies feels like you’re a bit annoyed by my (potential) bug reports. I know I’m not a paying customer so my goal was to give you guys some feedback to help you improve Silver and Fire. There’s always a way to bypass the issues and wait for the next release. That would be faster anyway because sometimes it takes time to compile a project for you guys. Anyway, that was my idea of “paying” for my usage of Silver until I can become a paying customer again. Right now I can’t afford it.

Please let me know if you would like me to report on issues with Silver in the future.

I commented out the stuff that doesn’t work, maybe that’s why it compiles for you.

Niko, I’m not annoyed by your bug reports; we welcome reports, as the only way we can fix these issues is by getting this feedback.

But to help you out, I need to know what actually fails. The two issues in the original thread, the entire description was, literally “does not compile”, without a concrete error message or a full code that would allow me to obtain the error message myself. The project you attached compiles clean for me.

Just from the 5 lines of switch statement without context, I have no way of guessing how it might fail for you, just as I have no idea of guessing where you might be forced to declare the public init you mention.

At the very least, if you provide the error messages that you get, I have something to work on. (which Fire makes really easy, just use Cmd+Option+C to copy the code snippet, and the messages will be copied along.

2391 is the latest from yesterday, yes.

Please do, yes, but please include the actual errors you get in the report.

That may very well be it, yes ;).

Can I get a project where the stuff that fails actually does fail; then we can have a look.

thanx!

Sorry, I’m a bit confused here, so please confirm, even if you remove the comments, as in the screenshot, it compiles for you in 2391?

I didn’t make any changes to your project. I opened it as tis, hit build, and it compiled without errors. Please send me a copy that shows the errors as-is, and I’ll have a look and log an issue if needed.

Coming up in a few minutes.

Comments from Android/NetStandard project removed.

I also added an XCode project so you can see that it fails to compile without MessageType constructor. Fire doesn’t mind not having a constructor. So once again, a situation where this could be a bug in Fire for compiling without constructor, or in XCode for not compiling without it.

Please confirm if both solutions, Fire and XCode, now fail to compile for you.

EnumLikeStructTest.zip (476.3 KB)

Thanx. I get 6 errors now:

EnumLikeStructTest.Android: Test.swift, line 51 — (E64) Type mismatch, cannot find operator to evaluate "MessageType" = "MessageType"
EnumLikeStructTest.NetStandard: Test.swift, line 51 — (E64) Type mismatch, cannot find operator to evaluate "MessageType" = "MessageType"
EnumLikeStructTest.Android: Test.swift, line 52 — (E65) Constant value expected
EnumLikeStructTest.NetStandard: Test.swift, line 52 — (E65) Constant value expected
EnumLikeStructTest.Android: Test.swift, line 61 — (E486) Parameter 1 is "<array literal>", should be "Swift.Array<MessageType>", in call to func ParamTestClass!.testParams(_ aParams: Swift.Array<MessageType>)
EnumLikeStructTest.NetStandard: Test.swift, line 61 — (E486) Parameter 1 is "<array literal>", should be "Array<MessageType>", in call to func ParamTestClass!.testParams(_ aParams: Array<MessageType>)

lets see:

switch aMessage.type { // E64 Type mismatch, cannot find operator to evaluate "MessageType" = "MessageType"

MessageType is struct, I believe you’d need to implement == in order for equality to work, not just Equal. I’ll check with Carlo what we can do to make this work (and if making that work without == operator is actually the right thing to do.

case .serverStarted: // E65 Constant value expected

is as expected, I believe. Switch cases must always be constant afaik, and serverStarted is not.

ptc.testParams([.serverStarted, .serverStopped]) // E486 Parameter 1 is "<array literal>", should be "Swift.Array<MessageType>", in call to func ParamTestClass!.testParams(_ aParams: Swift.Array<MessageType>)

definitely looks like a bug with type inference for the array literal; I’ll log.

Thanks, logged as bugs://82237 (for switch compatibility)

Thanks, logged as bugs://82238 (for the array literal issue)

It compiles in XCode, so maybe it’s worth looking into? Without it even switch compatibility kind of doesn’t make sense.

What else is missing in code below? I’m not an expert on Swift internals so I didn’t quite understand what you meant by "implement == in order for equality to work, not just Equal".

public struct MessageType: RawRepresentable, Equatable, Hashable, Comparable {
    //  Equatable
    public static func ==(lhs: MessageType, rhs: MessageType) -> Bool {
        return lhs.rawValue == rhs.rawValue
    }
}

I think marc overlooked that one, but that should indeed have sufficed. I’m investigating the issue now.