Skip to content

Commit

Permalink
Fix varargs
Browse files Browse the repository at this point in the history
  • Loading branch information
noti0na1 committed Oct 11, 2023
1 parent 45f56cb commit eb01981
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 9 deletions.
12 changes: 7 additions & 5 deletions compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,22 @@ object JavaNullInterop {

/** Should we nullify `tp` at the outermost level? */
def needsNull(tp: Type): Boolean =
!outermostLevelAlreadyNullable && (tp match {
!(outermostLevelAlreadyNullable || (tp match {
case tp: TypeRef =>
// We don't modify value types because they're non-nullable even in Java.
!tp.symbol.isValueClass &&
tp.symbol.isValueClass
// We don't modify unit types.
|| tp.isRef(defn.UnitClass)
// We don't modify `Any` because it's already nullable.
!tp.isRef(defn.AnyClass) &&
|| tp.isRef(defn.AnyClass)
// We don't nullify Java varargs at the top level.
// Example: if `setNames` is a Java method with signature `void setNames(String... names)`,
// then its Scala signature will be `def setNames(names: (String|Null)*): Unit`.
// This is because `setNames(null)` passes as argument a single-element array containing the value `null`,
// and not a `null` array.
!tp.isRef(defn.RepeatedParamClass)
|| !ctx.flexibleTypes && tp.isRef(defn.RepeatedParamClass)
case _ => true
})
}))

override def apply(tp: Type): Type = tp match {
case tp: TypeRef if needsNull(tp) => nullify(tp)
Expand Down
10 changes: 6 additions & 4 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -970,13 +970,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// A sequence argument `xs: _*` can be either a `Seq[T]` or an `Array[_ <: T]`,
// irrespective of whether the method we're calling is a Java or Scala method,
// so the expected type is the union `Seq[T] | Array[_ <: T]`.
val ptArg =
val pt1 = pt.stripFlexible
val ptArg0 =
// FIXME(#8680): Quoted patterns do not support Array repeated arguments
if ctx.mode.isQuotedPattern then
pt.translateFromRepeated(toArray = false, translateWildcard = true)
pt1.translateFromRepeated(toArray = false, translateWildcard = true)
else
pt.translateFromRepeated(toArray = false, translateWildcard = true)
| pt.translateFromRepeated(toArray = true, translateWildcard = true)
pt1.translateFromRepeated(toArray = false, translateWildcard = true)
| pt1.translateFromRepeated(toArray = true, translateWildcard = true)
val ptArg = if pt1 eq pt then ptArg0 else FlexibleType(ptArg0)
val expr0 = typedExpr(tree.expr, ptArg)
val expr1 = if ctx.explicitNulls && (!ctx.mode.is(Mode.Pattern)) then
if expr0.tpe.isNullType then
Expand Down

0 comments on commit eb01981

Please sign in to comment.