summaryrefslogtreecommitdiff
path: root/test/files
diff options
context:
space:
mode:
Diffstat (limited to 'test/files')
-rw-r--r--test/files/jvm/t9044.scala6
-rw-r--r--test/files/pos/patmat-suppress.flags1
-rw-r--r--test/files/pos/patmat-suppress.scala159
-rw-r--r--test/files/pos/t7459a.scala18
-rw-r--r--test/files/pos/t7459b.scala12
-rw-r--r--test/files/pos/t7459c.scala18
-rw-r--r--test/files/pos/t7459d.scala8
-rw-r--r--test/files/pos/t7704.scala10
-rw-r--r--test/files/pos/t8999.flags1
-rw-r--r--test/files/pos/t8999.scala271
-rw-r--r--test/files/run/t7459a.scala14
-rw-r--r--test/files/run/t7459b-optimize.flags1
-rw-r--r--test/files/run/t7459b-optimize.scala21
-rw-r--r--test/files/run/t7459b.scala21
-rw-r--r--test/files/run/t7459c.scala16
-rw-r--r--test/files/run/t7459d.scala15
-rw-r--r--test/files/run/t7459f.scala12
-rw-r--r--test/files/run/t7965.scala54
-rw-r--r--test/files/run/t9030.scala19
19 files changed, 677 insertions, 0 deletions
diff --git a/test/files/jvm/t9044.scala b/test/files/jvm/t9044.scala
new file mode 100644
index 0000000000..b1073325e8
--- /dev/null
+++ b/test/files/jvm/t9044.scala
@@ -0,0 +1,6 @@
+trait A
+trait B
+object Test extends A with B with App {
+ val is = Test.getClass.getInterfaces.mkString(", ")
+ assert(is == "interface A, interface B, interface scala.App", is)
+}
diff --git a/test/files/pos/patmat-suppress.flags b/test/files/pos/patmat-suppress.flags
new file mode 100644
index 0000000000..a988a5b807
--- /dev/null
+++ b/test/files/pos/patmat-suppress.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -Xno-patmat-analysis \ No newline at end of file
diff --git a/test/files/pos/patmat-suppress.scala b/test/files/pos/patmat-suppress.scala
new file mode 100644
index 0000000000..7c8aded690
--- /dev/null
+++ b/test/files/pos/patmat-suppress.scala
@@ -0,0 +1,159 @@
+// test that none of these warn due to -Xno-patmat-analysis
+// tests taken from test/files/neg/patmatexhaust.scala, test/files/neg/pat_unreachable.scala
+class TestSealedExhaustive { // compile only
+ sealed abstract class Foo
+
+ case class Bar(x:Int) extends Foo
+ case object Baz extends Foo
+
+ def ma1(x:Foo) = x match {
+ case Bar(_) => // not exhaustive
+ }
+
+ def ma2(x:Foo) = x match {
+ case Baz => // not exhaustive
+ }
+
+ sealed abstract class Mult
+ case class Kult(s:Mult) extends Mult
+ case class Qult() extends Mult
+
+ def ma33(x:Kult) = x match { // exhaustive
+ case Kult(_) => // exhaustive
+ }
+
+ def ma3(x:Mult) = (x,x) match { // not exhaustive
+ case (Kult(_), Qult()) => // Kult missing
+ //case (Kult(_), Kult(_)) =>
+ case (Qult(), Kult(_)) => // Qult missing
+ //case (Qult(), Qult()) =>
+ }
+
+ def ma3u(x:Mult) = ((x,x) : @unchecked) match { // not exhaustive, but not checked!
+ case (Kult(_), Qult()) =>
+ case (Qult(), Kult(_)) =>
+ }
+
+ sealed abstract class Deep
+
+ case object Ga extends Deep
+ sealed class Gp extends Deep
+ case object Gu extends Gp
+
+ def zma3(x:Deep) = x match { // exhaustive!
+ case _ =>
+ }
+ def zma4(x:Deep) = x match { // exhaustive!
+ case Ga =>
+ case _ =>
+ }
+
+ def ma4(x:Deep) = x match { // missing cases: Gu, Gp which is not abstract so must be included
+ case Ga =>
+ }
+
+ def ma5(x:Deep) = x match {
+ case Gu =>
+ case _ if 1 == 0 =>
+ case Ga =>
+ }
+
+ def ma6() = List(1,2) match { // give up
+ case List(1,2) =>
+ case x :: xs =>
+ }
+
+ def ma7() = List(1,2) match { //exhaustive
+ case 1::2::Nil =>
+ case _ =>
+ }
+
+ sealed class B
+ case class B1() extends B
+ case object B2 extends B
+ def ma8(x: B) = x match {
+ case _: B => true
+ }
+ def ma9(x: B) = x match {
+ case B1() => true // missing B, which is not abstract so must be included
+ case B2 => true
+ }
+
+ object ob1 {
+ sealed abstract class C
+ sealed abstract class C1 extends C
+ object C2 extends C
+ case class C3() extends C
+ case object C4 extends C
+
+ def ma10(x: C) = x match { // exhaustive: abstract sealed C1 is dead end.
+ case C3() => true
+ case C2 | C4 => true
+ }
+ }
+
+ object ob2 {
+ sealed abstract class C
+ abstract class C1 extends C
+ object C2 extends C
+ case class C3() extends C
+ case object C4 extends C
+
+ def ma10(x: C) = x match { // not exhaustive: C1 is not sealed.
+ case C3() => true
+ case C2 | C4 => true
+ }
+ }
+ object ob3 {
+ sealed abstract class C
+ sealed abstract class C1 extends C
+ object D1 extends C1
+ case class D2() extends C1
+ object C2 extends C
+ case class C3() extends C
+ case object C4 extends C
+
+ def ma10(x: C) = x match { // not exhaustive: C1 has subclasses.
+ case C3() => true
+ case C2 | C4 => true
+ }
+ }
+ object ob4 {
+ sealed abstract class C
+ sealed class C1 extends C
+ object C2 extends C
+ case class C3() extends C
+ case object C4 extends C
+
+ def ma10(x: C) = x match { // not exhaustive: C1 is not abstract.
+ case C3() => true
+ case C2 | C4 => true
+ }
+ }
+}
+
+object TestUnreachable extends App {
+ def unreachable1(xs:Seq[Char]) = xs match {
+ case Seq(x, y, _*) => x::y::Nil
+ case Seq(x, y, z, w) => List(z,w) // redundant!
+ }
+ def unreachable2(xs:Seq[Char]) = xs match {
+ case Seq(x, y, _*) => x::y::Nil
+ case Seq(x, y) => List(x, y)
+ }
+
+ def not_unreachable(xs:Seq[Char]) = xs match {
+ case Seq(x, y, _*) => x::y::Nil
+ case Seq(x) => List(x)
+ }
+ def not_unreachable2(xs:Seq[Char]) = xs match {
+ case Seq(x, y) => x::y::Nil
+ case Seq(x, y, z, _*) => List(x,y)
+ }
+
+ def contrivedExample[A, B, C](a: A, b: B, c: C): Unit = a match {
+ case b => println("matched b")
+ case c => println("matched c")
+ case _ => println("matched neither")
+ }
+}
diff --git a/test/files/pos/t7459a.scala b/test/files/pos/t7459a.scala
new file mode 100644
index 0000000000..5107715e06
--- /dev/null
+++ b/test/files/pos/t7459a.scala
@@ -0,0 +1,18 @@
+trait SpecialException extends Throwable
+
+object Test {
+ def run() {
+ try {
+ ???
+ } catch {
+ case e: SpecialException => e.isInstanceOf[SpecialException]
+ case e =>
+ }
+
+ // OKAY
+ // (null: Throwable) match {
+ // case e: SpecialException => e.isInstanceOf[SpecialException]
+ // case e =>
+ // }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t7459b.scala b/test/files/pos/t7459b.scala
new file mode 100644
index 0000000000..a4b4fd07a9
--- /dev/null
+++ b/test/files/pos/t7459b.scala
@@ -0,0 +1,12 @@
+import scala.concurrent._
+import scala.util._
+
+
+class Test {
+ (null: Any) match {
+ case s @ Some(_) => ???
+ case f @ _ =>
+ () => f
+ ???
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t7459c.scala b/test/files/pos/t7459c.scala
new file mode 100644
index 0000000000..dc2605abe6
--- /dev/null
+++ b/test/files/pos/t7459c.scala
@@ -0,0 +1,18 @@
+object Test {
+ trait Universe {
+ type Type
+ type TypeTag[A] >: Null <: TypeTagApi[A]
+ trait TypeTagApi[A] { def tpe: Type }
+ }
+ trait JavaUniverse extends Universe
+
+ trait Mirror[U <: Universe] {
+ def universe: U
+ }
+ (null: Mirror[_]).universe match {
+ case ju: JavaUniverse =>
+ val ju1 = ju
+ val f = {() => (null: ju.TypeTag[Nothing]).tpe }
+ }
+ trait M[A]
+}
diff --git a/test/files/pos/t7459d.scala b/test/files/pos/t7459d.scala
new file mode 100644
index 0000000000..7843156885
--- /dev/null
+++ b/test/files/pos/t7459d.scala
@@ -0,0 +1,8 @@
+class Test {
+ (null: Any) match {
+ case s @ Some(_) => ???
+ case f @ _ =>
+ () => f
+ ???
+ }
+}
diff --git a/test/files/pos/t7704.scala b/test/files/pos/t7704.scala
new file mode 100644
index 0000000000..cae88d3324
--- /dev/null
+++ b/test/files/pos/t7704.scala
@@ -0,0 +1,10 @@
+class Attr { type V ; class Val }
+class StrAttr extends Attr { type V = String }
+class BoolAttr extends Attr { type V = Boolean }
+
+object Main {
+ def f(x: Attr) = x match {
+ case v: StrAttr => new v.Val
+ case v: BoolAttr => new v.Val
+ }
+}
diff --git a/test/files/pos/t8999.flags b/test/files/pos/t8999.flags
new file mode 100644
index 0000000000..0f96f1f872
--- /dev/null
+++ b/test/files/pos/t8999.flags
@@ -0,0 +1 @@
+-nowarn \ No newline at end of file
diff --git a/test/files/pos/t8999.scala b/test/files/pos/t8999.scala
new file mode 100644
index 0000000000..99c4b2ad84
--- /dev/null
+++ b/test/files/pos/t8999.scala
@@ -0,0 +1,271 @@
+object Types {
+
+ abstract sealed class Type
+
+ case object AnyType extends Type
+
+ case object NothingType extends Type
+
+ case object UndefType extends Type
+
+ case object BooleanType extends Type
+
+ case object IntType extends Type
+
+ case object LongType extends Type
+
+ case object FloatType extends Type
+
+ case object DoubleType extends Type
+
+ case object StringType extends Type
+
+ case object NullType extends Type
+
+ sealed abstract class ReferenceType extends Type
+
+ final case class ClassType(className: String) extends ReferenceType
+
+ final case class ArrayType(baseClassName: String, dimensions: Int) extends ReferenceType
+
+ final case class RecordType(fields: List[RecordType.Field]) extends Type
+
+ object RecordType {
+ final case class Field(name: String, originalName: Option[String],
+ tpe: Type, mutable: Boolean)
+ }
+
+ case object NoType extends Type
+
+}
+
+
+sealed abstract class ClassKind
+
+object ClassKind {
+
+ case object Class extends ClassKind
+
+ case object ModuleClass extends ClassKind
+
+ case object Interface extends ClassKind
+
+ case object RawJSType extends ClassKind
+
+ case object HijackedClass extends ClassKind
+
+ case object TraitImpl extends ClassKind
+
+}
+
+object Trees {
+
+ import Types._
+
+ abstract sealed class Tree
+
+ case object EmptyTree extends Tree
+
+ sealed trait PropertyName
+ case class Ident(name: String, originalName: Option[String]) extends PropertyName
+ object Ident {
+ def apply(name: String): Ident =
+ new Ident(name, Some(name))
+ }
+
+ case class VarDef(name: Ident, vtpe: Type, mutable: Boolean, rhs: Tree) extends Tree
+
+ case class ParamDef(name: Ident, ptpe: Type, mutable: Boolean) extends Tree
+
+ case class Skip() extends Tree
+
+ class Block private(val stats: List[Tree]) extends Tree
+
+ object Block {
+ def unapply(block: Block): Some[List[Tree]] = Some(block.stats)
+ }
+
+ case class Labeled(label: Ident, tpe: Type, body: Tree) extends Tree
+
+ case class Assign(lhs: Tree, rhs: Tree) extends Tree
+
+ case class Return(expr: Tree, label: Option[Ident] = None) extends Tree
+
+ case class If(cond: Tree, thenp: Tree, elsep: Tree) extends Tree
+
+ case class While(cond: Tree, body: Tree, label: Option[Ident] = None) extends Tree
+
+ case class DoWhile(body: Tree, cond: Tree, label: Option[Ident] = None) extends Tree
+
+ case class Try(block: Tree, errVar: Ident, handler: Tree, finalizer: Tree) extends Tree
+
+ case class Throw(expr: Tree) extends Tree
+
+ case class Continue(label: Option[Ident] = None) extends Tree
+
+ case class Match(selector: Tree, cases: List[(List[Literal], Tree)], default: Tree) extends Tree
+
+ case class Debugger() extends Tree
+
+ case class New(cls: ClassType, ctor: Ident, args: List[Tree]) extends Tree
+
+ case class LoadModule(cls: ClassType) extends Tree
+
+ case class StoreModule(cls: ClassType, value: Tree) extends Tree
+
+ case class Select(qualifier: Tree, item: Ident, mutable: Boolean) extends Tree
+
+ case class Apply(receiver: Tree, method: Ident, args: List[Tree]) extends Tree
+
+ case class StaticApply(receiver: Tree, cls: ClassType, method: Ident, args: List[Tree]) extends Tree
+
+ case class TraitImplApply(impl: ClassType, method: Ident, args: List[Tree]) extends Tree
+
+ case class UnaryOp(op: Int, lhs: Tree) extends Tree
+
+ case class BinaryOp(op: Int, lhs: Tree, rhs: Tree) extends Tree
+
+ case class NewArray(tpe: ArrayType, lengths: List[Tree]) extends Tree
+
+ case class ArrayValue(tpe: ArrayType, elems: List[Tree]) extends Tree
+
+ case class ArrayLength(array: Tree) extends Tree
+
+ case class ArraySelect(array: Tree, index: Tree) extends Tree
+
+ case class RecordValue(tpe: RecordType, elems: List[Tree]) extends Tree
+
+ case class IsInstanceOf(expr: Tree, cls: ReferenceType) extends Tree
+
+ case class AsInstanceOf(expr: Tree, cls: ReferenceType) extends Tree
+
+ case class Unbox(expr: Tree, charCode: Char) extends Tree
+
+ case class GetClass(expr: Tree) extends Tree
+
+ case class CallHelper(helper: String, args: List[Tree]) extends Tree
+
+ case class JSNew(ctor: Tree, args: List[Tree]) extends Tree
+
+ case class JSDotSelect(qualifier: Tree, item: Ident) extends Tree
+
+ case class JSBracketSelect(qualifier: Tree, item: Tree) extends Tree
+
+ case class JSFunctionApply(fun: Tree, args: List[Tree]) extends Tree
+
+ case class JSDotMethodApply(receiver: Tree, method: Ident, args: List[Tree]) extends Tree
+
+ case class JSBracketMethodApply(receiver: Tree, method: Tree, args: List[Tree]) extends Tree
+
+ case class JSDelete(prop: Tree) extends Tree
+
+ case class JSUnaryOp(op: String, lhs: Tree) extends Tree
+
+ case class JSBinaryOp(op: String, lhs: Tree, rhs: Tree) extends Tree
+
+ case class JSArrayConstr(items: List[Tree]) extends Tree
+
+ case class JSObjectConstr(fields: List[(PropertyName, Tree)]) extends Tree
+
+ case class JSEnvInfo() extends Tree
+
+ sealed trait Literal extends Tree
+
+ case class Undefined() extends Literal
+
+ case class UndefinedParam() extends Literal
+
+ case class Null() extends Literal
+
+ case class BooleanLiteral(value: Boolean) extends Literal
+
+ case class IntLiteral(value: Int) extends Literal
+
+ case class LongLiteral(value: Long) extends Literal
+
+ case class FloatLiteral(value: Float) extends Literal
+
+ case class DoubleLiteral(value: Double) extends Literal
+
+ case class StringLiteral(value: String) extends Literal with PropertyName
+
+ case class ClassOf(cls: ReferenceType) extends Literal
+
+ case class VarRef(ident: Ident, mutable: Boolean) extends Tree
+
+ case class This() extends Tree
+
+ case class Closure(captureParams: List[ParamDef], params: List[ParamDef],
+ body: Tree, captureValues: List[Tree]) extends Tree
+
+ case class ClassDef(name: Ident, kind: ClassKind, parent: Option[Ident], ancestors: List[Ident], defs: List[Tree]) extends Tree
+
+ case class MethodDef(name: PropertyName, args: List[ParamDef], resultType: Type, body: Tree) extends Tree
+
+ case class PropertyDef(name: PropertyName, getterBody: Tree, setterArg: ParamDef, setterBody: Tree) extends Tree
+
+ case class ConstructorExportDef(name: String, args: List[ParamDef], body: Tree) extends Tree
+
+ case class ModuleExportDef(fullName: String) extends Tree
+
+ final class TreeHash(val treeHash: Array[Byte], val posHash: Array[Byte])
+}
+
+object Main {
+ import Trees._
+ import Types._
+
+ private def transform(tree: Tree) = {
+ val ObjectClass = "O"
+ tree match {
+ case VarDef(_, _, _, rhs) =>
+ case tree: Block =>
+ case Labeled(ident@Ident(label, _), tpe, body) =>
+ case Assign(lhs, rhs) =>
+ case Return(expr, optLabel) =>
+ case If(cond, thenp, elsep) =>
+ case While(cond, body, optLabel) =>
+ case DoWhile(body, cond, None) =>
+ case Try(block, errVar, EmptyTree, finalizer) =>
+ case Try(block, errVar@Ident(name, originalName), handler, finalizer) =>
+ case Throw(expr) =>
+ case Continue(optLabel) =>
+ case Match(selector, cases, default) =>
+ case New(cls, ctor, args) =>
+ case StoreModule(cls, value) =>
+ case tree: Select =>
+ case tree: Apply =>
+ case tree: StaticApply =>
+ case tree: TraitImplApply =>
+ case tree@UnaryOp(_, arg) =>
+ case tree@BinaryOp(op, lhs, rhs) =>
+ case NewArray(tpe, lengths) =>
+ case ArrayValue(tpe, elems) =>
+ case ArrayLength(array) =>
+ case ArraySelect(array, index) =>
+ case RecordValue(tpe, elems) =>
+ case IsInstanceOf(expr, ClassType(ObjectClass)) =>
+ case IsInstanceOf(expr, tpe) =>
+ case AsInstanceOf(expr, ClassType(ObjectClass)) =>
+ case AsInstanceOf(expr, cls) =>
+ case Unbox(arg, charCode) =>
+ case GetClass(expr) =>
+ case JSNew(ctor, args) =>
+ case JSDotSelect(qualifier, item) =>
+ case JSBracketSelect(qualifier, item) =>
+ case tree: JSFunctionApply =>
+ case JSDotMethodApply(receiver, method, args) =>
+ case JSBracketMethodApply(receiver, method, args) =>
+ case JSDelete(JSDotSelect(obj, prop)) =>
+ case JSDelete(JSBracketSelect(obj, prop)) =>
+ case JSUnaryOp(op, lhs) =>
+ case JSBinaryOp(op, lhs, rhs) =>
+ case JSArrayConstr(items) =>
+ case JSObjectConstr(fields) =>
+ case _: VarRef | _: This =>
+ case Closure(captureParams, params, body, captureValues) =>
+ case _: Skip | _: Debugger | _: LoadModule |
+ _: JSEnvInfo | _: Literal | EmptyTree =>
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t7459a.scala b/test/files/run/t7459a.scala
new file mode 100644
index 0000000000..e9653c6e79
--- /dev/null
+++ b/test/files/run/t7459a.scala
@@ -0,0 +1,14 @@
+class LM {
+ class Node[B1]
+ case class CC(n: LM)
+
+ // crash
+ val f: (LM => Any) = {
+ case tttt =>
+ new tttt.Node[Any]()
+ }
+}
+
+object Test extends App {
+ new LM().f(new LM())
+}
diff --git a/test/files/run/t7459b-optimize.flags b/test/files/run/t7459b-optimize.flags
new file mode 100644
index 0000000000..49d036a887
--- /dev/null
+++ b/test/files/run/t7459b-optimize.flags
@@ -0,0 +1 @@
+-optimize
diff --git a/test/files/run/t7459b-optimize.scala b/test/files/run/t7459b-optimize.scala
new file mode 100644
index 0000000000..605890962c
--- /dev/null
+++ b/test/files/run/t7459b-optimize.scala
@@ -0,0 +1,21 @@
+class LM {
+ class Node[B1]
+
+ // crash
+ val g: (CC => Any) = {
+ case CC(tttt) =>
+ new tttt.Node[Any]()
+ }
+
+ val h: (Some[CC] => Any) = {
+ case Some(CC(tttt)) =>
+ new tttt.Node[Any]()
+ }
+}
+
+object Test extends App {
+ new LM().g(new CC(new LM()))
+ new LM().h(Some(new CC(new LM())))
+}
+case class CC(n: LM)
+
diff --git a/test/files/run/t7459b.scala b/test/files/run/t7459b.scala
new file mode 100644
index 0000000000..605890962c
--- /dev/null
+++ b/test/files/run/t7459b.scala
@@ -0,0 +1,21 @@
+class LM {
+ class Node[B1]
+
+ // crash
+ val g: (CC => Any) = {
+ case CC(tttt) =>
+ new tttt.Node[Any]()
+ }
+
+ val h: (Some[CC] => Any) = {
+ case Some(CC(tttt)) =>
+ new tttt.Node[Any]()
+ }
+}
+
+object Test extends App {
+ new LM().g(new CC(new LM()))
+ new LM().h(Some(new CC(new LM())))
+}
+case class CC(n: LM)
+
diff --git a/test/files/run/t7459c.scala b/test/files/run/t7459c.scala
new file mode 100644
index 0000000000..144c5d793b
--- /dev/null
+++ b/test/files/run/t7459c.scala
@@ -0,0 +1,16 @@
+class LM {
+ class Node[B1]
+
+ // crash
+ val g: (CC => Any) = {
+ case CC(tttt) =>
+ tttt.## // no crash
+ new tttt.Node[Any]()
+ }
+}
+
+object Test extends App {
+ new LM().g(new CC(new LM()))
+}
+case class CC(n: LM)
+
diff --git a/test/files/run/t7459d.scala b/test/files/run/t7459d.scala
new file mode 100644
index 0000000000..3263701f9d
--- /dev/null
+++ b/test/files/run/t7459d.scala
@@ -0,0 +1,15 @@
+class LM {
+ class Node[B1]
+ case class CC(n: LM)
+
+ // crash
+ val f: (LM => Any) = {
+ case tttt =>
+ val uuuu: (tttt.type, Any) = (tttt, 0)
+ new uuuu._1.Node[Any]()
+ }
+}
+
+object Test extends App {
+ new LM().f(new LM())
+}
diff --git a/test/files/run/t7459f.scala b/test/files/run/t7459f.scala
new file mode 100644
index 0000000000..63e2109560
--- /dev/null
+++ b/test/files/run/t7459f.scala
@@ -0,0 +1,12 @@
+object Test extends App {
+ class C
+
+ case class FooSeq(x: Int, y: String, z: C*)
+
+ FooSeq(1, "a", new C()) match {
+ case FooSeq(1, "a", x@_* ) =>
+ //println(x.toList)
+ x.asInstanceOf[x.type]
+ assert(x.isInstanceOf[x.type])
+ }
+}
diff --git a/test/files/run/t7965.scala b/test/files/run/t7965.scala
new file mode 100644
index 0000000000..df80d4b5bb
--- /dev/null
+++ b/test/files/run/t7965.scala
@@ -0,0 +1,54 @@
+// Test that scala doesn't apply boxing or varargs conversions to the
+// @PolymorphicSignature magical methods, MethodHandle#{invoke, invokeExact}
+object Test {
+ val code = """
+
+object O {
+ private def foo = "foo"
+ private def bar(x: Int): Int = -x
+ private def baz(x: Box): Unit = x.a = "present"
+ val lookup = java.lang.invoke.MethodHandles.lookup
+}
+
+import java.lang.invoke._
+class Box(var a: Any)
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ def lookup(name: String, params: Array[Class[_]], ret: Class[_]) = {
+ val mt = MethodType.methodType(ret, params)
+ O.lookup.findVirtual(O.getClass, name, mt)
+ }
+ val fooResult = (lookup("foo", Array(), classOf[String]).invokeExact(O): Int)
+ assert(fooResult == "foo")
+
+ val barResult = (lookup("bar", Array(classOf[Int]), classOf[Int]).invokeExact(O, 42): Int)
+ assert(barResult == -42)
+
+ val box = new Box(null)
+ (lookup("baz", Array(classOf[Box]), Void.TYPE).invokeExact(O, box) : Unit)
+ assert(box.a == "present")
+
+ // Note: Application in statement position in a block in Java also infers return type of Unit,
+ // but we don't support that, ascribe the type to Unit as above.
+ // as done in Java.
+ // lookup("baz", Array(classOf[Box]), Void.TYPE).invokeExact(O, box)
+ ()
+ }
+}
+
+"""
+ def main(args: Array[String]): Unit = {
+ if (util.Properties.isJavaAtLeast("1.7")) test()
+ }
+
+ def test() {
+ import scala.reflect.runtime._
+ import scala.tools.reflect.ToolBox
+
+ val m = currentMirror
+ val tb = m.mkToolBox()
+ import tb._
+ eval(parse(code))
+ }
+}
diff --git a/test/files/run/t9030.scala b/test/files/run/t9030.scala
new file mode 100644
index 0000000000..48d24e5b54
--- /dev/null
+++ b/test/files/run/t9030.scala
@@ -0,0 +1,19 @@
+object Test extends App {
+
+ // For these methods, the compiler emits calls to BoxesRuntime.equalsNumNum/equalsNumChar/equalsNumObject directly
+
+ def numNum(a: java.lang.Number, b: java.lang.Number) = assert(a == b)
+ def numChar(a: java.lang.Number, b: java.lang.Character) = assert(a == b)
+ def numObject(a: java.lang.Number, b: java.lang.Object) = assert(a == b)
+
+ // The compiler doesn't use equalsCharObject directly, but still adding an example for completeness
+
+ def charObject(a: java.lang.Character, b: java.lang.Object) = assert(a == b)
+
+ numNum(new Integer(1), new Integer(1))
+ numChar(new Integer(97), new Character('a'))
+ numObject(new Integer(1), new Integer(1))
+ numObject(new Integer(97), new Character('a'))
+
+ charObject(new Character('a'), new Integer(97))
+}