Skip to content

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

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

Closed
rssh opened this issue Feb 25, 2023 · 1 comment · Fixed by #20087
Assignees
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug regression This worked in a previous version but doesn't anymore
Milestone

Comments

@rssh
Copy link
Contributor

rssh commented Feb 25, 2023

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

@rssh rssh added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 25, 2023
@rssh
Copy link
Contributor Author

rssh commented Feb 25, 2023

nn-badtypes.tar.gz

(ready to run sbt project)

@Kordyjan Kordyjan added area:metaprogramming:reflection Issues related to the quotes reflection API regression This worked in a previous version but doesn't anymore and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 27, 2023
@Kordyjan Kordyjan added this to the Future versions milestone Feb 27, 2023
nicolasstucki added a commit that referenced this issue Apr 5, 2024
…20087)

Fixes #17009 
The problem here was with the sub typing check for `line.split(" ").nn`,
which needed to confirm that:

```scala
(?2 : Array[String]) & Array[String]  <:  (?1 : Array[String]) & Array[String]
```
`TypeComparer` would eventually try to compare two skolem types:
```scala
(?2 : Array[String]) <: (?1 : Array[String])
```
The behavior of `TypeComparer` differs here when executed during the
typer phase, where it always returns false for two skolem types, without
checking the sub typing further. This makes sense for Typer, but not so
much for the macro checks, which for `transparent inline`s end up being
executed during Typer. I think the best solution here is to artificially
change the phase in the checkingContext, so the checks done for
transparent and non-transparent macros are the same.
@Kordyjan Kordyjan modified the milestones: Future versions, 3.5.0 May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants