Skip to content

Commit c656920

Browse files
committed
SI-6663: don't ignore type parameter on selectDynamic invocation
Fix mkInvoke to handle selectDynamic calls of the form new C.foo[T].xyz or new C.foo[T].xyz :U (where C extends Dynamic) Without this patch, the type parameter was silently ignored, and possibly inferred to a different. This patch fixes mkInvoke to handle these cases, where ctxTree has the form Select(TypeApply(fun, targs), nme) or Typed(...)
1 parent 8501088 commit c656920

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3935,9 +3935,14 @@ trait Typers extends Modes with Adaptations with Tags {
39353935
case t: ValOrDefDef => t.rhs
39363936
case t => t
39373937
}
3938-
val (outer, explicitTargs) = cxTree1 match {
3938+
val cxTree2 = cxTree1 match {
3939+
case Typed(t, tpe) => t // ignore outer type annotation
3940+
case t => t
3941+
}
3942+
val (outer, explicitTargs) = cxTree2 match {
39393943
case TypeApply(fun, targs) => (fun, targs)
39403944
case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
3945+
case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
39413946
case t => (t, Nil)
39423947
}
39433948
def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty

test/files/neg/t6663.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
t6663.scala:16: error: type mismatch;
2+
found : String
3+
required: Int
4+
var v = new C(42).foo[String].get :Int
5+
^
6+
one error found

test/files/neg/t6663.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import language.dynamics
2+
3+
class C(v: Any) extends Dynamic {
4+
def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
5+
def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
6+
}
7+
8+
object Test extends App {
9+
// this should be converted to
10+
// C(42).selectDynamic[String]("foo").get
11+
// causing a compile error.
12+
13+
// but, before fixing SI-6663, became
14+
// C(42).selectDynamic("foo").get, ignoring
15+
// the [String] type parameter
16+
var v = new C(42).foo[String].get :Int
17+
println(v)
18+
}
19+

test/files/run/t6663.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
42

test/files/run/t6663.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import language.dynamics
2+
3+
class C(v: Any) extends Dynamic {
4+
def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
5+
def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
6+
}
7+
8+
object Test extends App {
9+
// this should be converted to
10+
// C(42).selectDynamic[Int]("foo").get
11+
// but, before fixing SI-6663, became
12+
// C(42).selectDynamic[Nothing]("foo").get
13+
// leading to a ClassCastException
14+
var v = new C(42).foo[Int].get
15+
println(v)
16+
}
17+

0 commit comments

Comments
 (0)