Skip to content

Commit bbc7e21

Browse files
authored
Merge pull request #8946 from dotty-staging/java-intersection-erasure
Properly erase Java intersections
2 parents 68deb63 + a543e00 commit bbc7e21

File tree

5 files changed

+21
-1
lines changed

5 files changed

+21
-1
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ object TypeOps:
156156
case _: AppliedType | _: MatchType =>
157157
val normed = tp.tryNormalize
158158
if (normed.exists) normed else mapOver
159+
case tp: MethodicType =>
160+
tp // See documentation of `Types#simplified`
159161
case _ =>
160162
mapOver
161163
}

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,13 @@ object Types {
16671667
* what was a union or intersection of type variables might be a simpler type
16681668
* after the type variables are instantiated. Finally, it
16691669
* maps poly params in the current constraint set back to their type vars.
1670+
*
1671+
* NOTE: Simplifying an intersection type might change its erasure (for
1672+
* example, the Java erasure of `Object & Serializable` is `Object`,
1673+
* but its simplification is `Serializable`). This means that simplification
1674+
* should never be used in a `MethodicType`, because that could
1675+
* lead to a different `signature`. Since this isn't very useful anyway,
1676+
* this method handles this by never simplifying inside a `MethodicType`.
16701677
*/
16711678
def simplified(implicit ctx: Context): Type = TypeOps.simplify(this, null)
16721679

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,8 @@ class ClassfileParser(
434434
if (sig(index) != ':') // guard against empty class bound
435435
ts += objToAny(sig2type(tparams, skiptvs))
436436
}
437-
TypeBounds.upper(ts.foldLeft(NoType: Type)(_ & _) orElse defn.AnyType)
437+
val bound = if ts.isEmpty then defn.AnyType else ts.reduceLeft(AndType.apply)
438+
TypeBounds.upper(bound)
438439
}
439440

440441
var tparams = classTParams

tests/run/java-intersection/A_1.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class A_1 {
2+
public <T extends Object & java.io.Serializable> void foo(T x) {}
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a = new A_1
4+
val x = new java.io.Serializable {}
5+
a.foo(x)
6+
}
7+
}

0 commit comments

Comments
 (0)