haxe
haxe copied to clipboard
[nullsafety] field access false positive with multiple guards
Shouldn't this compile with loose null safety? Neither a1 nor a2 can be null here due to the previous checks:
@:nullSafety
class Main {
static function main() {}
public static function equals<T>(a1:Null<Array<T>>, a2:Null<Array<T>>):Bool {
if (a1 == null && a2 == null) return true;
if (a1 == null && a2 != null) return false;
if (a1 != null && a2 == null) return false;
if (a1.length != a2.length) return false;
// ...
return true;
}
}
source/Main.hx:9: characters 7-16 : Null safety: Cannot access "length" of a nullable value.
source/Main.hx:9: characters 20-29 : Null safety: Cannot access "length" of a nullable value.
That's a nice test case :)
After a1 == null && a2 == null you need to know that one of exprs is not-null and this seems overcomplicated to implement. I just checked and Kotlin/Dart/TS doesn't track such thing and show similar errors, so i think this can be closed as non-planned.
It is such a nice test case though... I can see how the logic would work:
public static function equals<T>(a1:Null<Array<T>>, a2:Null<Array<T>>):Bool {
if (a1 == null && a2 == null)
return true;
/*
post:
a1 != null || a2 != null
*/
if (a1 == null && a2 != null)
return false;
/*
post:
a1 != null || a2 == null
combined with previous post:
(a1 != null || a2 != null) && (a1 != null && a2 == null)
simplified:
a1 != null && (a2 != null || a2 == null)
right part is tautology, so just:
a1 != null
*/
if (a1 != null /* this is actually redundant */ && a2 == null)
return false;
/*
post:
a1 == null || a2 != null
combined with previous post:
a1 != null && (a1 == null || a2 != null)
expanded:
a1 != null && a1 == null || a1 != null && a2 != null
left part is tautology, so just:
a1 != null && a2 != null
*/
if (a1.length != a2.length)
return false;
return true;
}
I understand that we don't really have a framework to support this, but it sure would be nice if we did. I'd like to keep this open in case I randomly decide to implement something like this at some point.