diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index b77c21893ef7..3d07f2b87250 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3746,6 +3746,15 @@ class Typer extends Namer if target <:< pt then return readapt(tree.cast(target)) + // if unsafeNulls is enabled, try to strip nulls from Java function calls + if Nullables.unsafeNullsEnabled then + tree match + case _: Apply | _: Select if tree.symbol.is(JavaDefined) => + wtp match + case OrNull(wtp1) => return readapt(tree.cast(wtp1)) + case _ => + case _ => + def recover(failure: SearchFailureType) = if canDefineFurther(wtp) || canDefineFurther(pt) then readapt(tree) else err.typeMismatch(tree, pt, failure) diff --git a/tests/explicit-nulls/unsafe-common/unsafe-java-call/J.java b/tests/explicit-nulls/unsafe-common/unsafe-java-call/J.java new file mode 100644 index 000000000000..554b91749889 --- /dev/null +++ b/tests/explicit-nulls/unsafe-common/unsafe-java-call/J.java @@ -0,0 +1,17 @@ +public class J { + public String f1() { + return ""; + } + + public int f2() { + return 0; + } + + public T g1() { + return null; + } +} + +class J2 { + public T x = null; +} \ No newline at end of file diff --git a/tests/explicit-nulls/unsafe-common/unsafe-java-call/S.scala b/tests/explicit-nulls/unsafe-common/unsafe-java-call/S.scala new file mode 100644 index 000000000000..3b5108bacfa9 --- /dev/null +++ b/tests/explicit-nulls/unsafe-common/unsafe-java-call/S.scala @@ -0,0 +1,37 @@ +// Check Java calls have been cast to non-nullable. + +val j: J = new J + +val s1: String = j.f1() // error + +val s1n: String | Null = j.f1() + +val i1: Int = j.f2() + +val s2: String = j.g1[String]() // error + +val s2n: String | Null = j.g1[String]() + +val s3: String = j.g1[String | Null]() // error + +val s3n: String | Null = j.g1[String | Null]() + +val i2: Int = j.g1[Int]() // error + +val a1: Any = j.g1[Any]() + +val ar1: AnyRef = j.g1[AnyRef]() // error + +val n1: Null = j.g1[Null]() + +val ar2: AnyRef = j.g1[Null]() // error + +def clo1[T]: T = j.g1[T]() // error + +def clo2[T <: AnyRef]: T = j.g1[T | Null]() // error + +def clo3[T >: Null <: AnyRef | Null]: T = j.g1[T]() + +def testJ2[T]: T = + val j2: J2[T] = new J2 + j2.x // error