Aladdin - Scala Bugtracking
[#717] project: compiler priority: low category: missing feature
submitter assigned to status date submitted
Burak Burak fixed 2006-08-30 14:54:09.0
subject pattern matching ignores paths
code
class Foo(j:Int) {
  case class Bar(i:Int)
}
object testob {
  val foo1 = new Foo(1)
  val foo2 = new Foo(2)
  def main(args:Array[String]) = {
    (foo1.Bar(2):Any) match {
      case foo2.Bar(2) => Console.println(false)
      case foo1.Bar(2) => Console.println(true)
    }
  }
}

what happened
ignores prefix when matching
what expected prints true
[back to overview]
Changes of this bug report
Burak  edited on  2006-08-30 17:33:13.0
I tried to get this implemented. However, it requires swapping transmatch with the immediately succeeding explicitOuter.
Try to do that and bootstrap. It fails with an obscure internal error. If anybody could explain me why it fails, I can insert the outer-comparing code and enable this feature.
Burak  edited on  2006-08-30 20:08:54.0
The problem, when compiling scala.tools.nsc.ast.SyntaxAnalyzer, is that normally, Erasure calls OverridingPairs, which computes the following scope:
computing bridges for class ParserPhase
OverridingPairs: decls is {
    def run(): scala.this.Unit;
    def name(): lang.this.String;
    def apply(Global.this.CompilationUnit): scala.this.Unit;
  final  def asInstanceOf$erased[  T0](): T0;
  final  def isInstanceOf$erased[  T0](): scala.this.Boolean;
  final  def asInstanceOf[  T0](): T0;
  final  def isInstanceOf[  T0](): scala.this.Boolean;
   def toString(): lang.this.String;
   def hashCode(): scala.this.Int;
   def equals(scala.this.Any): scala.this.Boolean;
  final  def !=(scala.this.Any): scala.this.Boolean;
  final  def ==(scala.this.Any): scala.this.Boolean;
  final  def $asInstanceOf[  T0](): T0;
  final  def $isInstanceOf[  T0](): scala.this.Boolean;
  final  def synchronized[  T0](T0): T0;
  final  def ne(lang.this.Object): scala.this.Boolean;
  final  def eq(lang.this.Object): scala.this.Boolean;
  final  def !=(lang.this.Object): scala.this.Boolean;
  final  def ==(lang.this.Object): scala.this.Boolean;
  protected   def finalize(): scala.this.Unit;
  final   def wait(): scala.this.Unit;
  final   def wait(scala.this.Long,scala.this.Int): scala.this.Unit;
  final   def wait(scala.this.Long): scala.this.Unit;
  final   def notifyAll(): scala.this.Unit;
  final   def notify(): scala.this.Unit;
    def toString(): lang.this.String;
  protected   def clone(): lang.this.Object;
    def equals(scala.this.Any): scala.this.Boolean;
    def hashCode(): scala.this.Int;
  final   def getClass(): lang.this.Class;
   def $tag: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@6779e6;
  override  def toString(): lang.this.String;
   def flatClasses(): scala.this.Boolean;
   def erasedTypes(): scala.this.Boolean;
   def description: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@a00185;
   def next: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@c3c315;
   def flagMask: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@1a4ded3;
   def newFlags(): scala.this.Long;
     def id: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@134ce4a;
      def prev: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@f01771;
  final  def applyPhase: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@933bcb;
  override  def flatClasses(): scala.this.Boolean;
  override  def erasedTypes(): scala.this.Boolean;
   def run(): scala.this.Unit;
  override  def newFlags(): scala.this.Long;
   def name(): lang.this.String;
   def apply(SyntaxAnalyzer.this.global.CompilationUnit): scala.this.Unit
}
however, when swapping explicitouter and transmatch, we get the following scope:
base.isTrait: false
computing bridges for class ParserPhase
OverridingPairs: decls is {
    def run(): scala.this.Unit;
    def name(): lang.this.String;
    def apply(Global.this.CompilationUnit): scala.this.Unit;
  final  def asInstanceOf$erased[  T0](): T0;
  final  def isInstanceOf$erased[  T0](): scala.this.Boolean;
  final  def asInstanceOf[  T0](): T0;
  final  def isInstanceOf[  T0](): scala.this.Boolean;
   def toString(): lang.this.String;
   def hashCode(): scala.this.Int;
   def equals(scala.this.Any): scala.this.Boolean;
  final  def !=(scala.this.Any): scala.this.Boolean;
  final  def ==(scala.this.Any): scala.this.Boolean;
  final  def $asInstanceOf[  T0](): T0;
  final  def $isInstanceOf[  T0](): scala.this.Boolean;
  final  def synchronized[  T0](T0): T0;
  final  def ne(lang.this.Object): scala.this.Boolean;
  final  def eq(lang.this.Object): scala.this.Boolean;
  final  def !=(lang.this.Object): scala.this.Boolean;
  final  def ==(lang.this.Object): scala.this.Boolean;
  protected   def finalize(): scala.this.Unit;
  final   def wait(): scala.this.Unit;
  final   def wait(scala.this.Long,scala.this.Int): scala.this.Unit;
  final   def wait(scala.this.Long): scala.this.Unit;
  final   def notifyAll(): scala.this.Unit;
  final   def notify(): scala.this.Unit;
    def toString(): lang.this.String;
  protected   def clone(): lang.this.Object;
    def equals(scala.this.Any): scala.this.Boolean;
    def hashCode(): scala.this.Int;
  final   def getClass(): lang.this.Class;
   def $tag: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@6779e6;
  override  def toString(): lang.this.String;
   def flatClasses(): scala.this.Boolean;
   def erasedTypes(): scala.this.Boolean;
   def description: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@a00185;
   def next: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@c3c315;
   def flagMask: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@1a4ded3;
   def newFlags(): scala.this.Long;
     def id: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@134ce4a;
      def prev: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@f01771;
      def $outer(): Global.this.type;
  final  def applyPhase: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@933bcb;
  override  def flatClasses(): scala.this.Boolean;
  override  def erasedTypes(): scala.this.Boolean;
   def run(): scala.this.Unit;
      def $outer(): SubComponent.this.type;
  override  def newFlags(): scala.this.Long;
   def name(): lang.this.String;
      def $outer(): SyntaxAnalyzer.this.type;
   def apply(SyntaxAnalyzer.this.global.CompilationUnit): scala.this.Unit
}
Burak  edited on  2006-08-31 12:08:20.0
The problem, when compiling scala.tools.nsc.ast.SyntaxAnalyzer, is that normally, Erasure calls OverridingPairs, which computes the following scope:
computing bridges for class ParserPhase
OverridingPairs: decls is {
    def run(): scala.this.Unit;
    def name(): lang.this.String;
    def apply(Global.this.CompilationUnit): scala.this.Unit;
  final  def asInstanceOf$erased[  T0](): T0;
  final  def isInstanceOf$erased[  T0](): scala.this.Boolean;
  final  def asInstanceOf[  T0](): T0;
  final  def isInstanceOf[  T0](): scala.this.Boolean;
   def toString(): lang.this.String;
   def hashCode(): scala.this.Int;
   def equals(scala.this.Any): scala.this.Boolean;
  final  def !=(scala.this.Any): scala.this.Boolean;
  final  def ==(scala.this.Any): scala.this.Boolean;
  final  def $asInstanceOf[  T0](): T0;
  final  def $isInstanceOf[  T0](): scala.this.Boolean;
  final  def synchronized[  T0](T0): T0;
  final  def ne(lang.this.Object): scala.this.Boolean;
  final  def eq(lang.this.Object): scala.this.Boolean;
  final  def !=(lang.this.Object): scala.this.Boolean;
  final  def ==(lang.this.Object): scala.this.Boolean;
  protected   def finalize(): scala.this.Unit;
  final   def wait(): scala.this.Unit;
  final   def wait(scala.this.Long,scala.this.Int): scala.this.Unit;
  final   def wait(scala.this.Long): scala.this.Unit;
  final   def notifyAll(): scala.this.Unit;
  final   def notify(): scala.this.Unit;
    def toString(): lang.this.String;
  protected   def clone(): lang.this.Object;
    def equals(scala.this.Any): scala.this.Boolean;
    def hashCode(): scala.this.Int;
  final   def getClass(): lang.this.Class;
   def $tag: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@6779e6;
  override  def toString(): lang.this.String;
   def flatClasses(): scala.this.Boolean;
   def erasedTypes(): scala.this.Boolean;
   def description: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@a00185;
   def next: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@c3c315;
   def flagMask: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@1a4ded3;
   def newFlags(): scala.this.Long;
     def id: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@134ce4a;
      def prev: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@f01771;
  final  def applyPhase: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@933bcb;
  override  def flatClasses(): scala.this.Boolean;
  override  def erasedTypes(): scala.this.Boolean;
   def run(): scala.this.Unit;
  override  def newFlags(): scala.this.Long;
   def name(): lang.this.String;
   def apply(SyntaxAnalyzer.this.global.CompilationUnit): scala.this.Unit
}
however, when swapping explicitouter and transmatch, we get the following scope:
base.isTrait: false
computing bridges for class ParserPhase
OverridingPairs: decls is {
    def run(): scala.this.Unit;
    def name(): lang.this.String;
    def apply(Global.this.CompilationUnit): scala.this.Unit;
  final  def asInstanceOf$erased[  T0](): T0;
  final  def isInstanceOf$erased[  T0](): scala.this.Boolean;
  final  def asInstanceOf[  T0](): T0;
  final  def isInstanceOf[  T0](): scala.this.Boolean;
   def toString(): lang.this.String;
   def hashCode(): scala.this.Int;
   def equals(scala.this.Any): scala.this.Boolean;
  final  def !=(scala.this.Any): scala.this.Boolean;
  final  def ==(scala.this.Any): scala.this.Boolean;
  final  def $asInstanceOf[  T0](): T0;
  final  def $isInstanceOf[  T0](): scala.this.Boolean;
  final  def synchronized[  T0](T0): T0;
  final  def ne(lang.this.Object): scala.this.Boolean;
  final  def eq(lang.this.Object): scala.this.Boolean;
  final  def !=(lang.this.Object): scala.this.Boolean;
  final  def ==(lang.this.Object): scala.this.Boolean;
  protected   def finalize(): scala.this.Unit;
  final   def wait(): scala.this.Unit;
  final   def wait(scala.this.Long,scala.this.Int): scala.this.Unit;
  final   def wait(scala.this.Long): scala.this.Unit;
  final   def notifyAll(): scala.this.Unit;
  final   def notify(): scala.this.Unit;
    def toString(): lang.this.String;
  protected   def clone(): lang.this.Object;
    def equals(scala.this.Any): scala.this.Boolean;
    def hashCode(): scala.this.Int;
  final   def getClass(): lang.this.Class;
   def $tag: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@6779e6;
  override  def toString(): lang.this.String;
   def flatClasses(): scala.this.Boolean;
   def erasedTypes(): scala.this.Boolean;
   def description: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@a00185;
   def next: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@c3c315;
   def flagMask: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@1a4ded3;
   def newFlags(): scala.this.Long;
     def id: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@134ce4a;
      def prev: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@f01771;
      def $outer(): Global.this.type;
  final  def applyPhase: scala.tools.nsc.symtab.classfile.UnPickler$UnPickle$LazyTypeRef@933bcb;
  override  def flatClasses(): scala.this.Boolean;
  override  def erasedTypes(): scala.this.Boolean;
   def run(): scala.this.Unit;
      def $outer(): SubComponent.this.type;
  override  def newFlags(): scala.this.Long;
   def name(): lang.this.String;
      def $outer(): SyntaxAnalyzer.this.type;
   def apply(SyntaxAnalyzer.this.global.CompilationUnit): scala.this.Unit
}
Burak  edited on  2006-08-31 22:41:52.0
phases swapped, Erasure use phase.prev.prev, and part of ExplicitOuter is duplicated (to be refactored into some framework class, e.g. TreeGen).
Burak  edited on  2006-09-01 15:42:25.0
I changed the example a bit, so it's easier to put in the test suite (expected outcome now "prints true")