Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive dead code elimination on pure expressions #17317

Closed
kubukoz opened this issue Apr 19, 2023 · 2 comments · Fixed by #19598
Closed

False positive dead code elimination on pure expressions #17317

kubukoz opened this issue Apr 19, 2023 · 2 comments · Fixed by #19598

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Apr 19, 2023

Compiler version

3.3.0-RC3, 3.2.2

Minimized code

Sample 1

//> using scala "3.2.2"

package object foo {

  object HelloGen {
    println("hello world")
  }

  val Hello = HelloGen
}

import foo.Hello

object Main {

  def main(args: Array[String]): Unit = Hello: Unit
}

Sample 2

Instead of a package object, use a top-level definition.

//> using scala "3.2.2"


object HelloGen {
  println("hello world")
}

val Hello = HelloGen


object Main {

  def main(args: Array[String]): Unit = Hello: Unit
}

Output

Compiling project (Scala 3.3.0-RC3, JVM)
[warn] ./main.scala:13:5
[warn] A pure expression does nothing in statement position; you may be omitting necessary parentheses
[warn]     Hello: Unit
[warn]     ^^^^^
Compiled project (Scala 3.3.0-RC3, JVM)

Expectation

Compiling project (Scala 3.3.0-RC3, JVM)
Compiled project (Scala 3.3.0-RC3, JVM)
hello world

Notes:

  1. Here's javap verbose for main:
public void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=0, locals=2, args_size=2
         0: return
      LineNumberTable:
        line 16: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  this   LMain$;
            0       1     1  args   [Ljava/lang/String;
    Signature: #27                          // ([Ljava/lang/String;)V
    MethodParameters:
      Name                           Flags
      args                           final

Notably the code is just a return, as the call is erased from the output.

  1. This doesn't happen in Scala 2.13 or if you fully qualify foo.Hello.
@kubukoz kubukoz added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 19, 2023
@kubukoz kubukoz changed the title False positive "A pure expression does nothing in statement position" False positive dead code elimination on pure expressions Apr 19, 2023
@jchyb jchyb added area:transform and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 20, 2023
@aherlihy
Copy link
Contributor

aherlihy commented Feb 1, 2024

WIP notes:

  • the Hello gets tagged as a purity level 3, so it's removed
  • it is not actually pure, it's a val in an object that is assigned from a lazyval so the expression has the stable flag but not a lazy flag
  • adding a path, so foo.Hello will fix the issue because it's not tagged as purity level 3
  • doesn't matter if object or package object
  • potential incoherence in handling: slightly different tree shapes between with path/without path (should be Ident (without the foo.) but ends up being Apply)
  • defining Hello as a lazy val will work around the problem for now

aherlihy added a commit to aherlihy/scala3 that referenced this issue Feb 2, 2024
aherlihy added a commit to aherlihy/scala3 that referenced this issue Feb 2, 2024
aherlihy added a commit to aherlihy/scala3 that referenced this issue Feb 2, 2024
@mbovel
Copy link
Member

mbovel commented Feb 8, 2024

Another minimization (I just needed it to convince myself the problem was indeed the import 😉):

//> using scala "3.2.2"

package objectInit

object Hello:
    println("hello world")

object HelloProxy:
    val hello = Hello

@main def doesntPrint: Unit =
    import HelloProxy.hello
    hello

@main def prints: Unit =
    HelloProxy.hello

Run with:

$ scala-cli --server=false -M objectInit.prints objectInit.scala
$ scala-cli --server=false -M objectInit.doesntPrint objectInit.scala

sjrd added a commit that referenced this issue Feb 9, 2024
@Kordyjan Kordyjan added this to the 3.4.1 milestone Feb 14, 2024
WojciechMazur pushed a commit that referenced this issue Jun 28, 2024
WojciechMazur pushed a commit that referenced this issue Jun 30, 2024
WojciechMazur pushed a commit that referenced this issue Jun 30, 2024
WojciechMazur pushed a commit that referenced this issue Jun 30, 2024
WojciechMazur pushed a commit that referenced this issue Jun 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants