Skip to content

Interaciton between top-level definition and import is unspecified (and confusing) #13706

Closed
@smarter

Description

@smarter

The following code typechecks, even though it looks like length is accessed before it's imported:

val a: String = ""
val x = length
import a.length
val b = length

This happens because desugaring moves top-level definitions below everything else:

import a.length
final lazy module val test$package: test$package = new test$package()
final module class test$package() extends Object() { this: test$package.type =>
  val a: String = ""
  val x: Int = a.length()
  val b: Int = a.length()
}

This behavior is not specified, https://dotty.epfl.ch/docs/reference/dropped-features/package-objects.html simply states that "The compiler generates synthetic objects that wrap top-level definitions", but it doesn't say anything about statements being reordered (one could imagine the package object being defined above the other definitions, but then no import would be visible at all).

I think ideally we would prevent this code from typechecking, but it seems like that would require a much more involved desugaring of top-level definition, so short of that we should document the status quo.

Metadata

Metadata

Assignees

Labels

area:desugarDesugaring happens after parsing but before typing, see desugar.scalaitype:bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions