|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I started out looking to limit the noise from empty type
bounds, i.e. the endless repetition of
class A[T >: _root_.scala.Nothing <: _root_.scala.Any]
This led me to be reminded of all the unnecessary and
in fact damaging overreaches which are performed during parsing.
Why should a type parameter for which no bounds are
specified be immediately encoded with this giant tree:
TypeBounds(
Select(Select(Ident(nme.ROOTPKG), tpnme.scala_), tpnme.Nothing),
Select(Select(Ident(nme.ROOTPKG), tpnme.scala_), tpnme.Any)
)
...which must then be manually recognized as empty type bounds?
Truly, this is madness.
- It deftly eliminates the possibility of recognizing
whether the user wrote "class A[T]" or "class A[T >: Nothing]"
or "class A[T <: Any]" or specified both bounds. The fact
that these work out the same internally does not imply the
information should be exterminated even before parsing completes.
- It burdens everyone who must recognize type bounds trees,
such as this author
- It is far less efficient than the obvious encoding
- It offers literally no advantage whatsoever
Encode empty type bounds as
TypeBounds(EmptyTree, EmptyTree)
What could be simpler.
|