Details

      Description

      I get the following exception in the IDE when opening certain files. I couldn't nail it down to a specific file yet, but git archeology suggests an existing workaround was removed with the belief that the NPE can't happen anymore:

      module.attachments.get[ConstructorDefaultsAttachment] match {
        // by martin: the null case can happen in IDE; this is really an ugly hack on top of an ugly hack but it seems to work
        // later by lukas: disabled when fixing SI-5975, i think it cannot happen anymore
        case Some(cda) /*if cma.companionModuleClassNamer == null*/ =>
          val p = (cda.classWithDefault, cda.companionModuleClassNamer)
          moduleNamer = Some(p)
          p
      
      java.lang.NullPointerException
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$addDefaultGetters$2$$anonfun$apply$14.apply(Namers.scala:1169)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$addDefaultGetters$2.apply(Namers.scala:1102)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$addDefaultGetters$2.apply(Namers.scala:1099)
      	at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:110)
      	at scala.collection.immutable.List.foldLeft(List.scala:78)
      	at scala.tools.nsc.typechecker.Namers$Namer.addDefaultGetters(Namers.scala:1099)
      	at scala.tools.nsc.typechecker.Namers$Namer.methodSig(Namers.scala:1027)
      	at scala.tools.nsc.typechecker.Namers$Namer.getSig$1(Namers.scala:1305)
      	at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1347)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply$mcV$sp(Namers.scala:709)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:708)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:708)
      	at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$logAndValidate(Namers.scala:1385)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:708)
      	at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:707)
      	at scala.tools.nsc.typechecker.Namers$$anon$1.completeImpl(Namers.scala:1496)
      	at scala.tools.nsc.typechecker.Namers$LockingTypeCompleter$class.complete(Namers.scala:1504)
      	at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1494)
      	at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1217)
      	at scala.reflect.internal.Symbols$Symbol.paramss(Symbols.scala:1473)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$DefOwner$class.addDef(ScalaStructureBuilder.scala:668)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$Builder.addDef(ScalaStructureBuilder.scala:871)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$DefOwner$class.addDef(ScalaStructureBuilder.scala:658)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$Builder.addDef(ScalaStructureBuilder.scala:871)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser.traverse(ScalaStructureBuilder.scala:943)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.collection.immutable.List.foreach(List.scala:309)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser.traverse(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.collection.immutable.List.foreach(List.scala:309)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser.traverse(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser$$anonfun$traverse$1.apply(ScalaStructureBuilder.scala:950)
      	at scala.collection.immutable.List.foreach(List.scala:309)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser$TreeTraverser.traverse(ScalaStructureBuilder.scala:950)
      	at scala.tools.eclipse.javaelements.ScalaStructureBuilder$StructureBuilderTraverser.traverse(ScalaStructureBuilder.scala:903)
      	at scala.tools.eclipse.javaelements.ScalaCompilationUnit$$anonfun$buildStructure$2$$anonfun$apply$5$$anonfun$apply$1.apply$mcV$sp(ScalaCompilationUnit.scala:74)
      	at scala.tools.eclipse.javaelements.ScalaCompilationUnit$$anonfun$buildStructure$2$$anonfun$apply$5$$anonfun$apply$1.apply(ScalaCompilationUnit.scala:73)
      	at scala.tools.eclipse.javaelements.ScalaCompilationUnit$$anonfun$buildStructure$2$$anonfun$apply$5$$anonfun$apply$1.apply(ScalaCompilationUnit.scala:73)
      	at scala.tools.nsc.util.InterruptReq.execute(InterruptReq.scala:26)
      	at scala.tools.nsc.interactive.Global.pollForWork(Global.scala:331)
      	at scala.tools.nsc.interactive.PresentationCompilerThread.run(PresentationCompilerThread.scala:22)
      

        Activity

        Hide
        Iulian Dragos added a comment -

        I can reproduce it in the debugger (but no stand-alone test yet). All I need is a class that defines an annotation with a default parameter, this is enough:

        class HippyAnnotation[T <: Throwable](cause: String = "") extends scala.annotation.StaticAnnotation {
          def this(clazz: Class[T]) = this()
        }
        

        It all boils down to this code in Namers.scala:

              // if default getters (for constructor defaults) need to be added to that module, here's the namer
              // to use. clazz is the ModuleClass. sourceModule works also for classes defined in methods.
              val module = clazz.sourceModule
              for (cda <- module.attachments.get[ConstructorDefaultsAttachment]) {
                cda.companionModuleClassNamer = templateNamer
              }
        

        The `sourceModule` call assumes it will get something other than `NoSymbol`, but that's not the case: `clazz` is the class symbol for the annotation, and therefore does not have a moduleClass. It follows that the namer is not assigned to the attachment, that stays null.

        Show
        Iulian Dragos added a comment - I can reproduce it in the debugger (but no stand-alone test yet). All I need is a class that defines an annotation with a default parameter, this is enough: class HippyAnnotation[T <: Throwable](cause: String = "") extends scala.annotation.StaticAnnotation { def this(clazz: Class[T]) = this() } It all boils down to this code in Namers.scala: // if default getters (for constructor defaults) need to be added to that module, here's the namer // to use. clazz is the ModuleClass. sourceModule works also for classes defined in methods. val module = clazz.sourceModule for (cda <- module.attachments.get[ConstructorDefaultsAttachment]) { cda.companionModuleClassNamer = templateNamer } The `sourceModule` call assumes it will get something other than `NoSymbol`, but that's not the case: `clazz` is the class symbol for the annotation, and therefore does not have a moduleClass. It follows that the namer is not assigned to the attachment, that stays null.
        Hide
        Jason Zaugg added a comment -

        I still don't see what's different between an annotation and regular class here...

        Show
        Jason Zaugg added a comment - I still don't see what's different between an annotation and regular class here...
        Hide
        Iulian Dragos added a comment -

        True, I didn't minimize it all the way. Here it is, all that's needed to see it:

        class HippyClass(cause: String = "")
        
        Show
        Iulian Dragos added a comment - True, I didn't minimize it all the way. Here it is, all that's needed to see it: class HippyClass(cause: String = "")
        Hide
        Jason Zaugg added a comment - - edited

        Yep, the buggy code is only exercised for constructor parameter defaults, which must be generated in the companion object.

        Show
        Jason Zaugg added a comment - - edited Yep, the buggy code is only exercised for constructor parameter defaults, which must be generated in the companion object.
        Hide
        François Garillot added a comment - - edited

        This probably manifested in the IDE as #1001479

        Show
        François Garillot added a comment - - edited This probably manifested in the IDE as #1001479

          People

          • Assignee:
            Paul Phillips
            Reporter:
            Iulian Dragos
          • Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development