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

SI-6318 fixes ClassTag.unapply for primitives #1265

Merged
merged 1 commit into from Sep 7, 2012

Conversation

xeno-by
Copy link
Member

@xeno-by xeno-by commented Sep 6, 2012

ClassTag.unapply now takes a class tag itself, so that it can preserve
boxiness of value classes when performing subtyping tests.

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

review by @jsuereth

@jsuereth
Copy link
Member

jsuereth commented Sep 6, 2012

LGTM

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/367/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1075/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Failed - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/367/

@jsuereth
Copy link
Member

jsuereth commented Sep 6, 2012

Aborted build?

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

That wasn't me. PLS REBUILD ALL

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/370/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Failed - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/370/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Failed - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1075/

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

PLS REBUILD ALL

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

@jsuereth could you please take another look? I stumbled upon an issue with patmat and had to completely redo the implementation

@jsuereth
Copy link
Member

jsuereth commented Sep 6, 2012

Does the issue pop up with any value class or just primitives?

Could you add an anyval test? Something simple like class X(val y: Int) extends AnyVal

I'm paranoid about them now.

Other than that LGTM, although it seems odd. Can you describe what virtpatmat was freaking out on?

Im

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

Only with primitives, yet I have a test that checks derived value classes: test/files/run/t6318_derived.check.

The patmat was saying: warning: The outer reference in this type test cannot be checked at run time.

Here's the dump of -Xprint:specialize (the phase before explicitouter) for when I added the type parameter to the signature of unapply: unapply[T](x: T) instead of unapply(x: Any). The lines marked with the >>> sign (added by me right now, not present in the original printout) are the ones that appeared after that change. I believe that T was inferred to be Extractors.this.T and this scared the patmat into inserting additional checks.

trait Extractors {
  type T
  implicit val tTag: ClassTag[T]
  object ExtractT {
    def unapply(x: T) = Some(x)
  }
  def apply(a: Any) = a match {
    case ExtractT(x)  => 
  }
}

myke compile C:\Projects\Kepler\sandbox\Test.scala -Xprint:specialize
git: branch = ticket/6318, commit = c2a95d1352 SI-6318 fixes ClassTag.unapply for primitives (Eugene Burmako, 06.09.2012 12:41:42 +02:00)
psi: filename = cmd.exe, arguments = /C c:\PROGRA~1\Java\JDK\bin\java.exe -cp "C:\Projects\Kepler\test\files\codelib\code.jar;C:\Projects\Kepler\lib\jline.jar;C:\Projects\Kepler\lib\fjbg.jar;C:\Projects\Kepler\build\locker\classes\compiler;C:\Projects\Kepler\build\asm\classes;C:\Projects\Kepler\build\libs\forkjoin.jar;C:\Projects\Kepler\build\locker\classes\reflect;C:\Projects\Kepler\build\locker\classes\library" -Dscala.usejavacp=true -Dscala.repl.vids=1 -Dscala.repl.autoruncode=C:\Users\xeno.by/.scala_autorun -Dscala.repl.maxprintstring=0 scala.tools.nsc.Main -language:experimental.macros -Xprint:specialize Test.scala, home = C:\Projects\Kepler\sandbox
[[syntax trees at end of                specialize]] // Test.scala
package <empty> {
  abstract trait Extractors extends Object {
    def /*Extractors*/$init$(): Unit = {
      ()
    };
    type T;
    implicit <stable> <accessor> def tTag(): scala.reflect.ClassTag[Extractors.this.T];
    object ExtractT extends Object {
      def <init>(): Extractors.this.ExtractT.type = {
        ExtractT.super.<init>();
        ()
      };
      def unapply(x: Extractors.this.T): Some[Extractors.this.T] = new Some[Extractors.this.T](x)
    };
    @volatile <synthetic> private[this] var ExtractT$module: Extractors.this.ExtractT.type = _;
    <stable> def ExtractT(): Extractors.this.ExtractT.type = new Extractors.this.ExtractT.type();
    def apply(a: Any): Unit = {
      case <synthetic> val x1: Any = a;
      case8(){
        >>> if (x1.isInstanceOf[Extractors.this.T]().&&((x1.asInstanceOf[Extractors.this.T](): Extractors.this.T).<outer>().eq(Extractors.this)))
          {
            >>> val x3: Extractors.this.T = (x1.asInstanceOf[Extractors.this.T](): Extractors.this.T);
            {
              val o11: Option[Extractors.this.T] = Extractors.this.tTag().unapply[Extractors.this.T](x3, Extractors.this.tTag());
              if (o11.isEmpty().unary_!())
                {
                  val p2: Extractors.this.T = o11.get();
                  {
                    val o10: Option[Extractors.this.T] = Extractors.this.ExtractT().unapply(p2);
                    if (o10.isEmpty().unary_!())
                      {
                        val x: Extractors.this.T = o10.get();
                        matchEnd7(())
                      }
                    else
                      case9()
                  }
                }
              else
                case9()
            }
          }
        else
          case9()
      };
      case9(){
        matchEnd7(throw new MatchError(x1))
      };
      matchEnd7(x: Unit){
        x
      }
    }
  }
}

warning: there were 1 unchecked warnings; re-run with -unchecked for details
one warning found

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/376/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1083/

@scala-jenkins
Copy link

I c. So we couldn't just use Any because patmat freaks out with casting
in the wrong manner.

Patch LGTM

@jsuereth
Copy link
Member

jsuereth commented Sep 6, 2012

Lgtm to me too. Sorry for the email shared accounts.

@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

My pull request has been approved by the kitteh!

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Failed - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1083/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Failed - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/376/

ClassTag.unapply now has overloads for primitive value classes
so that it can preserve boxiness when performing subtyping tests.

First I wanted to annotate ClassTag.unapply with a ClassTag itself,
i.e. to transform its signature from "def unapply(x: Any): Option[T]"
to "def unapply[U: ClassTag](x: U): Option[T]".

But then virtpatmat_typetag.scala exhibited a nasty problem.
When pattern matching with this unapply, patmat first infers U as something
and then tries to pattern match against this inferred type. And if U gets
inferred as an abstract type itself, bad things happen:
warning: The outer reference in this type test cannot be checked at run time.

That's why I decided to drop the ClassTag idea and go with 9 extra overloads.
Not very beautiful, but definitely robust.
@xeno-by
Copy link
Member Author

xeno-by commented Sep 6, 2012

Omg that's embarassing. PLS REBUILD ALL

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/377/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1084/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/1084/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/377/

jsuereth added a commit that referenced this pull request Sep 7, 2012
SI-6318 fixes ClassTag.unapply for primitives
@jsuereth jsuereth merged commit b7e0872 into scala:2.10.x Sep 7, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants