#1360 add(null) runtime check for non-nullable item type

vkuzkokov Thu 9 Dec 2010

class Main
{
  Void main(Str[] args)
  {
    echo(((Int?[])[0]).add(null))
  }
}

results in

[0, null]

while some kind of NullErr was expected.

DanielFath Thu 9 Dec 2010

Why would this return NullErr? The list is casted as Int?[], is it not?

vkuzkokov Fri 10 Dec 2010

Cast to Int?[] is ok. NullErr should be raised inside of add because runtime type of list is Int[].

qualidafial Fri 10 Dec 2010

Looks like the null check is enforced at the call site. So when you cast from e.g. Int[] to Int?[] your null safety is gone:

Fantom Shell v1.0.56 ('?' for help)
fansh> nonNullable := Int[0]
[0]
fansh> nonNullable.add(null)
ERROR(13): Invalid args add(sys::Int), not (null)
fansh> Int?[] nullable := nonNullable
[0]
fansh> nullable.add(null)
[0, null]

vkuzkokov Fri 25 Mar 2011

Somehow this issue isn't tracked as bug. Here's a patch.

diff -r 80706233791e src/sys/java/fan/sys/List.java
--- a/src/sys/java/fan/sys/List.java    Fri Mar 25 09:23:21 2011 -0400
+++ b/src/sys/java/fan/sys/List.java    Fri Mar 25 21:23:30 2011 +0600
@@ -324,6 +324,8 @@
   public final List set(long index, Object value)
   {
     modify();
+    if (value == null && !of.isNullable())
+      throw NullErr.make("Adding null to '" + of + "[]'").val;
     try
     {
       int i = (int)index;
@@ -368,6 +370,8 @@
     try
     {
       modify();
+      if (value == null && !of.isNullable())
+        throw NullErr.make("Adding null to '" + of + "[]'").val;
       if (values.length <= size)
         grow(size+1);
       if (i < size)

brian Fri 25 Mar 2011

I don't want to sound dismissive, but I don't personally think it is worth it worrying about. There are a ton of cases where the wrong type could potentially make its way into a List. This patch fixes one case, but doesn't cover all the cases. If we really wanted to obsess about making List perfectly type safe it would require a lot of extra checks, most of which would duplicate the casts the compiler is always inserting.

vkuzkokov Fri 25 Mar 2011

Well, compiler might not know the type, so it will resort to Java Generics behavior.

All the cases will be covered if checks for generic types are added in the same 2 places.

Login or Signup to reply.