Skip to content

Commit eb374a1

Browse files
committed
Disallow @main methods with implicit parameters
1 parent 622e8c3 commit eb374a1

File tree

2 files changed

+31
-23
lines changed

2 files changed

+31
-23
lines changed

compiler/src/dotty/tools/dotc/ast/MainProxies.scala

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,50 @@ object MainProxies {
4242
import untpd._
4343
def mainProxy(mainFun: Symbol) given (ctx: Context): List[TypeDef] = {
4444
val mainAnnotSpan = mainFun.getAnnotation(defn.MainAnnot).get.tree.span
45-
45+
def pos = mainFun.sourcePos
4646
val argsRef = Ident(nme.args)
4747

48-
def addArgs(call: untpd.Tree, formals: List[Type], restpe: Type, idx: Int): untpd.Tree = {
49-
val args = formals.zipWithIndex map {
50-
(formal, n) =>
51-
val (parserSym, formalElem) =
52-
if (formal.isRepeatedParam) (defn.CLP_parseRemainingArguments, formal.argTypes.head)
53-
else (defn.CLP_parseArgument, formal)
54-
val arg = Apply(
55-
TypeApply(ref(parserSym.termRef), TypeTree(formalElem) :: Nil),
56-
argsRef :: Literal(Constant(idx + n)) :: Nil)
57-
if (formal.isRepeatedParam) repeated(arg) else arg
48+
def addArgs(call: untpd.Tree, mt: MethodType, idx: Int): untpd.Tree = {
49+
if (mt.isImplicitMethod) {
50+
ctx.error(s"@main method cannot have implicit parameters", pos)
51+
call
5852
}
59-
val call1 = Apply(call, args)
60-
restpe match {
61-
case restpe: MethodType if !restpe.isImplicitMethod =>
62-
if (formals.lastOption.getOrElse(NoType).isRepeatedParam)
63-
ctx.error(s"varargs parameter of @main method must come last", mainFun.sourcePos)
64-
addArgs(call1, restpe.paramInfos, restpe.resType, idx + args.length)
65-
case _ =>
66-
call1
53+
else {
54+
val args = mt.paramInfos.zipWithIndex map {
55+
(formal, n) =>
56+
val (parserSym, formalElem) =
57+
if (formal.isRepeatedParam) (defn.CLP_parseRemainingArguments, formal.argTypes.head)
58+
else (defn.CLP_parseArgument, formal)
59+
val arg = Apply(
60+
TypeApply(ref(parserSym.termRef), TypeTree(formalElem) :: Nil),
61+
argsRef :: Literal(Constant(idx + n)) :: Nil)
62+
if (formal.isRepeatedParam) repeated(arg) else arg
63+
}
64+
val call1 = Apply(call, args)
65+
mt.resType match {
66+
case restpe: MethodType =>
67+
if (mt.paramInfos.lastOption.getOrElse(NoType).isRepeatedParam)
68+
ctx.error(s"varargs parameter of @main method must come last", pos)
69+
addArgs(call1, restpe, idx + args.length)
70+
case _ =>
71+
call1
72+
}
6773
}
6874
}
6975

7076
var result: List[TypeDef] = Nil
7177
if (!mainFun.owner.isStaticOwner)
72-
ctx.error(s"@main method is not statically accessible", mainFun.sourcePos)
78+
ctx.error(s"@main method is not statically accessible", pos)
7379
else {
7480
var call = ref(mainFun.termRef)
7581
mainFun.info match {
7682
case _: ExprType =>
7783
case mt: MethodType =>
78-
if (!mt.isImplicitMethod) call = addArgs(call, mt.paramInfos, mt.resultType, 0)
84+
call = addArgs(call, mt, 0)
7985
case _: PolyType =>
80-
ctx.error(s"@main method cannot have type parameters", mainFun.sourcePos)
86+
ctx.error(s"@main method cannot have type parameters", pos)
8187
case _ =>
82-
ctx.error(s"@main can only annotate a method", mainFun.sourcePos)
88+
ctx.error(s"@main can only annotate a method", pos)
8389
}
8490
val errVar = Ident(nme.error)
8591
val handler = CaseDef(

tests/neg/main-functions2.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ class Foo {
99
@main def g(x: Int*)(y: Int*) = () // error: varargs parameter of @main method must come last
1010

1111
@main def h[T: util.FromString](x: T) = () // error: @main method cannot have type parameters
12+
13+
@main def i(x: Int) given Foo = () // error: @main method cannot have implicit parameters

0 commit comments

Comments
 (0)