Scala2Erasure
Erasure logic specific to Scala 2 symbols.
Erasure logic specific to Scala 2 symbols.
Type members
Types
The equivalent of a Scala 2 type symbol.
The equivalent of a Scala 2 type symbol.
In some situations, nsc will create a symbol for a type where we wouldn't:
A with B with C { ... }
is represented with a RefinedType whose symbol is a fresh class symbol whose parents areA
,B
,C
.- Structural members also get their own symbols.
To emulate this, we simply use the type itself as a stand-in for its symbol.
See also sameSymbol
which determines if two pseudo-symbols are really the same.
A type that would be represented as a RefinedType in Scala 2.
A type that would be represented as a RefinedType in Scala 2.
The RefinedType
of Scala 2 contains both a list of parents
and a list of refinements, intersections are represented as a RefinedType
with no refinements.
Value members
Concrete methods
Is this a supported Scala 2 refinement or parent of such a type?
Is this a supported Scala 2 refinement or parent of such a type?
We do not allow types that look like: ((A with B) @foo) with C or: (A { type X <: ... })#X with C`
as it would make our implementation of Scala 2 intersection erasure
significantly more complicated. The problem is that each textual
appearance of an intersection or refinement in a parent corresponds to a
fresh instance of RefinedType (because Scala 2 does not hash-cons these
types) with a fresh synthetic class symbol, thus affecting the result of
isNonBottomSubClass
. To complicate the matter, the Scala 2 UnCurry phase
will also recursively dealias parent types, thus creating distinct class
symbols even in situations where the same type alias is used to refer to a
given refinement. Note that types like (A with B) with C
do not run into
these issues because they get flattened into a single RefinedType with
three parents, cf flattenedParents
.
See sbt-dotty/sbt-test/scala2-compat/erasure/changes/Main.scala for examples.
- Throws
- TypeError
if this type is unsupported.
A flattened list of parents of this intersection.
A flattened list of parents of this intersection.
Mimic what Scala 2 does: intersections like A with (B with C)
are
flattened to three parents.
An emulation of Erasure#intersectionDominator
from Scala 2.
An emulation of Erasure#intersectionDominator
from Scala 2.
Accurately reproducing the behavior of this method is extremely difficult
because it operates on the symbols of the non-erased parent types, an
implementation detail of the compiler. Furthermore, these non-class
symbols are passed to methods such as isNonBottomSubClass
whose behavior
is only specified for class symbols. Therefore, the accuracy of this
method cannot be guaranteed, the best we can do is make sure it works on
as many test cases as possible which can be run from sbt using:
sbt-dotty/scripted scala2-compat/erasure
The body of this method is made to look as much as the Scala 2 version as possible to make them easier to compare, cf: https://github.com/scala/scala/blob/v2.13.5/src/reflect/scala/reflect/internal/transform/Erasure.scala#L356-L389
Extensions
Extensions
Is this a class symbol? Also returns true for refinements since they get a class symbol in Scala 2.
Is this a class symbol? Also returns true for refinements since they get a class symbol in Scala 2.
An emulation of Symbol#isNonBottomSubClass
from Scala 2.
An emulation of Symbol#isNonBottomSubClass
from Scala 2.
The documentation of the original method is:
Is this class symbol a subclass of that symbol, and is this class symbol also different from Null or Nothing?
Which sounds fine, except that it is also used with non-class symbols,
so what does it do then? Its implementation delegates to Type#baseTypeSeq
whose documentation states:
The base type sequence of T is the smallest set of [...] class types Ti, so that [...]
But this is also wrong: the sequence returned by baseTypeSeq
can
contain non-class symbols.
Given that we cannot rely on the documentation and that the implementation is extremely complex, this reimplementation is mostly based on reverse-engineering rules derived from the observed behavior of the original method.