#991 closure calling toImmutable on a null value?

KevinKelley Tue 23 Feb 2010

I maybe have a bug, relating to this rule about immutable closures:

Closure which capture non-final variables which aren't known to be immutable until runtime (such as Obj or List) will return false for isImmutable, but will provide a toImmutable method which attempts to bind to the current variables by calling toImmutable on each one

I'm doing a hairy impl. of monads using closures, and just ran into this error:

->null
sys::NullErr: java.lang.NullPointerException
  fan.sys.FanObj.toImmutable (FanObj.java:118)
  ex3parser_0::ParserMonad$unit$0.toImmutable (/C:/dev/working/monads/fan/ex3 - parser.fan:61)
  fan.sys.FanObj.toImmutable (FanObj.java:117)
  ex3parser_0::ParserMonad$or$4.toImmutable (/C:/dev/working/monads/fan/ex3 - parser.fan:112)
  fan.sys.FanObj.toImmutable (FanObj.java:117)
  ex3parser_0::ParserMonad$seq$7.toImmutable (/C:/dev/working/monads/fan/ex3 - parser.fan:142)
  fan.sys.FanObj.toImmutable (FanObj.java:117)
  ex3parser_0::ParserMonad$bind$1.toImmutable (/C:/dev/working/monads/fan/ex3 - parser.fan:74)
  fan.sys.FanObj.toImmutable (FanObj.java:117)
  ex3parser_0::Parser.instance$init$ex3parser_0$Parser (/C:/dev/working/monads/fan/ex3 - parser.fan:293)
  ex3parser_0::Parser.make$ (/C:/dev/working/monads/fan/ex3 - parser.fan:261)
  ex3parser_0::Parser.make (/C:/dev/working/monads/fan/ex3 - parser.fan)
  java.lang.reflect.Method.invoke (Unknown)
  fan.sys.Method.invoke (Method.java:536)
  fan.sys.Method$MethodFunc.callList (Method.java:182)
  fan.sys.Type.make (Type.java:242)
  fan.sys.ClassType.make (ClassType.java:110)
  fan.sys.Type.make (Type.java:232)
  fanx.tools.Fan.callMain (Fan.java:137)
  fanx.tools.Fan.executeFile (Fan.java:88)
  4 More...

it's throwing from this point:

|State->Result| unit(Obj? v) {
  echo("->$v"); 
  return |State? st->Result|{Result.Ok(v, st)}  // closure captures v, and calls
                                                // toImmutable on it even tho it's null
}

Could be I'm tripping myself up somehow, but it looks to me like a fantom bug. I'll see if I can fix it now...

KevinKelley Tue 23 Feb 2010

Further info... I added a null-test in src/sys/java/fan/sys/FanObj.java toImmutable method:

public static Object toImmutable(Object self)
{
  if (self == null) return null;

  if (self instanceof FanObj)
    return ((FanObj)self).toImmutable();
  else if (FanUtil.isJavaImmutable(self.getClass()))
    return self;
  throw NotImmutableErr.make(self.getClass().getName()).val;
}

and my code now seems to work. Question: null should be considered immutable, right? So it should be okay to use it like I am, and Fantom shouldn't break on it, if I'm not confused.

Next question, I don't know what the right fix is; I guess the compiler's generating the toImmutable call, so I guess it ought to check for null first. I think I'll leave that to Brian. :-)

Anyway I've got a workaround, so no big deal, but wanted to report what seems to be a bug.

brian Wed 24 Feb 2010

Well the root problem is that the compiler should probably make that a safe call. But this problem has bitten me a couple times before, so think I'll just do the check in FanObj as you suggested. I pushed a fix for that.

Login or Signup to reply.