Skip to content

Compiler throws NullPointerException when inferring type #9291

Closed
@scabug

Description

@scabug

The following test case causes the compiler to throw a NullPointerException:

// more than one field is required to trigger crash
// there must be a default value for one of the parameters
case class OuterObject(field: Int = 1, anotherField: Int = 2)
	
object Test {
	OuterObject().copy(field = OuterObject().field)

	// declaring something without explicit type, with the same name as OuterObject.field
	def field = "anything"
}

Some things to note:

  • the name of the def Test.field is important, if it is not the same as the parameter name in OuterObject, the crash does not occur.
  • if OuterObject.field is the only parameter, the crash does not occur (any number of additional parameter are needed)
  • using the default values is important, i.e. changing the test case to have both parameters specified within the copy call avoids the bug: {code}
    OuterObject().copy(field = OuterObject(1, 2).field) {code}

The exception does not occur on 2.10.4 (we are upgrading from that version). Since this bug seems so bizarrely specific, a workaround should be available by changing pretty much anything about the code, e.g. explicitly defining type information.

Compiling with -Ydebug gives the following additional output:

warning: !!! exception when typing OuterObject().copy(field = OuterObject().field), pt=?
warning: !!! exception when typing <module> object Test extends scala.AnyRef {
  <method> def <init>(): <empty>.this.Test.type = {
    super.<init>();
    ()
  };
  OuterObject().copy(field = OuterObject().field);
  <method> <triedcooking> def field: lang.this.String = "anything"
}, pt=?
warning: !!! exception when typing package <empty> {
  case class OuterObject extends scala.Product with scala.Serializable {
    <caseaccessor> <paramaccessor> <triedcooking> private[this] val field : scala.this.Int = _;
    <caseaccessor> <paramaccessor> <triedcooking> private[this] val anotherField : scala.this.Int = _;
    <method> <triedcooking> def <init>(field: Int = 1, anotherField: Int = 2): <empty>.this.OuterObject = {
      super.<init>();
      ()
    }
  };
  <module> object Test extends scala.AnyRef {
    <method> def <init>(): <empty>.this.Test.type = {
      super.<init>();
      ()
    };
    OuterObject().copy(field = OuterObject().field);
    <method> <triedcooking> def field: lang.this.String = "anything"
  }
}, pt=?

Partial stack trace:

error: java.lang.NullPointerException
	at scala.tools.nsc.typechecker.Typers$Typer.noExpectedType$1(Typers.scala:3378)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$handleMonomorphicCall$1(Typers.scala:3381)
	at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3409)
	at scala.tools.nsc.typechecker.Typers$Typer.tryNamesDefaults$1(Typers.scala:3295)
	at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3367)
	at scala.tools.nsc.typechecker.Typers$Typer.tryNamesDefaults$1(Typers.scala:3353)
	at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3367)
	at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$1.apply(Typers.scala:4404)
	at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$1.apply(Typers.scala:4404)
	at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:676)
	at scala.tools.nsc.typechecker.Typers$Typer.tryTypedApply$1(Typers.scala:4404)
	at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4449)
	at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4484)
	at scala.tools.nsc.typechecker.Typers$Typer.typedInAnyMode$1(Typers.scala:5242)
	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5259)
	at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5295)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5322)
	at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5269)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5273)
	at scala.tools.nsc.typechecker.Typers$Typer.typedByValueExpr(Typers.scala:5351)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2977)
	at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$60.apply(Typers.scala:3081)
	at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$60.apply(Typers.scala:3081)
	at scala.collection.immutable.List.loop$1(List.scala:172)
	at scala.collection.immutable.List.mapConserve(List.scala:188)
	at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3081)
	at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1880)
	at scala.tools.nsc.typechecker.Typers$Typer.typedModuleDef(Typers.scala:1767)
	at scala.tools.nsc.typechecker.Typers$Typer.typedMemberDef$1(Typers.scala:5209)
	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5258)
	at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5295)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5322)
	at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5269)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5273)
	at scala.tools.nsc.typechecker.Typers$Typer.typedByValueExpr(Typers.scala:5351)
	at ...
Exception in thread "main" java.lang.NullPointerException
	at scala.tools.nsc.typechecker.Typers$Typer.noExpectedType$1(Typers.scala:3378)
	at ...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions