diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 1ce0f6376b95..be6a43de3976 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -140,9 +140,19 @@ trait TypeAssigner { val name = tree.name val pre = maybeSkolemizePrefix(qualType, name) val mbr = qualType.findMember(name, pre) + def isDynamicExpansion(tree: untpd.RefTree): Boolean = { + Dynamic.isDynamicMethod(name) || ( + tree match + case Select(Apply(fun: untpd.RefTree, _), nme.apply) if defn.isContextFunctionClass(fun.symbol.owner) => + isDynamicExpansion(fun) + case Select(qual, nme.apply) => + Dynamic.isDynamicMethod(qual.symbol.name) && tree.span.isSynthetic + case _ => false + ) + } if (reallyExists(mbr)) qualType.select(name, mbr) - else if (qualType.derivesFrom(defn.DynamicClass) && name.isTermName && !Dynamic.isDynamicMethod(name)) + else if (qualType.derivesFrom(defn.DynamicClass) && name.isTermName && !isDynamicExpansion(tree)) TryDynamicCallType else if (qualType.isErroneous || name.toTermName == nme.ERROR) UnspecifiedErrorType diff --git a/tests/neg/i9295a.scala b/tests/neg/i9295a.scala new file mode 100644 index 000000000000..86acc959f931 --- /dev/null +++ b/tests/neg/i9295a.scala @@ -0,0 +1,9 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(arg: Any): Foo = ??? +} +object F { + val foo = new Foo + def baz = foo.blah(43) // error: method applyDynamic in class Foo does not take more parameters +} diff --git a/tests/neg/i9295b.scala b/tests/neg/i9295b.scala new file mode 100644 index 000000000000..24a5c81eaede --- /dev/null +++ b/tests/neg/i9295b.scala @@ -0,0 +1,14 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(arg: Any): Bar = ??? +} +class Bar extends Dynamic { + def applyDynamic(arg: Any)(x: Int): Int = ??? +} +object F { + val foo = new Foo + def baz = foo.blah(43) // error: method applyDynamic in class Foo does not take more parameters + def qux = foo.blah.blah(43) // error: value selectDynamic is not a member of Foo + def quxx = foo.blah().blah(43) // error: method applyDynamic in class Foo does not take more parameters +} diff --git a/tests/neg/i9295c.scala b/tests/neg/i9295c.scala new file mode 100644 index 000000000000..701b84fa4bcc --- /dev/null +++ b/tests/neg/i9295c.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def selectDynamic(name: String)(using DummyImplicit): Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah(42) // error diff --git a/tests/neg/i9295d.scala b/tests/neg/i9295d.scala new file mode 100644 index 000000000000..28c64d8fb77a --- /dev/null +++ b/tests/neg/i9295d.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(name: String)(): DummyImplicit ?=> Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah()(42) // error diff --git a/tests/pos/i9295.scala b/tests/pos/i9295.scala new file mode 100644 index 000000000000..654ff1dc00d5 --- /dev/null +++ b/tests/pos/i9295.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(name: String)(): Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah().apply(42) diff --git a/tests/pos/i9295b.scala b/tests/pos/i9295b.scala new file mode 100644 index 000000000000..071875b7fa24 --- /dev/null +++ b/tests/pos/i9295b.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(name: String)()(using DummyImplicit): Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah().apply(42) diff --git a/tests/pos/i9295c.scala b/tests/pos/i9295c.scala new file mode 100644 index 000000000000..f0e86339bf4c --- /dev/null +++ b/tests/pos/i9295c.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def selectDynamic(name: String)(using DummyImplicit): Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah.apply(42) diff --git a/tests/pos/i9295d.scala b/tests/pos/i9295d.scala new file mode 100644 index 000000000000..8488d71cc067 --- /dev/null +++ b/tests/pos/i9295d.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +class Foo extends Dynamic { + def applyDynamic(name: String)(): DummyImplicit ?=> DummyImplicit ?=> Bar = ??? +} + +class Bar extends Dynamic { + def applyDynamic(name: String)(x: Int) = ??? +} + +val foo = new Foo +def baz = foo.blah().apply(42)