Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AnyHashable type-erasing behaves differently on Linux #77508

Open
tomsci opened this issue Nov 9, 2024 · 3 comments
Open

AnyHashable type-erasing behaves differently on Linux #77508

tomsci opened this issue Nov 9, 2024 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. casting Feature: explicit casting (is, as, as? and as!) Foundation Linux Platform: Linux transfer candidate The issue may belong in another repository

Comments

@tomsci
Copy link

tomsci commented Nov 9, 2024

Description

On the linux build of Swift, AnyHashable does not appear to have the type-erasing semantics that it does on macOS and iOS. On those platforms, any type of integer converted to an AnyHashable can then be converted to any other type of integer (providing it fits), whereas on linux, you can only convert it back to the original type.

Reproduction

let i: Int32 = 1
let a = i as AnyHashable
let oi = a as? Int8 // This conversion succeeds on macOS/iOS, fails on linux

Expected behavior

Expected the as? Int8 to succeed and return Optional<Int8>(1) on all platforms. It only succeeds on macOS and iOS, and returns nil on linux.

Environment

Swift version 5.10.1 (swift-5.10.1-RELEASE)
Ubuntu 22.04.5 LTS

Additional information

Tested using the following github actions job: tomsci/LuaSwift#7
The issue was found during the development of tomsci/LuaSwift#6 which necessitated a lot of additional code to compensate for the difference in behaviour of AnyHashable.

@tomsci tomsci added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Nov 9, 2024
@tbkka
Copy link
Contributor

tbkka commented Nov 11, 2024

I believe this is a side-effect of Foundation NSNumber support. NSNumber supports casting to/from every numeric type, and as a side-effect, allows certain other casts to do the same.

@tomsci
Copy link
Author

tomsci commented Nov 11, 2024

Yikes that's a pretty big side effect, modifying the entire runtime's behaviour to support a single Foundation type! It's not like one can avoid using Foundation (in any non-trivial project) and Foundation does exist on Linux but doesn't exhibit this behaviour (I ran the same unit tests on both platforms, explicitly importing Foundation on both) so is the bug here that the linux implementation doesn't faithfully replicate this quirk?

If I'm understanding that right, it's very weird to hear that the way the language is supposed to behave isn't the way it actually behaves in 99% of projects. Is this formalised somewhere? Is the NSNumber modifying other casts behaviour considered a bug? It makes me wonder, why are integers castable to and from NSNumber in Swift? Toll-free-bridging made sense in Objective-C to and from CoreFoundation but I can't really think of any reason why I'd want this in Swift code...?

@tbkka
Copy link
Contributor

tbkka commented Nov 11, 2024

Differences between Foundation on Linux and macOS should be reported against Foundation, I think. CC: @parkera

@AnthonyLatsis AnthonyLatsis added Linux Platform: Linux Foundation transfer candidate The issue may belong in another repository casting Feature: explicit casting (is, as, as? and as!) and removed triage needed This issue needs more specific labels labels Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. casting Feature: explicit casting (is, as, as? and as!) Foundation Linux Platform: Linux transfer candidate The issue may belong in another repository
Projects
None yet
Development

No branches or pull requests

3 participants