Skip to content

PureInterface is needlessly dropped when defKind encounters a lazy val  #4328

Closed
@gsps

Description

@gsps

Here's an example where typer (i.e., defKind) and the unpickler disagree about whether MakeMeAnInterface should in fact be a PureInterface:

When I run

class A()

trait MakeMeAnInterface {
  lazy val a: A = new A()
}

using

dotc -pagewidth 200 -color:never -Xprint-types -Ytest-pickler -Yprint-pos -Yprint-pos-syms  MakeMeAnInterface.scala

I get

$ diff before-pickling.txt after-pickling.txt 
4c4
<   ):scala.annotation.internal.SourceFile>@<no position> <trait> trait MakeMeAnInterface() extends java.lang.Object { 
---
>   ):scala.annotation.internal.SourceFile>@<no position> <trait> interface trait MakeMeAnInterface() extends java.lang.Object {

I'm not sure when exactly a trait can be considered a PureInterface, but I assume that defKind is in fact wrong, and should check for the presence of Lazy vals, for instance like this:

def defKind(tree: Tree)(implicit ctx: Context): FlagSet = unsplice(tree) match {
    case EmptyTree | _: Import => NoInitsInterface
    case tree: TypeDef => if (tree.isClassDef) NoInits else NoInitsInterface
    case tree: DefDef => if (tree.unforcedRhs == EmptyTree) NoInitsInterface else NoInits
    case tree: ValDef => if (tree.unforcedRhs == EmptyTree /* >> added */ || tree.symbol.is(Lazy) /* added << */) NoInitsInterface else EmptyFlags
    case _ => EmptyFlags
  }

I can make a PR if that's the correct fix.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions