diff --git a/compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala b/compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala index 6fa76f927dca..37f32a9b2b16 100644 --- a/compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala +++ b/compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 363c466e62d9..495eafcfffd4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -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