Skip to content

Copying block in macro with valdef with explicit null expression cause error with -XcheckMacro (regression) #17009

Closed
@rssh

Description

@rssh

Compiler version

master bracnh from 2023.02.25. (3.3.1-RC1-bin-SNAPSHOT)

options enabled: "-Yexplicit-nulls", "-Xcheck-macros"

Minimized code

main.scala

package x

def processLine(line: String): Unit = {
    Test.transform{
      val x = line.split(" ").nn
      ???
    }
}

macro.scala

package x

import scala.quoted._

object Test {


  transparent inline def transform[T](inline expr: T): T =
  ${
         transformImpl[T]('expr)
  }

  def transformImpl[T:Type](f: Expr[T])(using Quotes): Expr[T] = {
     import quotes.reflect.*
     f.asTerm match
       case Inlined(x,binding,body) =>
          Inlined(x,binding,transformImpl(body.asExprOf[T]).asTerm).asExprOf[T]
       case Block(stats,last) =>
          Block(stats,last).asExprOf[T]
       case _ =>
          f
  }

}

Output

[error] -- Error: /Users/rssh/tests/dotty/nn-badtypes/src/main/scala/main.scala:4:18 ---
[error]  4 |    Test.transform{
[error]    |    ^
[error]    |Malformed tree was found while expanding macro with -Xcheck-macros.
[error]    |               |The tree does not conform to the compiler's tree invariants.
[error]    |               |
[error]    |               |Macro was:
[error]    |               |scala.quoted.runtime.Expr.splice[scala.Nothing](((evidence$2: scala.quoted.Quotes) ?=> x.Test.transformImpl[scala.Nothing](scala.quoted.runtime.Expr.quote[scala.Nothing](({
[error]    |  val x: scala.Array[java.lang.String | scala.Null] = scala.Predef.nn[scala.Array[java.lang.String | scala.Null]](line.split(" "))
[error]    |  scala.Predef.???
[error]    |}: scala.Nothing @scala.annotation.internal.InlineParam)).apply(using evidence$2))(scala.quoted.Type.of[scala.Nothing](evidence$2), evidence$2)))
[error]    |               |
[error]    |               |The macro returned:
[error]    |               |({
[error]    |  val x: scala.Array[java.lang.String | scala.Null] = scala.Predef.nn[scala.Array[java.lang.String | scala.Null]](line.split(" "))
[error]    |  scala.Predef.???
[error]    |}: scala.Nothing @scala.annotation.internal.InlineParam)
[error]    |               |
[error]    |               |Error:
[error]    |               |assertion failed: Types differ
[error]    |Original type : (?1 : Array[String | Null] | Null) & Array[String | Null]
[error]    |After checking: (?2 : Array[String | Null] | Null) & Array[String | Null]
[error]    |Original tree : nn[Array[String | Null]](line.split(" "))
[error]    |After checking: nn[Array[String | Null]](line.split(" "))
[error]    |Why different :
[error]    |             Subtype trace:
[error]    |  ==> (?2 : Array[String | Null] | Null) & Array[String | Null]  <:  (?1 : Array[String | Null] | Null) & Array[String | Null]
[error]    |    ==> (?2 : Array[String | Null] | Null) & Array[String | Null]  <:  (?1 : Array[String | Null] | Null)
[error]    |      ==> (?2 : Array[String | Null] | Null)  <:  (?1 : Array[String | Null] | Null)
[error]    |        ==> Array[String | Null] | Null  <:  (?1 : Array[String | Null] | Null) (left is approximated)
[error]    |          ==> Array[String | Null] | Null  <:  Nothing (left is approximated)
[error]    |            ==> Array[String | Null]  <:  Nothing (left is approximated)
[error]    |            <== Array[String | Null]  <:  Nothing (left is approximated) = false
[error]    |          <== Array[String | Null] | Null  <:  Nothing (left is approximated) = false
[error]    |        <== Array[String | Null] | Null  <:  (?1 : Array[String | Null] | Null) (left is approximated) = false
[error]    |      <== (?2 : Array[String | Null] | Null)  <:  (?1 : Array[String | Null] | Null) = false
[error]    |      ==> Array[String | Null]  <:  (?1 : Array[String | Null] | Null)
[error]    |      <== Array[String | Null]  <:  (?1 : Array[String | Null] | Null) = false
[error]    |    <== (?2 : Array[String | Null] | Null) & Array[String | Null]  <:  (?1 : Array[String | Null] | Null) = false
[error]    |  <== (?2 : Array[String | Null] | Null) & Array[String | Null]  <:  (?1 : Array[String | Null] | Null) & Array[String | Null] = false
[error]    |               |
[error]    |stacktrace available when compiling with `-Ydebug`
[error]    |               |
[error]  5 |      val x = line.split(" ").nn
[error]  6 |      ???
[error]  7 |    }
[error]    |----------------------------------------------------------------------------
[error]    |Inline stack trace
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from mcps.scala:9
[error]  9 |  ${
[error]    |  ^
[error] 10 |         transformImpl[T]('expr)
[error] 11 |  }
[error]     ----------------------------------------------------------------------------
[error] one error found

Expectation

should be compiled.

Note, that this is compiled with 3.2.2

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions