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

spurious errors / crashes when pattern matching meets super #8138

Closed
scabug opened this issue Jan 10, 2014 · 9 comments
Closed

spurious errors / crashes when pattern matching meets super #8138

scabug opened this issue Jan 10, 2014 · 9 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Jan 10, 2014

import scala.language.experimental.macros
import scala.reflect.macros.WhiteboxContext

object Test {
  def impl(c: WhiteboxContext)(tree: c.Tree) = {
    import c.universe._
    object FindMatch extends Transformer {
      tree match {
        case arg: List[List[Tree]] =>
          // doesn't compile:
          // Test.scala:10: error: missing parameter type for expanded function ((x$1) => x$1.foreach(((y) => super.transform(y))))
          arg.foreach{_.foreach{y=>super.transform(y)}}

          // crashes in GenICode:
          // error: Unknown type: <notype>, <notype> [class scala.reflect.internal.Types$NoType$, class scala.reflect.internal.Types$NoType$] TypeRef? false
          // error: scala.reflect.internal.FatalError: Unknown type: <notype>, <notype> [class scala.reflect.internal.Types$NoType$, class scala.reflect.internal.Types$NoType$] TypeRef? false
          //   at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:56)
          //   at scala.tools.nsc.Global.abort(Global.scala:263)
          //   at scala.tools.nsc.backend.icode.TypeKinds$class.toTypeKind(TypeKinds.scala:401)
          //   at scala.tools.nsc.backend.icode.ICodes.toTypeKind(ICodes.scala:19)
          //   at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadApply1$1(GenICode.scala:607)
          //   at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:634)
          //   at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:119)
          //   at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:67)
          //   at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:67)
          arg.foreach{(x: List[Tree]) => x.foreach{y=>super.transform(y)}}
      }
    }
  }
}
@scabug
Copy link
Author

scabug commented Jan 10, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8138?orig=1
Reporter: @xeno-by
Affected Versions: 2.11.0-M7

@scabug
Copy link
Author

scabug commented Jan 10, 2014

@DarkDimius said:
Please be so kind to tell if there's a workaround.

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
With -Ycheck:all:

[Now checking: typer]
warning: [check: typer]
Out of scope symbol reference {
      tree  ModuleDef            object FindMatch extends c.universe.Transformer {...
  position  OffsetPosition       sandbox/test.scala:11
  with sym  ModuleSymbol         object FindMatch                                         in  method impl -> object Test -> package <empty>
   encl(1)  MethodSymbol         def impl(c: scala.reflect.macros.WhiteboxContext): Unit  in  object Test -> package <empty>
   encl(2)  ModuleSymbol         object Test                                              in  package <empty>
    ref to  ModuleClassSymbol    FindMatch (<module>)                                     in  method impl -> object Test -> package <empty>
}

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
Minimized:

class U {
  trait Transformer {
    def transform(a: Tree): Tree = ???
  }  
  trait Tree
}

object Test {
  def m(u: U) = {
    // val u = u0 // works
    class C extends u.Transformer {
      override def transform(t: u.Tree): u.Tree = {
        null match {
          case _ =>
            // crashes in GenICode:
            // error: Unknown type: <notype>, <notype> [class scala.reflect.internal.Types$NoType$, class scala.reflect.internal.Types$NoType$] TypeRef? false
            (y: Any) => super.transform(???)
        }
        ???
      }
    }
  }
}

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@xeno-by said:
@jason. The missing parameter type error is also spurious, right?

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
This fixes the crasher. https://github.com/retronym/scala/tree/ticket/8138

Not sure about the inference failure yet.

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
The inference failure does not appear to be a bug; the type of arg contains a pair of overloaded foreach members; one contributed by Tree, and the second contributed by List[List[Tree]]

This amounts to:

trait A { def foo(f: Int => String)}
sealed abstract class B1
final class B extends B1 { def foo(f: String => Int)}

object Test {
  def foo(a: A) = a match {
    case b: B1 =>
      b.foo(x => x)
  }
}

It is a pity that our static checks don't detect the "fruitless type test" here as they would if B were final.

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
scala/scala#3356

@scabug
Copy link
Author

scabug commented Jan 12, 2014

@retronym said:
The logic that would need tweaking in CheckabilityChecker:

    def areIrreconcilableAsParents(sym1: Symbol, sym2: Symbol): Boolean = areUnrelatedClasses(sym1, sym2) && (
         sym1.initialize.isEffectivelyFinal // initialization important
      || sym2.initialize.isEffectivelyFinal
      || !sym1.isTrait && !sym2.isTrait
      || sym1.isSealed && sym2.isSealed && allChildrenAreIrreconcilable(sym1, sym2) && !currentRun.compiles(sym1) && !currentRun.compiles(sym2)

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