let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 25 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
let i: Int = 5 let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 29 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
integer let i: Int = 5 let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 30 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
-- at runtime, we check the type metadata for a let i: Int = 5 let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 31 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
-- and can be used with zero overhead let i: Int = 5 let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 32 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
let a: Any = i as Any if let really_i = a as? Int { print("this works! i is \(really_i)") } 34 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
cast from Int Any ⇢ Int is a non-existential type, Any is existential ⇢ Compiler generates a "promotion" for 5, and stores it as a separate instance 36 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
is allocated ⇢ Points to type metadata ⇢ Which also points to "thunks" for protocol witnesses ⇢ Points to (or copies) the underlying value 37 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
if t is Int { printf("t is an Int!!\n") } return t as Int } func duplicate(_ t: Any) -> Any { return t as Int * 2 } 42 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
var v: Any = 1 if !(v is Bool) { printf("v: %d\n", v as Int) } v = true if v is Bool { printf("v: %s\n", v as Bool ? "true" : "false") } v = Foo(bar: 20, baz: true) if v is Foo { let foo = v as Foo printf("v: Foo(bar: %d, baz: %s)\n", foo.bar, foo.baz ? "true" : "false") } printf("[%s] foo returned\n", #function) printf("%d\n", f) printf("%d\n", duplicate(2) as Int) } 43 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018
.any = type { if storage(for: type) == .reference { // If we're promoting an existing Any value of a reference type, just // thread it through. return value } else { // If we're promoting an existing Any value of a value type, // then this should just be a copy of the existing value. return codegenCopyAny(value: value) } } let allocateAny = codegenIntrinsic(named: "trill_allocateAny") let meta = codegenTypeMetadata(type) let castMeta = builder.buildBitCast(meta, type: PointerType.toVoid, name: "mc") let res = builder.buildCall(allocateAny, args: [castMeta], name: "aa") let valPtr = codegenAnyValuePtr(res, type: type) builder.buildStore(value, to: valPtr) return res } 46 — Answering the Existential Question – Samuel Giddins @ FrenchKit 2018