Skip to content

Commit a21c616

Browse files
committed
Warn on unary methods with parameters
Fixes #9241
1 parent 1d83d0f commit a21c616

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,30 @@ object RefChecks {
10471047
report.error(i"private $sym cannot override ${other.showLocated}", sym.srcPos)
10481048
end checkNoPrivateOverrides
10491049

1050+
/** Check that unary method definition do not receive parameters.
1051+
* They can only receive inferred parameters such as type parameters and implicit parameters.
1052+
*/
1053+
def checkUnaryMethods(sym: Symbol)(using Context): Unit =
1054+
def checkParameters(tpe: Type): Unit =
1055+
tpe match
1056+
case tpe: MethodType =>
1057+
if tpe.isImplicitMethod || tpe.isContextualMethod then
1058+
checkParameters(tpe.resType)
1059+
else
1060+
val what =
1061+
if tpe.paramNames.isEmpty then "empty parameter list.\n\nPossible fix: remove the `()` arguments."
1062+
else "parameters"
1063+
report.warning(s"Unary method cannot take $what", sym.sourcePos)
1064+
case tpe: PolyType =>
1065+
checkParameters(tpe.resType)
1066+
case _ =>
1067+
// ok
1068+
1069+
if sym.name.startsWith(nme.UNARY_PREFIX.toString) then
1070+
checkParameters(sym.info)
1071+
1072+
end checkUnaryMethods
1073+
10501074
type LevelAndIndex = immutable.Map[Symbol, (LevelInfo, Int)]
10511075

10521076
class OptLevelInfo {
@@ -1254,6 +1278,7 @@ class RefChecks extends MiniPhase { thisPhase =>
12541278
checkExperimentalAnnots(tree.symbol)
12551279
checkExperimentalSignature(tree.symbol, tree)
12561280
checkImplicitNotFoundAnnotation.defDef(tree.symbol.denot)
1281+
checkUnaryMethods(tree.symbol)
12571282
tree
12581283
}
12591284

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Foo {
2+
def unary_~() : Foo = this // error
3+
def unary_-(using Int)(): Foo = this // error
4+
def unary_+()(implicit i: Int): Foo = this // error
5+
def unary_![T](): Foo = this // error
6+
}
7+
8+
9+
class Bar {
10+
def unary_~ : Bar = this
11+
def unary_-(using Int): Bar = this
12+
def unary_+(implicit i: Int): Bar = this
13+
def unary_![T]: Bar = this
14+
}
15+

0 commit comments

Comments
 (0)