Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-9392

compiler crash in new JVM backend with shapeless

    Details

    • Type: Bug
    • Status: CLOSED
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: Scala 2.12.0-M2
    • Fix Version/s: Scala 2.12.0-M2
    • Component/s: Compiler Backend
    • Labels:
      None

      Description

      Compiling the following,

      import shapeless._
      case class Quux()
      Lazy[Generic[Quux]]
      

      with Scala 2.12.0-M2 against the shapeless-2.2.4 source tree results in the following crash,

      java.lang.AssertionError: assertion failed: Cannot create ClassBType from non-class symbol value <local L                                                                                                                                      azyTests>                                                                                                                                                                                                                                      
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:105                                                                                                                                      )                                                                                                                                                                                                                                              
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.buildNestedInfo(BTypesFromSymbols.scala:379)                                                                                                                                          
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.setClassInfo(BTypesFromSymbols.scala:340)                                                                                                                                             
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$                                                                                                                                      anonfun$4(BTypesFromSymbols.scala:120)                                                                                                                                                                                                         
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1335/31327414.apply(Unknown Source)                                                                                                                                           
              at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)                                                                                                                                                                         
              at scala.collection.concurrent.TrieMap.getOrElse(TrieMap.scala:633)                                                                                                                                                                    
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:112                                                                                                                                      )                                                                                                                                                                                                                                              
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$                                                                                                                                      anonfun$8(BTypesFromSymbols.scala:153)                                                                                                                                                                                                         
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1372/756156527.apply(Unknown Source)                                                                                                                                          
              at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)                                                                                                                                                                         
              at scala.collection.AbstractMap.getOrElse(Map.scala:59)                                                                                                                                                                                
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.primitiveOrClassToBType$1(BTypesFromSymbols.scal                                                                                                                                      a:153)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.typeToBType(BTypesFromSymbols.scala:168)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.methodBTypeFromSymbol(BTypesFromSymbols.scala:133)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$anonfun$37(BTypesFromSymbols.scala:412)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1391/428986689.apply(Unknown Source)
              at scala.tools.nsc.backend.jvm.BCodeAsmCommon.scala$tools$nsc$backend$jvm$BCodeAsmCommon$$$anonfun$21(BCodeAsmCommon.scala:394)
              at scala.tools.nsc.backend.jvm.BCodeAsmCommon$$Lambda$1393/936737348.apply(Unknown Source)
              at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:435)
              at scala.collection.Iterator$class.foreach(Iterator.scala:781)
              at scala.collection.AbstractIterator.foreach(Iterator.scala:1267)
              at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:314)
              at scala.collection.AbstractIterator.toMap(Iterator.scala:1267)
              at scala.tools.nsc.backend.jvm.BCodeAsmCommon.buildInlineInfoFromClassSymbol(BCodeAsmCommon.scala:436)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.buildFromSymbol$1(BTypesFromSymbols.scala:412)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.buildInlineInfo(BTypesFromSymbols.scala:417)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.setClassInfo(BTypesFromSymbols.scala:342)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$anonfun$4(BTypesFromSymbols.scala:120)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1335/31327414.apply(Unknown Source)
              at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
              at scala.collection.concurrent.TrieMap.getOrElse(TrieMap.scala:633)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:112)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$anonfun$31(BTypesFromSymbols.scala:338)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1347/1555324219.apply(Unknown Source)
              at scala.collection.immutable.List.map(List.scala:277)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.setClassInfo(BTypesFromSymbols.scala:338)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.scala$tools$nsc$backend$jvm$BTypesFromSymbols$$$anonfun$4(BTypesFromSymbols.scala:120)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols$$Lambda$1335/31327414.apply(Unknown Source)
              at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
              at scala.collection.concurrent.TrieMap.getOrElse(TrieMap.scala:633)
              at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:112)
              at scala.tools.nsc.backend.jvm.BCodeHelpers$BCInnerClassGen$class.getClassBTypeAndRegisterInnerClass(BCodeHelpers.scala:345)
              at scala.tools.nsc.backend.jvm.BCodeHelpers$BCInnerClassGen$class.internalName(BCodeHelpers.scala:334)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.internalName(BCodeSkelBuilder.scala:50)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:103)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.visit(GenBCode.scala:183)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.scala$tools$nsc$backend$jvm$GenBCode$BCodePhase$Worker1$$$anonfun$1(GenBCode.scala:137)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1$$Lambda$1319/1693557037.apply$mcV$sp(Unknown Source)
              at scala.tools.nsc.Global$GlobalPhase.withCurrentUnit(Global.scala:431)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.run(GenBCode.scala:137)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.buildAndSendToDisk(GenBCode.scala:355)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.run(GenBCode.scala:324)
              at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1505)
              at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1490)
              at scala.tools.nsc.Global$Run.compileSources(Global.scala:1485)
              at scala.tools.nsc.Global$Run.compile(Global.scala:1586)
              at xsbt.CachedCompiler0.run(CompilerInterface.scala:116)
              at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
              at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:497)
              at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
              at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
              at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply$mcV$sp(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:75)
              at sbt.compiler.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:50)
              at sbt.compiler.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:65)
              at sbt.compiler.IC$$anonfun$compileInternal$1.apply(IncrementalCompiler.scala:160)
              at sbt.compiler.IC$$anonfun$compileInternal$1.apply(IncrementalCompiler.scala:160)
              at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:66)
              at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:64)
              at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
              at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:62)
              at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:61)
              at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:89)
              at sbt.inc.Incremental$.compile(Incremental.scala:61)
              at sbt.inc.IncrementalCompile$.apply(Compile.scala:54)
              at sbt.compiler.IC$.compileInternal(IncrementalCompiler.scala:160)
              at sbt.compiler.IC$.incrementalCompile(IncrementalCompiler.scala:138)
              at sbt.Compiler$.compile(Compiler.scala:128)
              at sbt.Compiler$.compile(Compiler.scala:114)
              at sbt.Defaults$.sbt$Defaults$$compileIncrementalTaskImpl(Defaults.scala:814)
              at sbt.Defaults$$anonfun$compileIncrementalTask$1.apply(Defaults.scala:805)
              at sbt.Defaults$$anonfun$compileIncrementalTask$1.apply(Defaults.scala:803)
              at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
              at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
              at sbt.std.Transform$$anon$4.work(System.scala:63)
              at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
              at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
              at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
              at sbt.Execute.work(Execute.scala:235)
              at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
              at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
              at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
              at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
              at java.util.concurrent.FutureTask.run(FutureTask.java:266)
              at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
              at java.util.concurrent.FutureTask.run(FutureTask.java:266)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
              at java.lang.Thread.run(Thread.java:745)
      

      Followed by a large number of follow on exceptions of the following form,

      java.lang.AssertionError: assertion failed: ClassBType.info not yet assigned: Lshapeless/LazyTests;
              at scala.tools.nsc.backend.jvm.BTypes$ClassBType.info(BTypes.scala:820)
              at scala.tools.nsc.backend.jvm.BTypes$ClassBType.isNestedClass(BTypes.scala:883)
              at scala.tools.nsc.backend.jvm.BCodeHelpers$BCInnerClassGen$class.toTypeKind(BCodeHelpers.scala:356)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.toTypeKind(BCodeSkelBuilder.scala:50)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.symInfoTK(BCodeSkelBuilder.scala:82)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.scala$tools$nsc$backend$jvm$BCodeSkelBuilder$PlainSkelBuilder$$$anonfun$10(BCodeSkelBuilder.scala:270)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.scala$tools$nsc$backend$jvm$BCodeSkelBuilder$PlainSkelBuilder$$$anonfun$10$adapted(BCodeSkelBuilder.scala:263)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.addClassFields(BCodeSkelBuilder.scala:263)
              at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:122)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.visit(GenBCode.scala:183)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.scala$tools$nsc$backend$jvm$GenBCode$BCodePhase$Worker1$$$anonfun$1(GenBCode.scala:137)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1$$Lambda$1319/1693557037.apply$mcV$sp(Unknown Source)
              at scala.tools.nsc.Global$GlobalPhase.withCurrentUnit(Global.scala:431)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase$Worker1.run(GenBCode.scala:137)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.buildAndSendToDisk(GenBCode.scala:355)
              at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.run(GenBCode.scala:324)
              at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1505)
              at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1490)
              at scala.tools.nsc.Global$Run.compileSources(Global.scala:1485)
              at scala.tools.nsc.Global$Run.compile(Global.scala:1586)
              at xsbt.CachedCompiler0.run(CompilerInterface.scala:116)
              at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
              at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:497)
              at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
              at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
              at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply$mcV$sp(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:51)
              at sbt.compiler.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:75)
              at sbt.compiler.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:50)
              at sbt.compiler.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:65)
              at sbt.compiler.IC$$anonfun$compileInternal$1.apply(IncrementalCompiler.scala:160)
              at sbt.compiler.IC$$anonfun$compileInternal$1.apply(IncrementalCompiler.scala:160)
              at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:66)
              at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:64)
              at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
              at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:62)
              at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:61)
              at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:89)
              at sbt.inc.Incremental$.compile(Incremental.scala:61)
              at sbt.inc.IncrementalCompile$.apply(Compile.scala:54)
              at sbt.compiler.IC$.compileInternal(IncrementalCompiler.scala:160)
              at sbt.compiler.IC$.incrementalCompile(IncrementalCompiler.scala:138)
              at sbt.Compiler$.compile(Compiler.scala:128)
              at sbt.Compiler$.compile(Compiler.scala:114)
              at sbt.Defaults$.sbt$Defaults$$compileIncrementalTaskImpl(Defaults.scala:814)
              at sbt.Defaults$$anonfun$compileIncrementalTask$1.apply(Defaults.scala:805)
              at sbt.Defaults$$anonfun$compileIncrementalTask$1.apply(Defaults.scala:803)
              at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
              at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
              at sbt.std.Transform$$anon$4.work(System.scala:63)
              at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
              at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
              at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
              at sbt.Execute.work(Execute.scala:235)
              at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
              at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
              at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
              at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
              at java.util.concurrent.FutureTask.run(FutureTask.java:266)
              at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
              at java.util.concurrent.FutureTask.run(FutureTask.java:266)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
              at java.lang.Thread.run(Thread.java:745)
      

        Attachments

          Issue Links

            Activity

            Hide
            retronym Jason Zaugg added a comment -

            Crashes since 2.11.3 with `-Ybackend:GenBCode`. The assertion error mentions a class symbol generated by a macro expansion.

            Show
            retronym Jason Zaugg added a comment - Crashes since 2.11.3 with `-Ybackend:GenBCode`. The assertion error mentions a class symbol generated by a macro expansion.
            Hide
            retronym Jason Zaugg added a comment - - edited
            Show
            retronym Jason Zaugg added a comment - - edited Regressed in https://github.com/scala/scala/commit/f73f026 , /cc Lukas Rytz
            Hide
            retronym Jason Zaugg added a comment -

            Looks like the `Lazy` macro of shapeless is generating incoherent trees, see the two different symbol IDs for the highlighted class:

            https://www.dropbox.com/s/wq6kf239ra983hy/Screenshot%202015-07-12%2015.24.19.png?dl=0

            This is because of the way that the macro untypechecks the nested tree (https://github.com/milessabin/shapeless/blob/shapeless-2.2.4/core/src/main/scala/shapeless/lazy.scala#L220) but nevertheless uses a type (`actualType`) (https://github.com/milessabin/shapeless/blob/shapeless-2.2.4/core/src/main/scala/shapeless/lazy.scala#L192) that refers to a symbol from the original tree. This in turn is because it doesn't take measures to "pack" the type, which would prevent leaking a reference from a block-local class to the type of that block. This is pretty hard to do in the retypechecking model of macros. I'll take a deeper look at this next week and see if I recommend a better approach for that macro.

            But I think we can demote this error to a dev-warning in the compiler.

            Show
            retronym Jason Zaugg added a comment - Looks like the `Lazy` macro of shapeless is generating incoherent trees, see the two different symbol IDs for the highlighted class: https://www.dropbox.com/s/wq6kf239ra983hy/Screenshot%202015-07-12%2015.24.19.png?dl=0 This is because of the way that the macro untypechecks the nested tree ( https://github.com/milessabin/shapeless/blob/shapeless-2.2.4/core/src/main/scala/shapeless/lazy.scala#L220 ) but nevertheless uses a type (`actualType`) ( https://github.com/milessabin/shapeless/blob/shapeless-2.2.4/core/src/main/scala/shapeless/lazy.scala#L192 ) that refers to a symbol from the original tree. This in turn is because it doesn't take measures to "pack" the type, which would prevent leaking a reference from a block-local class to the type of that block. This is pretty hard to do in the retypechecking model of macros. I'll take a deeper look at this next week and see if I recommend a better approach for that macro. But I think we can demote this error to a dev-warning in the compiler.
            Hide
            milessabin Miles Sabin added a comment -

            Is there anything I could/should do in Lazy to prevent this happening? You mention taking measures to "pack" the type ... can you say what would be involved in doing that?

            Show
            milessabin Miles Sabin added a comment - Is there anything I could/should do in Lazy to prevent this happening? You mention taking measures to "pack" the type ... can you say what would be involved in doing that?
            Hide
            retronym Jason Zaugg added a comment - - edited

            Here's a standalone test case:

            % tail sandbox/{macro,client}.scala
            ==> sandbox/macro.scala <==
              def impl(c: Context)(): c.Tree = {
                import c.universe._
                val tree = q"""class C; new C"""
                val tree1 = c.typecheck(tree)
                val tpe = tree1.tpe
                val tree2 = c.typecheck(c.untypecheck(tree1))
                q"""$tree2.asInstanceOf[$tpe]"""
              }
              def apply(): Any = macro impl
            }
             
            ==> sandbox/client.scala <==
            class Client {
              Macro()
            }
             
            % scalac-hash v2.11.3 sandbox/macro.scala && scalac-hash v2.11.3 -Ybackend:GenASM sandbox/client.scala
             
            % scalac-hash v2.11.3 sandbox/macro.scala && scalac-hash v2.11.3 -Ybackend:GenBCode sandbox/client.scala
            java.lang.AssertionError: assertion failed: Cannot create ClassBType from non-class symbol value <local Client>
            	at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:86)
            

            And a potential workaround for shapeless: https://github.com/milessabin/shapeless/pull/429

            Show
            retronym Jason Zaugg added a comment - - edited Here's a standalone test case: % tail sandbox/{macro,client}.scala ==> sandbox/macro.scala <== def impl(c: Context)(): c.Tree = { import c.universe._ val tree = q"""class C; new C""" val tree1 = c.typecheck(tree) val tpe = tree1.tpe val tree2 = c.typecheck(c.untypecheck(tree1)) q"""$tree2.asInstanceOf[$tpe]""" } def apply(): Any = macro impl }   ==> sandbox/client.scala <== class Client { Macro() }   % scalac-hash v2.11.3 sandbox/macro.scala && scalac-hash v2.11.3 -Ybackend:GenASM sandbox/client.scala   % scalac-hash v2.11.3 sandbox/macro.scala && scalac-hash v2.11.3 -Ybackend:GenBCode sandbox/client.scala java.lang.AssertionError: assertion failed: Cannot create ClassBType from non-class symbol value <local Client> at scala.tools.nsc.backend.jvm.BTypesFromSymbols.classBTypeFromSymbol(BTypesFromSymbols.scala:86) And a potential workaround for shapeless: https://github.com/milessabin/shapeless/pull/429
            Hide
            retronym Jason Zaugg added a comment -

            Miles Sabin The compiler will pack types when computing an inferred type of a member, or when computing the type of a match.

            scala> import scala.tools.reflect.ToolBox; val m = reflect.runtime.currentMirror; val u = m.universe; import u._; val tb = m.mkToolBox();
             
            scala> tb.typecheck(q"{class C extends Serializable; new C}").tpe
            res13: tb.u.Type = C
             
            scala> tb.typecheck(q"null match { case _ => class C extends Serializable; new C}").tpe
            res14: tb.u.Type = Serializable
             
            scala> tb.typecheck(q"def f = {class C extends Serializable; 0; new C}; f").tpe
            res15: tb.u.Type = Serializable
            

            However, the best practice is for a macro to generate an tree that ends with a type ascription to the desired type, rather than referring to an expansion-local class and relying on these implementation details.

            Show
            retronym Jason Zaugg added a comment - Miles Sabin The compiler will pack types when computing an inferred type of a member, or when computing the type of a match. scala> import scala.tools.reflect.ToolBox; val m = reflect.runtime.currentMirror; val u = m.universe; import u._; val tb = m.mkToolBox();   scala> tb.typecheck(q"{class C extends Serializable; new C}").tpe res13: tb.u.Type = C   scala> tb.typecheck(q"null match { case _ => class C extends Serializable; new C}").tpe res14: tb.u.Type = Serializable   scala> tb.typecheck(q"def f = {class C extends Serializable; 0; new C}; f").tpe res15: tb.u.Type = Serializable However, the best practice is for a macro to generate an tree that ends with a type ascription to the desired type, rather than referring to an expansion-local class and relying on these implementation details.
            Hide
            retronym Jason Zaugg added a comment - - edited

            Compiler workaround: https://github.com/scala/scala/pull/4623.

            We're going to recut 2.12.0-M2 with this included.

            Show
            retronym Jason Zaugg added a comment - - edited Compiler workaround: https://github.com/scala/scala/pull/4623 . We're going to recut 2.12.0-M2 with this included.
            Hide
            milessabin Miles Sabin added a comment -

            Awesome thanks

            Show
            milessabin Miles Sabin added a comment - Awesome thanks
            Hide
            rytz Lukas Rytz added a comment -
            Show
            rytz Lukas Rytz added a comment - follow-up in https://github.com/scala/scala/pull/4630

              People

              • Assignee:
                retronym Jason Zaugg
                Reporter:
                milessabin Miles Sabin
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: