#2356 Compiler Bug / Oversight

SlimerDude Mon 6 Oct 2014

Hi, when compiling a project today I ran into this:

compile [afPillow]
  Compile [afPillow]
    FindSourceFiles [20 files]
ERR: Internal compiler error
sys::NullErr: Coerce to non-null
  fan.sys.NullErr.makeCoerce (NullErr.java:38)
  compiler::Parser.simpleType (Parser.fan:2207)
  compiler::Parser.ctype (Parser.fan:2104)
  compiler::Parser.ctype (Parser.fan)
  compiler::Parser.tryType (Parser.fan:2078)
  compiler::Parser.termBaseExpr (Parser.fan:1524)
  compiler::Parser.termExpr (Parser.fan:1500)
  compiler::Parser.termExpr (Parser.fan)
  compiler::Parser.unaryExpr (Parser.fan:1471)
  compiler::Parser.parenExpr (Parser.fan:1405)
  compiler::Parser.multExpr (Parser.fan:1390)
  compiler::Parser.addExpr (Parser.fan:1378)
  compiler::Parser.rangeExpr (Parser.fan:1361)
  compiler::Parser.relationalExpr (Parser.fan:1330)
  compiler::Parser.equalityExpr (Parser.fan:1296)
  compiler::Parser.condAndExpr (Parser.fan:1276)
  compiler::Parser.condOrExpr (Parser.fan:1256)
  compiler::Parser.ifExpr (Parser.fan:1208)
  compiler::Parser.assignExpr (Parser.fan:1189)
  compiler::Parser.assignExpr (Parser.fan)
  compiler::Parser.expr (Parser.fan:1178)
  compiler::Parser.localDefStmt (Parser.fan:944)
  compiler::Parser.exprOrLocalDefStmt (Parser.fan:882)
  compiler::Parser.stmt (Parser.fan:855)
  compiler::Parser.stmtOrBlock (Parser.fan:822)
  compiler::Parser.block (Parser.fan:803)
  compiler::Parser.methodDef (Parser.fan:704)
  compiler::Parser.slotDef (Parser.fan:434)
  compiler::Parser.typeDef (Parser.fan:233)
  compiler::Parser.parse (Parser.fan:48)
  25 More...
BUILD FAILED [527ms]!

Which wasn't very helpful!

The Parser code in question looks like:

private CType simpleType() {
  ...

  // if more then one, first try to exclude those internal to other pods
  if (types.size > 1) types = types.exclude |t| { t.isInternal && t.pod.name != compiler.pod.name }

  // if more then one its ambiguous (use errReport to avoid suppression)
  if (types.size > 1)
    errReport(CompilerErr("Ambiguous type: " + types.join(", "), loc))

  // got it
  return types.first   // <-- line 2207
}

If all the types are internal to other pods then types becomes empty and types.first returns null resulting in the NullErr.

So my solution was to re-compile the compiler, adding the following to Parser.simpleType():

private CType simpleType() {
  ...

  // if more then one, first try to exclude those internal to other pods
  if (types.size > 1) types = types.exclude |t| { t.isInternal && t.pod.name != compiler.pod.name }

  // ---- PATCH START ----
  // all types were internal to other pods
  if (types.isEmpty)
    throw err("Unknown type '$id'", loc)
  // ---- PATCH END ------

  // if more then one its ambiguous (use errReport to avoid suppression)
  if (types.size > 1)
    errReport(CompilerErr("Ambiguous type: " + types.join(", "), loc))

  // got it
  return types.first
}

and now I get the following sane error msg:

compile [afPillow]
  Compile [afPillow]
    FindSourceFiles [20 files]
C:\Projects\Fantom-Factory\Pillow\fan\public\Pages.fan(58,12): 
Ambiguous type: afIoc::Utils, afEfanXtra::Utils, afBedSheet::Utils, afConcurrent::Utils
BUILD FAILED [790ms]!

Hooray!

brian Mon 20 Oct 2014

Before integrating that patch I'd also like to get a test case that reproduces it we can add to the testCompiler suite. What did the code look like that caused that? I can't make it happen

SlimerDude Sun 26 Oct 2014

What did the code look like that caused that?

Oh yeah, I forgot to add the important stuff!

If you install IoC then the following reproduces the null Err

using afIoc
using afPlastic

class Which {
    Void main() {
        Utils.getLog(this.typeof)
    }
}

Just run it as a script:

D:\Temp\fantom>fan Which.fan

ERROR: cannot compile script
sys::NullErr: Coerce to non-null
  fan.sys.NullErr.makeCoerce (NullErr.java:38)
  compiler::Parser.simpleType (Parser.fan:2207)
  compiler::Parser.ctype (Parser.fan:2104)
  compiler::Parser.ctype (Parser.fan)
  ...

Both IoC and Plastic have a Utils class with a getLog() method.

SlimerDude Mon 9 Feb 2015

Hi, I ran into this issue again today.

C:\Projects\CodeExplorer>fan build.fan

compile [mmCodeExplorer]
  Compile [mmCodeExplorer]
    FindSourceFiles [18 files]
ERR: Internal compiler error
sys::NullErr: Coerce to non-null
  fan.sys.NullErr.makeCoerce (NullErr.java:38)
  compiler::Parser.simpleType (Parser.fan:2208)
  compiler::Parser.ctype (Parser.fan:2105)
  compiler::Parser.ctype (Parser.fan)
  compiler::Parser.tryType (Parser.fan:2079)
  compiler::Parser.termBaseExpr (Parser.fan:1525)
  compiler::Parser.termExpr (Parser.fan:1501)
  compiler::Parser.termExpr (Parser.fan)
  compiler::Parser.unaryExpr (Parser.fan:1472)
  compiler::Parser.parenExpr (Parser.fan:1406)
  ...
  ...

I re-patched my compiler::Parser class with the code in the first post and now I get:

C:\Projects\CodeExplorer>fan build.fan

compile [mmCodeExplorer]
  Compile [mmCodeExplorer]
    FindSourceFiles [18 files]
C:\Projects\Nigel\CodeExplorer\fan\DataMigration.fan(178,18): Ambiguous type: afIocConfig::ErrMsgs, afButter::ErrMsgs
BUILD FAILED [587ms]!

The line causing the compilation error was:

using afButter
using afIocConfig

...

throw Err(ErrMsgs.noMatch)

With ErrMsgs being an internal class in both afIocConfig and afButter.

brian Mon 9 Feb 2015

With ErrMsgs being an internal class in both afIocConfig and afButter.

Yeah with that info I was able to reproduce it too. Thanks. Pushed a fix

Login or Signup to reply.