cadence icon indicating copy to clipboard operation
cadence copied to clipboard

Dynamic casting should unwrap optional values

Open austinkline opened this issue 2 years ago • 2 comments

Current Behavior

Dynamic casting (failable casting as?, and force casting as!) an optional value (potentially type-erased to an existential) to a non-optional type currently fails (e.g. failable casting results in nil).

Expected Behavior

I expected (but perhaps shouldn't have) that an optional value being casted into a subtype it conforms to would unwrap it. I'm really not sure if this is a bug or if it's expected though

Steps To Reproduce

I've made a repro contract/transactions to demonstrate

https://github.com/austinkline/cadence-burner-bug

Environment

- Cadence version:Version: v1.15.0-cadence-v1.0.0-preview.12, Commit: c582e63baf4581e4cf021a9b1917c198ca5b6065
- Network: emulator

austinkline avatar Mar 20 '24 01:03 austinkline

Discord thread: https://discord.com/channels/613813861610684416/621847426201944074/1219773414949126234

j1010001 avatar Mar 20 '24 18:03 j1010001

I guess that makes sense. For example, Swift also supports unwrapping using casting:

let hello: String??? = "hello"
let something: Any = hello 
something as! String   // "hello" of type `String`

However, casting to Any does not:

something as! Any   // Optional(Optional(Optional("hello"))) of type `String???`

Then again, the behaviour does not seem to be about existential types, because those are also unwrapped:

protocol I {}

struct S: I {}

let hello: S???? = S()
let something: Any = hello 
something as! any I   // S() of type `S`, not `Optional(Optional(Optional(S())))` of type `S???`

turbolent avatar Mar 28 '24 15:03 turbolent