Skip to content

aliasing gets less precise type than Scala #2198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
liufengyun opened this issue Apr 6, 2017 · 10 comments
Closed

aliasing gets less precise type than Scala #2198

liufengyun opened this issue Apr 6, 2017 · 10 comments

Comments

@liufengyun
Copy link
Contributor

In Scala, Nil gets the type collection.immutable.Nil.type, but in Dotty it gets scala.collection.immutable.Nil$.

object Test {
  val Nil = scala.collection.immutable.Nil
}
@smarter
Copy link
Member

smarter commented Apr 6, 2017

Is this an issue for anything in practice?

@DarkDimius
Copy link
Contributor

In Dotty, scala.collection.immutable.Nil$ will have a self-type collection.immutable.Nil.type. Do you have an example where you'll be able to see a distinction?

@smarter
Copy link
Member

smarter commented Apr 6, 2017

There's also a special case in subtyping: #1448, I wasn't sure if that special-casing was the right way to go, so feel free to propose a better solution if this one doesn't work in some cases.

@liufengyun
Copy link
Contributor Author

liufengyun commented Apr 6, 2017

The problem I have is the exhaustivity of the following program:

object Test {
  val Nil = scala.Nil
  val X = 5

  def foo1b[T](l: List[T]) = l match {
    case Nil => true
    case x::xs => false
  }
}

The checker will report that Nil is not matched, because:

scala.collection.immutable.Nil.type <:< scala.collection.immutable.Nil$(Test.Nil) = false

The checker can special case, but given that now we also have case val for enum, it would be nice that the checker only rely on the type system.

@smarter
Copy link
Member

smarter commented Apr 6, 2017

Ah indeed, that seems like a good reason for changing the inference rule (and reverting #1448).

@liufengyun
Copy link
Contributor Author

The following code can serve as test case, which is accepted by Scala but rejected by Dotty:

object Test {
  val nil = scala.collection.immutable.Nil
  def f(x: nil.type): Int = 3

  f(scala.collection.immutable.Nil)
}

@smarter
Copy link
Member

smarter commented Apr 6, 2017

If you want to try to fix it, it should probably be done in inferredType in Namer: https://github.com/lampepfl/dotty/blob/586113dab51d95f2a606c83b2cd31563ac47a6cf/compiler/src/dotty/tools/dotc/typer/Namer.scala#L971

@liufengyun
Copy link
Contributor Author

Thanks @smarter for the pointer, I'll play with it .

@liufengyun
Copy link
Contributor Author

liufengyun commented Apr 7, 2017

After some thinking, I think this issue might not need to be fixed, as long as:

  • we accept the minor discrepancy with Scalac
  • we push the responsibility to programmers to explicitly annotate the expected type to avoid widening

With the last assumption, the exhaustivity check works well without problem.

The justification is that code that avoids widening is very rare, maybe 1/10000, it doesn't make sense to make a rarity a rule in the language. In contrast, it justifies for programmers to pay additional efforts for a rare usage, i.e. to annotate the expected type with scala.collection.immutable.Nil.type to avoid widening.

@smarter
Copy link
Member

smarter commented Apr 7, 2017

The justification is that code that avoids widening is very rare, maybe 1/10000, it doesn't make sense to make a rarity a rule in the language.

It's not actually that rare, it's a common pattern to alias objects in a different package, e.g. https://github.com/scala/scala/blob/2.12.x/src/library/scala/Predef.scala#L150, https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/io/package.scala#L16, etc.

odersky added a commit to dotty-staging/dotty that referenced this issue Apr 9, 2017
Since module classes are a compiler-generated construct that's not directly
visible to programmers, it seems better not to automatically widen a module
singleton to its underlying class.

Fixes scala#2198.
odersky added a commit that referenced this issue Apr 10, 2017
Fix #2198: Don't widen module singletons
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants