diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index e5841a3de768..e86eb98be758 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -849,11 +849,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val namedTupleElems = qual.tpe.widenDealias.namedTupleElementTypes(true) val nameIdx = namedTupleElems.indexWhere(_._1 == selName) if nameIdx >= 0 && sourceVersion.enablesNamedTuples then - typed( - untpd.Apply( - untpd.Select(untpd.TypedSplice(qual), nme.apply), - untpd.Literal(Constant(nameIdx))), - pt) + if namedTupleElems.forall(_._1 != nme.apply) then + typed( + untpd.Apply( + untpd.Select(untpd.TypedSplice(qual), nme.apply), + untpd.Literal(Constant(nameIdx))), + pt) + else + report.error( + em"""Named tuples that define an `apply` field do not allow field selection. + |The `apply` field should be renamed to something else.""", + tree0.srcPos) + EmptyTree else EmptyTree // Otherwise, map combinations of A *: B *: .... EmptyTuple with nesting levels <= 22 diff --git a/tests/neg/named-tuple-apply.check b/tests/neg/named-tuple-apply.check new file mode 100644 index 000000000000..7a0c0c961963 --- /dev/null +++ b/tests/neg/named-tuple-apply.check @@ -0,0 +1,28 @@ +-- Error: tests/neg/named-tuple-apply.scala:5:2 ------------------------------------------------------------------------ +5 | (apply = () => 1)(()) // error // error + | ^^^^^^^^^^^^^^^^^ + | Named tuples that define an `apply` field do not allow field selection. + | The `apply` field should be renamed to something else. +-- [E007] Type Mismatch Error: tests/neg/named-tuple-apply.scala:5:20 -------------------------------------------------- +5 | (apply = () => 1)(()) // error // error + | ^^ + | Found: Unit + | Required: Int + | + | longer explanation available when compiling with `-explain` +-- Error: tests/neg/named-tuple-apply.scala:6:29 ----------------------------------------------------------------------- +6 | (apply = () => 1, foo = 2).foo // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Named tuples that define an `apply` field do not allow field selection. + | The `apply` field should be renamed to something else. +-- Error: tests/neg/named-tuple-apply.scala:7:29 ----------------------------------------------------------------------- +7 | (apply = () => 1, foo = 2).apply(1) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Named tuples that define an `apply` field do not allow field selection. + | The `apply` field should be renamed to something else. +-- [E050] Type Error: tests/neg/named-tuple-apply.scala:10:2 ----------------------------------------------------------- +10 | foo() // error (error message could be better) + | ^^^ + | method apply in class Foo does not take parameters + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/named-tuple-apply.scala b/tests/neg/named-tuple-apply.scala new file mode 100644 index 000000000000..0e2c94bf76b5 --- /dev/null +++ b/tests/neg/named-tuple-apply.scala @@ -0,0 +1,10 @@ +class Foo: + def apply: () => Int = () => 2 + +def test = + (apply = () => 1)(()) // error // error + (apply = () => 1, foo = 2).foo // error + (apply = () => 1, foo = 2).apply(1) // error + + val foo = Foo() + foo() // error (error message could be better)