A class imported from a companion that is not used as the default value for a constructor parameter

Consider the following code:

object Main extends App { object Project { case class Config(rules: Seq[String] = Seq.empty) } import Project._ //case class Project(root: String, config: Config) // compiles fine //case class Project(root: String, config: Project.Config = Project.Config()) // compiles fine case class Project(root: String, config: Config = Config()) // error: not found: type Config } 

Why is the latest version not compiling (same with Config = Config.apply() )?

+7
scala companion-object
source share
1 answer

I don’t understand if this is an error or not, but here is why it causes an error:

Consider this that works:

 import Project._ object Project { case class Config() } case class Project(config: Config = Config()) 

When you add a default argument, the compiler generates a method to calculate the value. When this value is the standard constructor, this method is added to the companion object of the class. Therefore, the compiler will generate this method:

 def <init>$default$1: Project.Config = Config() 

What will be added to your Project object.

A Scala type controller generates a Contexts object tree. Each context has a reference to the context of its external area. Thus, the generated method gets the context, and the created external area of ​​the method is the Project companion object.

When the type checker tries to resolve Config() , it traverses all the surrounding contexts and cannot find Config (I'm not sure why, and this may be an error).

Once he has run out of contexts, he decides on an import that has a Project._ import! The type controller is happy because now it can navigate through the import and find the apply method.

Now when you move the import below Project :

 object Project { case class Config() } import Project._ case class Project(config: Config = Config()) 

In this case, the import available for the generated method does not have Project._ import (this may also be an error), I suppose, because it is lower than the definition of the object in which the generated method lives. Then it checks the type of error because it cannot find Config .

What apparently happens when the type checker solves Config() , it needs an import over the Project companion object, because it must handle the import in order to be able to resolve it, and if the import does not exceed Project this import is not included in volume.

For those who want to debug further, see Contexts.lookupSymbol , in which the search takes place

+2
source share

All Articles