Importing type aliases

#1

I have had the problems several times that when I define type aliases within some top level object, Foo, then in another file import Foo._, that some of the type aliases are recognized and some are not. At least according to the colorization in IntelliJ.

I recently discovered the issue and it is easy to fix, but I wonder whether it is a bug or intentional.

Consider the following file content. When I import import dimacsSimplify._ in a second file, the type aliases Clause and Clauses are recognized but HashUpdateFunction is not. Moving up all type aliases before the first function definition fixes the problem.

Does that sound like an IntelliJ bug, or does it sound really like correct language semantics?

object dimacsSimplify {
  type Clause = List[Int]
  type Clauses = List[Clause]

 // stuff skipped

 // various function and variable definitions
  def every[A, B](L1: List[A], L2: List[B])(f: (A, B) => Boolean): Boolean = {
    (L1, L2) match {
      case (a :: as, b :: bs) => f(a, b) && every(as, bs)(f)
      case (_, _) => true
    }
  }
  //    now another type alias
  type HashUpdateFunction = (Clause, Int, Int) => Unit

  // other stuff
}
#2

It should definitely not make a difference if the type alias is defined at the top or the bottom. I can’t reproduce this error, neither with IntelliJ nor SBT (IntelliJ version #IU-191.7479.19, Scala Plugin 2019.1.8).

You could try to invalidate IntelliJ’s caches (under File > Invalidate Cache / restart). If that doesn’t help, you probably found a bug in IntelliJ.

FWIW, here is the code I tried to reproduce this with (in addition to your snippet):

object TestImportScope {
  import bar.dimacsSimplify._
  val a: Clause = List(1,2,3)
  val b: Clauses = List(a)
  val f: HashUpdateFunction = (_, _, _) => ()
}
#3

@crater2150, thanks for the response.

In fact this problem happened most recently during refactoring. version 1 of the code had a few methods which used the type alias, so the alias was defined “at the top” of the group of methods.
Later, version 2, I refactored the code and moved some of the methods to a different file. In this case, it does actually make sense to define the type alias at the type of the object, as it is no longer semantically local. the type alias is used across 2 (or more files), so it really belongs at the top of the object definition.

I consider the latter more readable. It just puzzled me that it makes a difference to IntelliJ.

You are right that it could have simply been an IntelliJ caching issue.