[pigeon] removes safe casting from nullables in kotlin and swift#3284
[pigeon] removes safe casting from nullables in kotlin and swift#3284auto-submit[bot] merged 7 commits intoflutter:mainfrom
Conversation
| if let aNullableEnumRawValue = list[12] as? Int { | ||
| if let aNullableEnumRawValue = list[12] as! Int? { | ||
| aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue) | ||
| } |
There was a problem hiding this comment.
you can avoid the var by either
let aNullableEnum: AnEnum?
if ... {
aNullableEnum = ...
} else {
aNullableEnum = nil
}
or using a map:
let aNullableEnum = (list[12] as! Int?).map { AnEnum(rawValue: $0) }
| func testAllEquals() throws { | ||
| let everything = AllNullableTypes( | ||
| aNullableBool: false, | ||
| aNullableBool: true, |
There was a problem hiding this comment.
were you able to resolve the Bool type issue the other day? What was the fix?
There was a problem hiding this comment.
switching from Any? to Any
There was a problem hiding this comment.
Can you provide more details? Not sure which Any? you are referring to.
There was a problem hiding this comment.
it's the same decode issue as the other comments I've replied to
| let a8ByteArray = list[5] as! FlutterStandardTypedData | ||
| let aFloatArray = list[6] as! FlutterStandardTypedData | ||
| let aList = list[7] as! [Any?] | ||
| let aList = list[7] as! [Any] |
There was a problem hiding this comment.
do we want to test out both [Any?] and [Any]
There was a problem hiding this comment.
What do you mean? I'm not sure why we would need Any? for anything in this context since Any can already be nil
There was a problem hiding this comment.
Oh interesting - what about the maps below? Do you also want to remove the ?
e.g.
var aNullableMap: [AnyHashable: Any?]? = nil
var nullableMapWithObject: [String?: Any?]? = nil
There was a problem hiding this comment.
probably a good idea
There was a problem hiding this comment.
I'm not sure why we would need Any? for anything in this context since Any can already be nil
Actually, Any cannot represent nil in Swift:
Hmmm, if I provide concrete type of nil then it works. I think it's fine to keep Any then. Though I am not sure how this is related to the Bool? crash you had the other day. May be helpful if you can provide a minimal reproducible code snippet so I can try out in playground.
There was a problem hiding this comment.
The Bool? crash was nil attempting to be cast to Bool?, it failed for the reasons mentioned here. I'm not sure how to replicate it without a lot of extra steps.
| @Suppress("UNCHECKED_CAST") | ||
| fun fromList(list: List<Any?>): TestMessage { | ||
| val testList = list[0] as? List<Any?> | ||
| val testList = list[0] as List<Any?>? |
There was a problem hiding this comment.
The kotlin version is still List<Any?>, but Swift changed from [Any?] to [Any]. Is it intended?
There was a problem hiding this comment.
Swift optional Any causes issues with force casting into optional types when the data is nil. Kotlin doesn't have that problem.
There was a problem hiding this comment.
Swift optional Any causes issues with force casting into optional types when the data is nil.
Not sure if I follow this. Can you share a short code snippet when it fails? Are you talking about this following scenario?
let list: [Any?] = [nil, 1, "Hi"]
let optionalBool = list[0] as! Bool?
There was a problem hiding this comment.
this is the scenario that was happening before. The only difference now is
list: [Any]
There was a problem hiding this comment.
Interesting. This scenario actually did not crash when I try it on the playground.
There was a problem hiding this comment.
The kotlin version is still
List<Any?>, but Swift changed from[Any?]to[Any]. Is it intended?
The core answer here is that Any is fundamentally different between the two languages: Any is a root type in Swift, but not Kotlin.
This Kotlin code:
val i: Int? = null
println(i is Any)
println(i is Any?)
prints
false
true
but this Swift code:
var i: Int? = nil
print(i is Any)
print(i is Any?)
prints
true
true
We're generating different code because the expression of "any type, including nullable types" is different in the two languages.
(I wasn't aware of this difference when reviewing the initial generator code, so didn't catch the incorrect use of Any? in Swift in the first place.)
| val aNullable4ByteArray = list[4] as IntArray? | ||
| val aNullable8ByteArray = list[5] as LongArray? | ||
| val aNullableFloatArray = list[6] as DoubleArray? | ||
| val aNullableList = list[7] as List<Any?>? |
There was a problem hiding this comment.
i'm curious - in Kotlin, can Any already represent a nullable?
hellohuanlin
left a comment
There was a problem hiding this comment.
The PR itself LGTM. Though I am still very curious why nil would fail to be casted to Bool? since my code snippet worked. I would need a minimal reproducible example to look into, but looks like you cannot create such example easily...
| @Suppress("UNCHECKED_CAST") | ||
| fun fromList(list: List<Any?>): TestMessage { | ||
| val testList = list[0] as? List<Any?> | ||
| val testList = list[0] as List<Any?>? |
There was a problem hiding this comment.
The kotlin version is still
List<Any?>, but Swift changed from[Any?]to[Any]. Is it intended?
The core answer here is that Any is fundamentally different between the two languages: Any is a root type in Swift, but not Kotlin.
This Kotlin code:
val i: Int? = null
println(i is Any)
println(i is Any?)
prints
false
true
but this Swift code:
var i: Int? = nil
print(i is Any)
print(i is Any?)
prints
true
true
We're generating different code because the expression of "any type, including nullable types" is different in the two languages.
(I wasn't aware of this difference when reviewing the initial generator code, so didn't catch the incorrect use of Any? in Swift in the first place.)
…tter#3284) [pigeon] removes safe casting from nullables in kotlin and swift

Removes safe casting during decode process for kotlin and swift to avoid hiding potential data type inconsistencies across channels.
fixes flutter/flutter#116999
Pre-launch Checklist
dart format.)[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.mdto add a description of the change, following repository CHANGELOG style.///).If you need help, consider asking for advice on the #hackers-new channel on Discord.