Skip to content

-Yexplicit-nulls fails to detect null pointer dereference #21380

Closed
@theosotr

Description

@theosotr

-Yexplicit-nulls fails to detect method call on a variable holding null.
This might be regression, as scalac v3.3.3 detects the error as expected.

Compiler version

3.4.2

Minimized code

@main def test() = {
  var x: String | Null = null
  if (false) {
    x = ""

  } else {
    x = ""
  }
  try {
    x = ""
    throw new Exception()
  }
  catch {
    case e: Exception => {
      x = null
    }
  }
  x.replace("", "") 
}

Output

The code compiles with -Yexplicit-nulls, but at runtime you get NPE

java.lang.NullPointerException
	at test$package$.test(test.scala:18)
	at test.main(test.scala:1)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at dotty.tools.runner.RichClassLoader$.run$extension$$anonfun$1(ScalaClassLoader.scala:36)
	at dotty.tools.runner.ScalaClassLoader$.asContext(ScalaClassLoader.scala:80)
	at dotty.tools.runner.RichClassLoader$.dotty$tools$runner$RichClassLoader$$$asContext$extension(ScalaClassLoader.scala:18)
	at dotty.tools.runner.RichClassLoader$.run$extension(ScalaClassLoader.scala:36)
	at dotty.tools.runner.CommonRunner.run(ObjectRunner.scala:23)
	at dotty.tools.runner.CommonRunner.run$(ObjectRunner.scala:13)
	at dotty.tools.runner.ObjectRunner$.run(ObjectRunner.scala:48)
	at dotty.tools.runner.CommonRunner.runAndCatch(ObjectRunner.scala:30)
	at dotty.tools.runner.CommonRunner.runAndCatch$(ObjectRunner.scala:13)
	at dotty.tools.runner.ObjectRunner$.runAndCatch(ObjectRunner.scala:48)
	at dotty.tools.MainGenericRunner$.run$1(MainGenericRunner.scala:215)
	at dotty.tools.MainGenericRunner$.process(MainGenericRunner.scala:270)
	at dotty.tools.MainGenericRunner$.main(MainGenericRunner.scala:281)
	at dotty.tools.MainGenericRunner.main(MainGenericRunner.scala)

Expectation

The code should have been rejected with

-- [E008] Not Found Error: test.scala:18:4 ----------------------------------------------------------------------------------------------------------------------------------------------------
18 |  x.replace("", "")
   |  ^^^^^^^^^
   |  value replace is not a member of String | Null.
   |  Since explicit-nulls is enabled, the selection is rejected because
   |  String | Null could be null at runtime.
   |  If you want to select replace without checking for a null value,
   |  insert a .nn before .replace or import scala.language.unsafeNulls.
1 error found

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions