How Can I represent Silver String / Integer literals as the Hashable interface / protocol?

Normally Swift strings + integers already conform to the ‘Hashable’ protocol.

Lets say I have a swift function declared as

public func foo<T: Hashable>(_ bar: T) -> BarContainer<T> {
    return BarContainer<T>(bar)
}

In swift I can simply assign a variable as:

let test: BarContainer<String> = foo("myString")
let test2: BarContainer<Int> = foo(0)

Silver complains though saying those literals don’t conform. I tried even creating an extension against ‘Any’ for Hashable but still no dice.

Those literals have the type System.String / System.Integer etc’ which is expected since they’re coming from the CLR. Do I have to do anything special for those CLR literals to be recognized as Hashable (or the IHashable interface you guys have?)

Thank you, this looks like the last problem I’m having with the port of my code over to Silver

This is a bit trickty, as these types map to CLR types we cannot change. You should be able to add interfaces (protocols) in an extension, but there are limitations to what works with in that, as extensions are compile-time magic, and disappear at runtime.

can you send me a minimal test case for what you are trying to accomplish, as a starting point for me t have a look at this? thanx!

[Deleted]

you’ll see the failure Under MockCombineDmtModel.swift when you run the solution. Ergonomically it would be best to recognize the literals as Hashable. I suppose I can always box them with a container class / struct, but I’d rather not.

Thanks!

Can you narrow this down to for me to a simple console project with just the one class/method needed to show the issue? thanx!

No problem, here ya go

HashableLiteralTest.zip (325.5 KB)

1 Like

Thanx!

I’m afraid it’s what I thought. because String & co are native CLR types, theres no way to add protocol compliance to them in a way what would work with the generics system. What’s more, there’s also no default “IHashable” interface in .NET that we cukld try and co-opt that System.String would already implement (think look different for IEquatable, which right now has the same issue, but does have a .NET equivalent we could look at somehow mapping to.

The best an extension adding a protocol could give you is support for this, as this is handled at compile time.

extension String : Hashable {
    var hashValue: Int { return 0 }
}

let x: Hashable = ""

(this code has a separate/unrelated bug right now, which I have logged as E26015: Two issues with implementing protocol in extension).

I’ll check with the team for ideas, but I’m afraid the answer here will be “sorry, this just wont work”. at least not until/unless we replace Swift.String with the (already existing in SBL) public struct SwiftString, but thats something I had for now even up on because it caused all kinds of problems…

1 Like

FWIW, SwiftString should be usable; its just not the default string type with SBL yet. If you wanna give it a spin, id appreciate your feedback. I’ve just added Hashable support to it, too

Im having a little trouble getting SwiftString working in the example I sent above, I tried extending Hashable to SwiftString but it seems to be failing on the constraint against ‘is class’

Yeah, SwiftString, like String in Apple Swift, is a struct not a class. TBH thats the whole main point while we wanna introduce it. You cant constrain on is class and use SwiftString, that won’t work (“as designed”).

1 Like

Thanks for your time. I found a work around for a similar style I was going for by wrapping these literals in a box while also exposing other functions accepting explicitly defined literals as parameters. Should still adhere to the design of the code I was looking for!

Cool, happy to hear!