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

name based patmat doesn't typecheck get #7850

Closed
scabug opened this issue Sep 17, 2013 · 10 comments
Closed

name based patmat doesn't typecheck get #7850

scabug opened this issue Sep 17, 2013 · 10 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Sep 17, 2013

class Casey(a: Int) { def isEmpty = false; def get = this }
object Casey { def unapply(a: Casey) = a }

object Test {
  def main(args: Array[String]) {
    val Casey(x) = new Casey(1)
    assert(x == 1, x)
  }
}

/*
     val x: Int = {
        case <synthetic> val x1: Casey = (new Casey(1): Casey @unchecked);
        case5(){
          <synthetic> val o7: Casey = Casey.unapply(x1);
          if (o7.isEmpty.unary_!)
            {
              val x: Casey = o7.get;
              matchEnd4(x)
            }
          else
            case6()
        };
        case6(){
          matchEnd4(throw new MatchError(x1))
        };
        matchEnd4(x: Int){
          x
        }
*/

ClassCastException ensues.

@scabug
Copy link
Author

scabug commented Sep 17, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7850?orig=1
Reporter: @retronym
Affected Versions: 2.11.0-M5

@scabug
Copy link
Author

scabug commented Oct 15, 2013

@gkossakowski said:
Unassigning and rescheduling to M7 as previous deadline was missed.

@scabug
Copy link
Author

scabug commented Nov 22, 2013

@paulp said:
Cannot reproduce or figure out what the bug is. You have get returning a Casey. When I compile this, matchEnd4 takes a "Casey" parameter as expected. The assertion fails of course because new Casey(1) != 1, but no CCE. Same thing with M5 or trunk. Can you explain?

test/files/neg/t7850.scala:7: warning: Casey and Int are unrelated: they will most likely never compare equal
    assert(x == 1, x)
             ^
one warning found
java.lang.AssertionError: assertion failed: Casey@3173175
/*
      val x: Casey = {
        case <synthetic> val x1: Casey = (new Casey(1): Casey @unchecked);
        case5(){
          <synthetic> val o7: Casey = Casey.unapply(x1);
          if (o7.isEmpty.unary_!)
            {
              val x: Casey = o7.get;
              matchEnd4(x)
            }
          else
            case6()
        };
        case6(){
          matchEnd4(throw new MatchError(x1))
        };
        matchEnd4(x: Casey){
          x
        }
      };
*/

@scabug
Copy link
Author

scabug commented Dec 6, 2013

@paulp said:
Ping retronym. I still have a patch in play which roams this neighborhood but I can't tell what the bug in this ticket is or whether it is real.

@scabug
Copy link
Author

scabug commented Dec 6, 2013

@retronym said:

(export V=v2.11.0-M7 && scalac-hash $V sandbox/test.scala && scala-hash $V Test)
sandbox/test.scala:7: warning: Casey and Int are unrelated: they will most likely never compare equal
    assert(x == 1, x)
             ^
one warning found
java.lang.AssertionError: assertion failed: Casey@c5a67c9
	at scala.Predef$.assert(Predef.scala:169)
	at Test$.main(test.scala:7)
	at Test.main(test.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:68)
	at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
	at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:99)
	at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:68)
	at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:99)
	at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
	at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
	at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
	at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
	at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:72)
	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:94)
	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
  ~/code/scala3 cat sandbox/test.scala
class Casey(a: Int) { def isEmpty = false; def get = this }
object Casey { def unapply(a: Casey) = a }

object Test {
  def main(args: Array[String]) {
    val Casey(x) = new Casey(1)
    assert(x == 1, x)
  }
}

@scabug
Copy link
Author

scabug commented Dec 6, 2013

@retronym said:
In earlier versions:

(export V=v2.11.0-M4 && scalac-hash $V sandbox/test.scala && scala-hash $V Test)
sandbox/test.scala:6: error: result type Casey of unapply defined in method unapply in object Casey does not conform to Option[_] or Boolean
    val Casey(x) = new Casey(1)
             ^
one error found

@scabug
Copy link
Author

scabug commented Dec 15, 2013

@paulp said:
@retronym I still don't understand what the bug is. You're doing an unchecked pattern match in the val assignment, that's how it works. The behavior is exactly the same in earlier versions if the unapply returns the type which was understood in earlier versions.

% cat test/files/neg/t7850.scala
class Casey(a: Int) { def isEmpty = false; def get = this }
object Casey { def unapply(a: Casey) = Some(a) }

object Test {
  def main(args: Array[String]) {
    val Casey(x) = new Casey(1)
    assert(x == 1, x)
  }
}

% scalac210 -d /tmp test/files/neg/t7850.scala
test/files/neg/t7850.scala:7: warning: Casey and Int are unrelated: they will most likely never compare equal
    assert(x == 1, x)
             ^
scalone warning found
% scala210 -cp /tmp Test
java.lang.AssertionError: assertion failed: Casey@1495c8c2
  at scala.Predef$.assert(Predef.scala:179)
  at Test$.main(t7850.scala:7)
  at Test.main(t7850.scala)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)

@scabug
Copy link
Author

scabug commented Dec 15, 2013

@retronym said (edited on Dec 15, 2013 8:11:57 PM UTC):
Looks like a few bits were twiddled between the original bug and this report. Sorry for the noise. Must have been a strong set of solar flares that day.

Here's a CCE. We should check that isEmpty returns boolean.

class Casey(a: Int) { def isEmpty = this; def get = this }
object Casey { def unapply(a: Casey) = a }
 
object Test {
  def main(args: Array[String]) {
    val Casey(x) = new Casey(1)
  }
}
 (export V=v2.11.0-M5 && scalac-hash $V sandbox/test.scala && scala-hash $V Test)
sandbox/test.scala:7: warning: Casey and Int are unrelated: they will most likely never compare equal
    assert(x == 1, x)
             ^
one warning found
java.lang.ClassCastException: Casey cannot be cast to java.lang.Boolean

(export V=origin/master && scalac-hash $V sandbox/test.scala && scala-hash $V Test)
sandbox/test.scala:7: warning: Casey and Int are unrelated: they will most likely never compare equal
    assert(x == 1, x)
             ^
one warning found
java.lang.ClassCastException: Casey cannot be cast to java.lang.Boolean

@scabug
Copy link
Author

scabug commented Dec 15, 2013

@paulp said:
OOOOOOOOOOOOOOOHHHHHHH, it doesn't check the return type of isEmpty. This I can work with.

@scabug
Copy link
Author

scabug commented Dec 16, 2013

@paulp said:
scala/scala#3275

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