Skip to content

Warn when calling synchronized on Predef or on synthetic file objects #17266

Closed
@mbovel

Description

@mbovel

Consider the following code in sync.scala:

package myPackage:
	def test1 = synchronized { println("1 starting"); Thread.sleep(2000); println("Ok t1 finished.") }
	def test2 = this.synchronized { println("2 starting"); Thread.sleep(2000); println("Ok t2 finished"); }

object MyObject:
	def test3 = synchronized { println("3 starting"); Thread.sleep(2000); println("Ok t3 finished.") }
	def test4 = this.synchronized { println("4 starting"); Thread.sleep(2000); println("Ok t4 finished"); }

scala-cli compile -Xprint:typer -Yprint-debug sync.scala ouputs:

package <root>.this.myPackage {
    final lazy module val sync2$package: myPackage.this.sync2$package$ = 
      new myPackage.this.sync2$package$.<init>()
    final module class sync2$package$() extends Object.<init>() { 
      this: myPackage.this.sync2$package.type =>
      def test1: scala.this.Unit(inf) = 
        scala.this.Predef.synchronized[scala.this.Unit^(inf)](
          {
            scala.this.Predef.println("1 starting")
            java.this.lang.Thread.sleep(2000L)
            scala.this.Predef.println("Ok t1 finished.")
          }
        )
      def test2: scala.this.Unit(inf) = 
        this.synchronized[scala.this.Unit^(inf)](
          {
            scala.this.Predef.println("2 starting")
            java.this.lang.Thread.sleep(2000L)
            scala.this.Predef.println("Ok t2 finished")
          }
        )
    }
  }
  final lazy module val MyObject: <empty>.this.MyObject$ = 
    new <empty>.this.MyObject$.<init>()
  final module class MyObject$() extends Object.<init>() { 
    this: <empty>.this.MyObject.type =>
    def test3: scala.this.Unit(inf) = 
      MyObject$.this.synchronized[scala.this.Unit^(inf)](
        {
          scala.this.Predef.println("3 starting")
          java.this.lang.Thread.sleep(2000L)
          scala.this.Predef.println("Ok t3 finished.")
        }
      )
    def test4: scala.this.Unit(inf) = 
      this.synchronized[scala.this.Unit^(inf)](
        {
          scala.this.Predef.println("4 starting")
          java.this.lang.Thread.sleep(2000L)
          scala.this.Predef.println("Ok t4 finished")
        }
      )
  }

C.f., the first synchronized is desugared to Predef.synchronized. This sounds rather confusing.

We should probably issue a warning in this case, and also when calling this.synchronized from top-level functions.

More context in #7713 (comment).

Metadata

Metadata

Assignees

No one assigned

    Labels

    SpreeSuitable for a future Spreearea:reportingError reporting including formatting, implicit suggestions, etcitype:enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions