#350 Bug? Compiler doesn't like List

cgrinds Wed 27 Aug 2008

I'm surprised this:

class CompilerBugEquals {
  static Void main() {
      list := ["abc", 4]
      CompilerBugEquals().works(list)
      CompilerBugEquals().doesNot(list)
  }
  Void works(Obj obj) {
    tuple := obj as Obj[]
    echo(tuple[0] == "abc")
  }
  Void doesNot(Obj obj) {
    tuple := obj as List
    echo(tuple[0] == "abc")  //this doesnt
  }
}

results in:

ERROR: cannot compile script
sys::UnsupportedErr
  compiler::GenericParameterType.slots (GenericTypes.fan:321)
  compiler::CType$.slot (Unknown:291)
  compiler::GenericParameterType.slot (GenericTypes.fan)
  compiler::CallResolver.find (CallResolver.fan:151)
  compiler::CallResolver.resolve (CallResolver.fan:61)
  compiler::ResolveExpr.resolveCall (ResolveExpr.fan:401)
  compiler::ResolveExpr.resolveShortcut (ResolveExpr.fan:498)
  compiler::ResolveExpr.resolveExpr (ResolveExpr.fan:151)
  compiler::ResolveExpr.visitExpr (ResolveExpr.fan:121)
  compiler::Expr.walk (Expr.fan:211)
  compiler::Expr.walkExprs (Expr.fan:231)
  compiler::CallExpr.walkChildren (Expr.fan:730)
  compiler::Expr.walk (Expr.fan:210)
  compiler::Stmt.walkExpr (Stmt.fan:54)
  compiler::ExprStmt.walkChildren (Stmt.fan:106)
  compiler::Stmt.walk (Stmt.fan:42)
  compiler::Block.walk (Block.fan:77)
  fan.sys.Func$Indirect1.call2 (Func.java:119)
  fan.sys.List.each (List.java:495)
  compiler::Block.walk (Block.fan:77)
  More...

brian Wed 27 Aug 2008

Chris, thanks for the report. As a general rule we prefer Obj[] to List so I haven't seen that. Although semantically they are the same thing and since they do take different code paths in the compiler, I've tried to be diligent about adding test cases when List is used. Guess I missed one (or many) case(s) - so I'll take a look.

brian Thu 28 Aug 2008

Fixed for next build.

change is to compiler::ResolveExpr line 127:

// expr type must be resolved at this point
if (expr.ctype == null)
  throw err("Expr type not resolved: ${expr.id}: ${expr}", expr.location)

// if we resolved to a generic parameter like V or K,
// then use its real underlying type
if (expr.ctype.isGenericParameter)
  expr.ctype = expr.ctype.raw

return expr

cgrinds Thu 28 Aug 2008

Thanks Brian, that fixes it.

Login or Signup to reply.