summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala20
-rw-r--r--test/files/run/t6327.check4
-rw-r--r--test/files/run/t6327.scala22
3 files changed, 39 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 21d61ff7b1..1beae1464a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3811,18 +3811,23 @@ trait Typers extends Modes with Adaptations with Tags {
* - simplest solution: have two method calls
*
*/
- def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] =
+ def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
+ debuglog(s"mkInvoke($cxTree, $tree, $qual, $name)")
acceptsApplyDynamicWithType(qual, name) map { tp =>
// tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user)
// in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct)
- // strip off type application -- we're not doing much with outer, so don't bother preserving cxTree's attributes etc
- val (outer, explicitTargs) = cxTree match {
- case TypeApply(fun, targs) => (fun, targs)
- case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
- case t => (t, Nil)
+ // strip off type application -- we're not doing much with outer,
+ // so don't bother preserving cxTree's attributes etc
+ val cxTree1 = cxTree match {
+ case t: ValOrDefDef => t.rhs
+ case t => t
+ }
+ val (outer, explicitTargs) = cxTree1 match {
+ case TypeApply(fun, targs) => (fun, targs)
+ case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
+ case t => (t, Nil)
}
-
@inline def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty
// note: context.tree includes at most one Apply node
@@ -3847,6 +3852,7 @@ trait Typers extends Modes with Adaptations with Tags {
atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
}
+ }
}
@inline final def deindentTyping() = context.typingIndentLevel -= 2
diff --git a/test/files/run/t6327.check b/test/files/run/t6327.check
new file mode 100644
index 0000000000..f7bacac931
--- /dev/null
+++ b/test/files/run/t6327.check
@@ -0,0 +1,4 @@
+A
+A
+A
+A
diff --git a/test/files/run/t6327.scala b/test/files/run/t6327.scala
new file mode 100644
index 0000000000..7683101f14
--- /dev/null
+++ b/test/files/run/t6327.scala
@@ -0,0 +1,22 @@
+import language._
+
+object Test extends App {
+
+ case class R[+T](s: String) { def x() = println(s) }
+
+ // Implicits in contention; StringR is nested to avoid ambiguity
+ object R { implicit val StringR = R[String]("A") }
+ implicit val Default = R[Any]("B")
+
+ class B() extends Dynamic {
+ def selectDynamic[T](f: String)(implicit r: R[T]): Unit = r.x()
+ }
+
+ val b = new B()
+
+ // These should all produce the same output, but they don't
+ b.selectDynamic[String]("baz")
+ b.baz[String]
+ val c = b.selectDynamic[String]("baz")
+ val d = b.baz[String]
+}