diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a562e69acc00..c9458c547aec 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -62,8 +62,21 @@ object Typer { if (!tree.isEmpty && !tree.isInstanceOf[untpd.TypedSplice] && ctx.typerState.isGlobalCommittable) assert(tree.pos.exists, s"position not set for $tree # ${tree.uniqueId}") + /** A context property that indicates the owner of any expressions to be typed in the context + * if that owner is different from the context's owner. Typically, a context with a class + * as owner would have a local dummy as ExprOwner value. + */ private val ExprOwner = new Property.Key[Symbol] + + /** An attachment on a Select node with an `apply` field indicating that the `apply` + * was inserted by the Typer. + */ private val InsertedApply = new Property.Key[Unit] + + /** An attachment on a tree `t` occurring as part of a `t()` where + * the `()` was dropped by the Typer. + */ + private val DroppedEmptyArgs = new Property.Key[Unit] } class Typer extends Namer with TypeAssigner with Applications with Implicits with Dynamic with Checking with Docstrings { @@ -1862,6 +1875,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit * * 0th strategy: If `tree` overrides a nullary method, mark the prototype * so that the argument is dropped and return `tree` itself. + * (but do this at most once per tree). * * After that, two strategies are tried, and the first that is successful is picked. * If neither of the strategies are successful, continues with`fallBack`. @@ -1899,7 +1913,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit pt match { case pt @ FunProto(Nil, _, _) - if tree.symbol.allOverriddenSymbols.exists(_.info.isNullaryMethod) => + if tree.symbol.allOverriddenSymbols.exists(_.info.isNullaryMethod) && + tree.getAttachment(DroppedEmptyArgs).isEmpty => + tree.putAttachment(DroppedEmptyArgs, ()) pt.markAsDropped() tree case _ => diff --git a/tests/neg/i3012/Fuzbar.java b/tests/neg/i3012/Fuzbar.java new file mode 100644 index 000000000000..2818d4f6455e --- /dev/null +++ b/tests/neg/i3012/Fuzbar.java @@ -0,0 +1,4 @@ +package fuz; +public interface Fuzbar { + public String str(); +} \ No newline at end of file diff --git a/tests/neg/i3012/a.scala b/tests/neg/i3012/a.scala new file mode 100644 index 000000000000..29f65430f05c --- /dev/null +++ b/tests/neg/i3012/a.scala @@ -0,0 +1,8 @@ + +object a extends fuz.Fuzbar { + override def str = "" + str()()()()()() // error: missing argument + str()() // error: missing argument + str() // ok + str // ok +}