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

broken Inlining type checks for proxied nn calls #13197

Closed
yuriy-yarosh opened this issue Jul 28, 2021 · 1 comment · Fixed by #13590
Closed

broken Inlining type checks for proxied nn calls #13197

yuriy-yarosh opened this issue Jul 28, 2021 · 1 comment · Fixed by #13590

Comments

@yuriy-yarosh
Copy link

Compiler version

Scala 3.0.2.-RC1 with "-Ycheck:all"

Minimized code

import software.amazon.awssdk.services.s3.model.*

case class Bucket(name: String):

  case class Object(
    key: String, 
    anything: Any = None, // Compiles if this deleted
    bucketKeyEnabled: Boolean = false
  )

  object Object:

    def fromS3Multipart(awsResp: CompleteMultipartUploadResponse): Object = 
      Object(
        key = awsResp.key().nn,
        bucketKeyEnabled = awsResp.bucketKeyEnabled().nn
      )

Output

exception while typing {
  val x$proxy1: String | Null = awsResp.key()
  scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
} of class class dotty.tools.dotc.ast.Trees$Inlined # -1
exception while typing val key$1: (?1 : String | Null) & String =
  {
    val x$proxy1: String | Null = awsResp.key()
    scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
  } of class class dotty.tools.dotc.ast.Trees$ValDef # -1
exception while typing {
  val key$1: (?1 : String | Null) & String =
    {
      val x$proxy1: String | Null = awsResp.key()
      scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
    }
  val bucketKeyEnabled$1: Boolean =
    Boolean2boolean(
      {
        val x$proxy2: Boolean | Null = awsResp.bucketKeyEnabled()
        scala.runtime.Scala3RunTime.nn[Boolean](x$proxy2):x$proxy2.type & Boolean
      }
    )
  val anything$1: Any @uncheckedVariance = io.bitsnap.lambdr.aws.Object.$lessinit$greater$default$2
  io.bitsnap.lambdr.aws.Object.apply(key = key$1, anything$1, bucketKeyEnabled = bucketKeyEnabled$1)
} of class class dotty.tools.dotc.ast.Trees$Block # -1
exception while typing def fromS3Multipart(awsResp: software.amazon.awssdk.services.s3.model.CompleteMultipartUploadResponse): io.bitsnap.lambdr.aws.Object =
  {
    val key$1: (?1 : String | Null) & String =
      {
        val x$proxy1: String | Null = awsResp.key()
        scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
      }
    val bucketKeyEnabled$1: Boolean =
      Boolean2boolean(
        {
          val x$proxy2: Boolean | Null = awsResp.bucketKeyEnabled()
          scala.runtime.Scala3RunTime.nn[Boolean](x$proxy2):x$proxy2.type & Boolean
        }
      )
    val anything$1: Any @uncheckedVariance = io.bitsnap.lambdr.aws.Object.$lessinit$greater$default$2
    io.bitsnap.lambdr.aws.Object.apply(key = key$1, anything$1, bucketKeyEnabled = bucketKeyEnabled$1)
  } of class class dotty.tools.dotc.ast.Trees$DefDef # -1
exception while typing @scala.annotation.internal.SourceFile("providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala") final module class Object() extends Object(), scala.deriving.Mirror.Product {
  this: io.bitsnap.lambdr.aws.Object.type =>
  private def writeReplace(): AnyRef = new scala.runtime.ModuleSerializationProxy(classOf[io.bitsnap.lambdr.aws.Object.type])
  def apply(key: String, anything: Any, bucketKeyEnabled: Boolean): io.bitsnap.lambdr.aws.Object = new io.bitsnap.lambdr.aws.Object(key, anything, bucketKeyEnabled)
  def unapply(x$1: io.bitsnap.lambdr.aws.Object): io.bitsnap.lambdr.aws.Object = x$1
  override def toString: String = "Object"
  def $lessinit$greater$default$2: Any @uncheckedVariance = None
  def $lessinit$greater$default$3: Boolean @uncheckedVariance = false
  def fromS3Multipart(awsResp: software.amazon.awssdk.services.s3.model.CompleteMultipartUploadResponse): io.bitsnap.lambdr.aws.Object =
    {
      val key$1: (?1 : String | Null) & String =
        {
          val x$proxy1: String | Null = awsResp.key()
          scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
        }
      val bucketKeyEnabled$1: Boolean =
        Boolean2boolean(
          {
            val x$proxy2: Boolean | Null = awsResp.bucketKeyEnabled()
            scala.runtime.Scala3RunTime.nn[Boolean](x$proxy2):x$proxy2.type & Boolean
          }
        )
      val anything$1: Any @uncheckedVariance = io.bitsnap.lambdr.aws.Object.$lessinit$greater$default$2
      io.bitsnap.lambdr.aws.Object.apply(key = key$1, anything$1, bucketKeyEnabled = bucketKeyEnabled$1)
    }
  type MirroredMonoType = io.bitsnap.lambdr.aws.Object
  def fromProduct(x$0: Product): io.bitsnap.lambdr.aws.Object.MirroredMonoType =
    new io.bitsnap.lambdr.aws.Object(x$0.productElement(0).$asInstanceOf[String], x$0.productElement(1), x$0.productElement(2).$asInstanceOf[Boolean])
} of class class dotty.tools.dotc.ast.Trees$TypeDef # -1
exception while typing package io.bitsnap.lambdr.aws {
  import software.amazon.awssdk.services.s3.model.*
  @scala.annotation.internal.SourceFile("providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala") case class Object(key: String, anything: Any, bucketKeyEnabled: Boolean) extends

  Object(), _root_.scala.Product, _root_.scala.Serializable {
    override def hashCode(): Int =
      {
        var acc: Int = -889275714
        acc = scala.runtime.Statics#mix(acc, this.productPrefix.hashCode())
        acc = scala.runtime.Statics#mix(acc, scala.runtime.Statics#anyHash(Object.this.key))
        acc = scala.runtime.Statics#mix(acc, scala.runtime.Statics#anyHash(Object.this.anything))
        acc = scala.runtime.Statics#mix(acc, if Object.this.bucketKeyEnabled then 1231 else 1237)
        scala.runtime.Statics#finalizeHash(acc, 3)
      }
    override def equals(x$0: Any): Boolean =
      this.eq(x$0.$asInstanceOf[Object]).||(
        x$0 match
          {
            case x$0 @ _:io.bitsnap.lambdr.aws.Object @unchecked =>
              this.bucketKeyEnabled.==(x$0.bucketKeyEnabled).&&(this.key.==(x$0.key)).&&(this.anything.==(x$0.anything)).&&(x$0.canEqual(this))
            case _ => false
          }
      )
    override def toString(): String = scala.runtime.ScalaRunTime._toString(this)
    override def canEqual(that: Any): Boolean = that.isInstanceOf[io.bitsnap.lambdr.aws.Object @unchecked]
    override def productArity: Int = 3
    override def productPrefix: String = "Object"
    override def productElement(n: Int): Any =
      n match
        {
          case 0 => this._1
          case 1 => this._2
          case 2 => this._3
          case _ => throw new IndexOutOfBoundsException(n.toString())
        }
    override def productElementName(n: Int): String =
      n match
        {
          case 0 => "key"
          case 1 => "anything"
          case 2 => "bucketKeyEnabled"
          case _ => throw new IndexOutOfBoundsException(n.toString())
        }
    val key: String
    val anything: Any
    val bucketKeyEnabled: Boolean
    def copy(key: String, anything: Any, bucketKeyEnabled: Boolean): io.bitsnap.lambdr.aws.Object = new io.bitsnap.lambdr.aws.Object(key, anything, bucketKeyEnabled)
    def copy$default$1: String @uncheckedVariance = Object.this.key
    def copy$default$2: Any @uncheckedVariance = Object.this.anything
    def copy$default$3: Boolean @uncheckedVariance = Object.this.bucketKeyEnabled
    def _1: String = this.key
    def _2: Any = this.anything
    def _3: Boolean = this.bucketKeyEnabled
  }
  final lazy module val Object: io.bitsnap.lambdr.aws.Object = new io.bitsnap.lambdr.aws.Object()
  @scala.annotation.internal.SourceFile("providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala") final module class Object() extends Object(), scala.deriving.Mirror.Product {
    this: io.bitsnap.lambdr.aws.Object.type =>
    private def writeReplace(): AnyRef = new scala.runtime.ModuleSerializationProxy(classOf[io.bitsnap.lambdr.aws.Object.type])
    def apply(key: String, anything: Any, bucketKeyEnabled: Boolean): io.bitsnap.lambdr.aws.Object = new io.bitsnap.lambdr.aws.Object(key, anything, bucketKeyEnabled)
    def unapply(x$1: io.bitsnap.lambdr.aws.Object): io.bitsnap.lambdr.aws.Object = x$1
    override def toString: String = "Object"
    def $lessinit$greater$default$2: Any @uncheckedVariance = None
    def $lessinit$greater$default$3: Boolean @uncheckedVariance = false
    def fromS3Multipart(awsResp: software.amazon.awssdk.services.s3.model.CompleteMultipartUploadResponse): io.bitsnap.lambdr.aws.Object =
      {
        val key$1: (?1 : String | Null) & String =
          {
            val x$proxy1: String | Null = awsResp.key()
            scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
          }
        val bucketKeyEnabled$1: Boolean =
          Boolean2boolean(
            {
              val x$proxy2: Boolean | Null = awsResp.bucketKeyEnabled()
              scala.runtime.Scala3RunTime.nn[Boolean](x$proxy2):x$proxy2.type & Boolean
            }
          )
        val anything$1: Any @uncheckedVariance = io.bitsnap.lambdr.aws.Object.$lessinit$greater$default$2
        io.bitsnap.lambdr.aws.Object.apply(key = key$1, anything$1, bucketKeyEnabled = bucketKeyEnabled$1)
      }
    type MirroredMonoType = io.bitsnap.lambdr.aws.Object
    def fromProduct(x$0: Product): io.bitsnap.lambdr.aws.Object.MirroredMonoType =
      new io.bitsnap.lambdr.aws.Object(x$0.productElement(0).$asInstanceOf[String], x$0.productElement(1), x$0.productElement(2).$asInstanceOf[Boolean])
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # -1
*** error while checking /home/yura/src/lambdr/providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala after phase inlining ***
[info] exception occurred while compiling /home/yura/src/lambdr/providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala
java.lang.AssertionError: assertion failed: Found:    (x$proxy1 : String | Null) & String
Required: (?1 : String | Null) & String

where:    ?1 is an unknown value of type String | Null

found: ??
expected: ??
tree = scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String while compiling 
/lambdr/providers/lambdr-aws/src/io/bitsnap/lambdr/aws/err.scala
[error] ## Exception when compiling 12 sources to /lambdr/providers/lambdr-aws/target/scala-3.0.2-RC1/classes
[error] java.lang.AssertionError: assertion failed: Found:    (x$proxy1 : String | Null) & String
[error] Required: (?1 : String | Null) & String
[error]
[error] where:    ?1 is an unknown value of type String | Null
[error]
[error] found: ??
[error] expected: ??
[error] tree = scala.runtime.Scala3RunTime.nn[String](x$proxy1):x$proxy1.type & String
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.adapt(TreeChecker.scala:599)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2821)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2818)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2825)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:310)
[error] dotty.tools.dotc.typer.Typer.typedInlined(Typer.scala:1768)

Expectation

For it to Type Check Correctly.

It compiles if anything: Any = None field is deleted.

@griggt
Copy link
Contributor

griggt commented Jul 29, 2021

Self-contained:

trait Bar:
  def b: String | Null

class Foo(a: String = "", b: String)
object Foo:    
  def foo(bar: Bar) = Foo(b = bar.b.nn)

Compile with -Yexplicit-nulls -Ycheck:all

@yuriy-yarosh yuriy-yarosh changed the title broken Inlining type checks for proxied Java nn calls broken Inlining type checks for proxied nn calls Jul 29, 2021
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
@Kordyjan Kordyjan added this to the 3.1.1 milestone Aug 2, 2023
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.

4 participants