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

double splice in macro fails when using -Yrangepos #6743

Closed
scabug opened this issue Nov 30, 2012 · 9 comments
Closed

double splice in macro fails when using -Yrangepos #6743

scabug opened this issue Nov 30, 2012 · 9 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Nov 30, 2012

Reproduce code:

// Macros.scala
import scala.language.experimental.macros
object Macros{
  def greetMacro( c:reflect.macros.Context )( who : c.Expr[String] ) ={
    c.universe.reify{
      println(who.splice)
      println(who.splice)
    }
  }
  def greet( who: String ) = macro greetMacro
}
// Test.scala
object Test extends App{
  Macros.greet( "test" )
}

Reproduce steps:

  1. scalac -Yrangepos Macros.scala
  2. scalac -Yrangepos Test.scala

Expected result:
compiles

Actual Result:

======= Position error
Synthetic tree [188] contains nonsynthetic tree [46]
== Enclosing tree [188] of type Apply at [40]Test.scala

[L   2        ] #188    [40]            Apply      // Apply(method println)

== Enclosed tree [46] of type Literal at [42:48]Test.scala

[L   2        ] #46     [42:48]         Literal    // "test"


While validating #196
[L   1        ] #196    [0:53]          PackageDef // object Test extends App{

Children:
  [L   1 P#  196] #58     [0:0]           Ident      // o
  [L   1 P#  196] #195    [0:53]          ModuleDef  // Test extends App{
=======
error:
     while compiling: Test.scala
        during phase: typer
     library version: version 2.10.0-RC1
    compiler version: version 2.10.0-RC1
  reconstructed args: -Yrangepos

  last tree to typer: Block
              symbol: null
   symbol definition: null
                 tpe: Unit
       symbol owners:
      context owners: value <local Test> -> object Test -> package <empty>

== Enclosing template or block ==

Template( // val <local Test>: <notype> in object Test
  "App" // parents
  ValDef(
    private
    "_"
    <tpt>
    <empty>
  )
  // 2 statements
  DefDef( // def <init>(): Test.type in object Test
    <method>
    "<init>"
    []
    List(Nil)
    <tpt> // tree.tpe=Test.type
    Block( // tree.tpe=Unit
      Apply( // def <init>(): Object in class Object, tree.tpe=Object
        Test.super."<init>" // def <init>(): Object in class Object, tree.tpe=()Object
        Nil
      )
      ()
    )
  )
  Apply( // def greet(who: String): Unit in object Macros, tree.tpe=Unit
    "Macros"."greet" // def greet(who: String): Unit in object Macros, tree.tpe=(who: String)Unit
    "test"
  )
)

== Expanded type of tree ==

TypeRef(TypeSymbol(final abstract class Unit extends AnyVal))

uncaught exception during compilation: scala.tools.nsc.interactive.RangePositions$ValidateException
error: scala.tools.nsc.interactive.RangePositions$ValidateException: Synthetic tree [188] contains nonsynthetic tree [46]
        at scala.tools.nsc.interactive.RangePositions$class.positionError$1(RangePositions.scala:201)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:218)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$class.validatePositions(RangePositions.scala:246)
        at scala.tools.nsc.Main$$anon$1.validatePositions(Main.scala:73)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:99)
        at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:461)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:90)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:90)
        at scala.collection.Iterator$class.foreach(Iterator.scala:727)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1156)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:90)
        at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1574)
        at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1548)
        at scala.tools.nsc.Global$Run.compileSources(Global.scala:1544)
        at scala.tools.nsc.Global$Run.compile(Global.scala:1654)
        at scala.tools.nsc.Driver.doCompile(Driver.scala:33)
        at scala.tools.nsc.Main$.doCompile(Main.scala:79)
        at scala.tools.nsc.Driver.process(Driver.scala:54)
        at scala.tools.nsc.Driver.main(Driver.scala:67)
        at scala.tools.nsc.Main.main(Main.scala)

Exception in thread "main" scala.tools.nsc.interactive.RangePositions$ValidateException: Synthetic tree [188] contains nonsynthetic tree [46]
        at scala.tools.nsc.interactive.RangePositions$class.positionError$1(RangePositions.scala:201)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:218)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$$anonfun$validate$1$7.apply(RangePositions.scala:241)
        at scala.collection.immutable.List.foreach(List.scala:309)
        at scala.tools.nsc.interactive.RangePositions$class.validate$1(RangePositions.scala:241)
        at scala.tools.nsc.interactive.RangePositions$class.validatePositions(RangePositions.scala:246)
        at scala.tools.nsc.Main$$anon$1.validatePositions(Main.scala:73)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:99)
        at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:461)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:90)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:90)
        at scala.collection.Iterator$class.foreach(Iterator.scala:727)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1156)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:90)
        at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1574)
        at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1548)
        at scala.tools.nsc.Global$Run.compileSources(Global.scala:1544)
        at scala.tools.nsc.Global$Run.compile(Global.scala:1654)
        at scala.tools.nsc.Driver.doCompile(Driver.scala:33)
        at scala.tools.nsc.Main$.doCompile(Main.scala:79)
        at scala.tools.nsc.Driver.process(Driver.scala:54)
        at scala.tools.nsc.Driver.main(Driver.scala:67)
        at scala.tools.nsc.Main.main(Main.scala)
@scabug
Copy link
Author

scabug commented Nov 30, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6743?orig=1
Reporter: @cvogt
Affected Versions: 2.10.0-RC1
Attachments:

  • Macros.scala (created on Nov 30, 2012 7:28:05 PM UTC, 271 bytes)
  • Test.scala (created on Nov 30, 2012 7:28:05 PM UTC, 55 bytes)

@scabug
Copy link
Author

scabug commented Nov 30, 2012

@cvogt said:
I tested RC1, but the problem exists like this or similar in the current 2.10 dev branch as well.

@scabug
Copy link
Author

scabug commented Apr 11, 2013

@jrudolph said:
Seems like #6076 is cheating around the same issue with https://github.com/scala/scala/pull/928/files.

A workaround is to set the position of the resulting tree of the macro to an arbitrary range position:

val res = // original result of the macro
c.Expr[String](atPos(somePos)(res.tree))

@scabug
Copy link
Author

scabug commented Apr 11, 2013

@jrudolph said:
One more comment: the underlying problem seems to be a conflict between what macros generate and what the range position validator expects:

Macros may generate both range positions and offset positions (this seems to be what reify does). The range position validator spews out this error if a tree with a range position is used inside a tree without a range position.

@scabug
Copy link
Author

scabug commented Apr 11, 2013

@retronym said:
I believe that we can disable validation of range position invariants by marking trees with "transparent" positions. I'm going to look into macro positions more in the context of scala-async, so I'll keep this ticket in mind.

@scabug
Copy link
Author

scabug commented Apr 18, 2013

@etorreborre said:
I have a macro called snippet that I use to capture pieces of code and using the workaround mentioned by Johannes.

However it returns the same kind of compiler error: "contains nonsynthetic tree", on the following code:

snippet {
  object AnInt { def unapply(a: String): Option[Int] = Some(a.toInt)}
  def f: PartialFunction[String, Int] = { case AnInt(i)  => i }
}

@scabug
Copy link
Author

scabug commented Dec 12, 2013

@som-snytt said:
Is this the issue for misc macro + -Yrangepos validation errors?

The conversation continued on the ML months later:

https://groups.google.com/d/msg/scala-internals/fmWKw5TDz98/SRXDDGPmzZEJ

@scabug
Copy link
Author

scabug commented Dec 12, 2013

@xeno-by said:
I will try to take a look before RC1.

@scabug
Copy link
Author

scabug commented Jan 22, 2014

@xeno-by said:
The issue seems to be fixed in master, probably thanks to Jason's work on IDE integration.

@scabug scabug closed this as completed Jan 22, 2014
@scabug scabug added the macros label Apr 7, 2017
@scabug scabug added this to the 2.11.0-RC1 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants