Skip to content

Commit eb92601

Browse files
committed
Modify generation for nullable union types in generic signatures
1 parent 9f70200 commit eb92601

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object NullOpsDecorator:
4242
}
4343
if tpStripped ne tpWiden then tpStripped else tp
4444

45-
if ctx.explicitNulls then strip(self) else self
45+
strip(self)
4646
}
4747

4848
/** Is self (after widening and dealiasing) a type of the form `T | Null`? */

compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@ object GenericSignatures {
304304
builder.append(')')
305305
methodResultSig(rte)
306306

307+
case OrNull(tp1) if !tp1.derivesFrom(defn.AnyValClass) =>
308+
// Special case for nullable union types whose underlying type is not a value class.
309+
// For example, `T | Null` where `T` is a type parameter becomes `T` in the signature;
310+
// `Int | Null` still becomes `Object`.
311+
jsig1(tp1)
312+
307313
case tp: AndType =>
308314
// Only intersections appearing as the upper-bound of a type parameter
309315
// can be preserved in generic signatures and those are already
@@ -455,15 +461,15 @@ object GenericSignatures {
455461
else x
456462
}
457463

458-
private def collectMethodParams(mtd: MethodOrPoly)(using Context): (List[TypeParamInfo], List[Type], Type) =
464+
private def collectMethodParams(mtd: MethodOrPoly)(using Context): (List[TypeParamInfo], List[Type], Type) =
459465
val tparams = ListBuffer.empty[TypeParamInfo]
460466
val vparams = ListBuffer.empty[Type]
461467

462468
@tailrec def recur(tpe: Type): Type = tpe match
463469
case mtd: MethodType =>
464470
vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot))
465471
recur(mtd.resType)
466-
case PolyType(tps, tpe) =>
472+
case PolyType(tps, tpe) =>
467473
tparams ++= tps
468474
recur(tpe)
469475
case _ =>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
f1(A): A
2+
f2(A): A
3+
g1(T): T
4+
g2(T): T
5+
i(java.lang.Object): java.lang.Object
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class C[T]:
2+
def f1[A](a: A | Null): A | Null = ???
3+
def f2[A](a: A): A = ???
4+
def g1(a: T | Null): T | Null = ???
5+
def g2(a: T): T = ???
6+
def i(a: Int | Null): Int | Null = ???
7+
8+
object Test:
9+
10+
def printGenericSignature(m: java.lang.reflect.Method): Unit =
11+
val tpe = m.getGenericParameterTypes().map(_.getTypeName).mkString(", ")
12+
val ret = m.getGenericReturnType().getTypeName
13+
println(s"${m.getName}($tpe): $ret")
14+
15+
def main(args: Array[String]): Unit =
16+
val c = classOf[C[_]]
17+
printGenericSignature(c.getDeclaredMethod("f1", classOf[Object]))
18+
printGenericSignature(c.getDeclaredMethod("f2", classOf[Object]))
19+
printGenericSignature(c.getDeclaredMethod("g1", classOf[Object]))
20+
printGenericSignature(c.getDeclaredMethod("g2", classOf[Object]))
21+
printGenericSignature(c.getDeclaredMethod("i", classOf[Object]))

0 commit comments

Comments
 (0)