Skip to content

Commit 35b7541

Browse files
committed
Fix unused method types propagation to next ()
1 parent 28a8554 commit 35b7541

File tree

6 files changed

+25
-31
lines changed

6 files changed

+25
-31
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+7-7
Original file line numberDiff line numberDiff line change
@@ -1843,12 +1843,12 @@ object Parsers {
18431843
def typeParamClauseOpt(ownerKind: ParamOwner.Value): List[TypeDef] =
18441844
if (in.token == LBRACKET) typeParamClause(ownerKind) else Nil
18451845

1846-
/** ClsParamClauses ::= {ClsParamClause} [[nl] `(' `implicit' ClsParams `)']
1847-
* ClsParamClause ::= [nl] `(' [ClsParams] ')'
1846+
/** ClsParamClauses ::= {ClsParamClause} [[nl] `(' `implicit' [`unused'] ClsParams `)']
1847+
* ClsParamClause ::= [nl] `(' [`unused'] [ClsParams] ')'
18481848
* ClsParams ::= ClsParam {`' ClsParam}
18491849
* ClsParam ::= {Annotation} [{Modifier} (`val' | `var') | `inline'] Param
1850-
* DefParamClauses ::= {DefParamClause} [[nl] `(' `implicit' DefParams `)']
1851-
* DefParamClause ::= [nl] `(' [DefParams] ')'
1850+
* DefParamClauses ::= {DefParamClause} [[nl] `(' `implicit' [`unused'] DefParams `)']
1851+
* DefParamClause ::= [nl] `(' [`unused'] [DefParams] ')'
18521852
* DefParams ::= DefParam {`,' DefParam}
18531853
* DefParam ::= {Annotation} [`inline'] Param
18541854
* Param ::= id `:' ParamType [`=' Expr]
@@ -1907,7 +1907,6 @@ object Parsers {
19071907
if (in.token == RPAREN) Nil
19081908
else {
19091909
if (in.token == IMPLICIT || in.token == UNUSED) {
1910-
imods = EmptyModifiers
19111910
if (in.token == IMPLICIT) {
19121911
implicitOffset = in.offset
19131912
imods = implicitMods(imods)
@@ -1920,12 +1919,13 @@ object Parsers {
19201919
}
19211920
def clauses(): List[List[ValDef]] = {
19221921
newLineOptWhenFollowedBy(LPAREN)
1923-
if (in.token == LPAREN)
1922+
if (in.token == LPAREN) {
1923+
imods = EmptyModifiers
19241924
paramClause() :: {
19251925
firstClauseOfCaseClass = false
19261926
if (imods is Implicit) Nil else clauses()
19271927
}
1928-
else Nil
1928+
} else Nil
19291929
}
19301930
val start = in.offset
19311931
val result = clauses()

compiler/src/dotty/tools/dotc/transform/Erasure.scala

+10-16
Original file line numberDiff line numberDiff line change
@@ -447,24 +447,16 @@ object Erasure {
447447
private def runtimeCallWithProtoArgs(name: Name, pt: Type, args: Tree*)(implicit ctx: Context): Tree = {
448448
val meth = defn.runtimeMethodRef(name)
449449
val followingParams = meth.symbol.info.firstParamTypes.drop(args.length)
450-
val followingArgs = protoArgs(pt).zipWithConserve(followingParams)(typedExpr).asInstanceOf[List[tpd.Tree]]
450+
val followingArgs = protoArgs(pt, meth.widen).zipWithConserve(followingParams)(typedExpr).asInstanceOf[List[tpd.Tree]]
451451
ref(meth).appliedToArgs(args.toList ++ followingArgs)
452452
}
453453

454-
private def protoArgs(pt: Type): List[untpd.Tree] = pt match {
455-
case pt: FunProto => pt.args ++ protoArgs(pt.resType)
454+
private def protoArgs(pt: Type, tp: Type): List[untpd.Tree] = (pt, tp) match {
455+
case (pt: FunProto, tp: MethodType) if tp.isUnusedMethod => protoArgs(pt.resType, tp.resType)
456+
case (pt: FunProto, tp: MethodType) => pt.args ++ protoArgs(pt.resType, tp.resType)
456457
case _ => Nil
457458
}
458459

459-
// TODO: merge this whit protoArgs if it is actually needed
460-
private def protoArgs2(pt: Type, tp: Type): List[untpd.Tree] = (pt, tp) match {
461-
case (pt: FunProto, tp: MethodType) if tp.isUnusedMethod => protoArgs2(pt.resType, tp.resType)
462-
case (pt: FunProto, tp: MethodType) => pt.args ++ protoArgs2(pt.resType, tp.resType)
463-
case _ =>
464-
assert(!tp.isInstanceOf[MethodOrPoly], tp)
465-
Nil
466-
}
467-
468460
override def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context) = {
469461
val ntree = interceptTypeApply(tree.asInstanceOf[TypeApply])(ctx.withPhase(ctx.erasurePhase))
470462

@@ -495,8 +487,8 @@ object Erasure {
495487
fun1.tpe.widen match {
496488
case mt: MethodType =>
497489
val outers = outer.args(fun.asInstanceOf[tpd.Tree]) // can't use fun1 here because its type is already erased
498-
var args0 = protoArgs2(pt, tree.typeOpt)
499-
if (!mt.isUnusedMethod) args0 = args ::: args0
490+
var args0 = protoArgs(pt, tree.typeOpt)
491+
if (mt.paramNames.nonEmpty && !mt.isUnusedMethod) args0 = args ::: args0
500492
args0 = outers ::: args0
501493

502494
if (args0.length > MaxImplementedFunctionArity && mt.paramInfos.length == 1) {
@@ -505,8 +497,10 @@ object Erasure {
505497
args0 = bunchedArgs :: Nil
506498
}
507499
// Arguments are phantom if an only if the parameters are phantom, guaranteed by the separation of type lattices
508-
val args1 = args0.filterConserve(arg => !wasPhantom(arg.typeOpt)).zipWithConserve(mt.paramInfos)(typedExpr)
509-
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
500+
val args1 = args0.filterConserve(arg => !wasPhantom(arg.typeOpt))
501+
assert(args1 hasSameLengthAs mt.paramInfos)
502+
val args2 = args1.zipWithConserve(mt.paramInfos)(typedExpr)
503+
untpd.cpy.Apply(tree)(fun1, args2) withType mt.resultType
510504
case _ =>
511505
throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
512506
}

tests/run/unused-4.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
foo
22
foo2
3-
fun
3+
fun 42
44
foo
55
foo2
6-
fun2
6+
fun2 abc

tests/run/unused-4.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ object Test {
1616
}
1717

1818
def fun(a: Int)(unused b: String): Unit = {
19-
println("fun")
19+
println("fun " + a)
2020
}
2121

2222
def fun2(unused a: Int)(b: String): Unit = {
23-
println("fun2")
23+
println("fun2 " + b)
2424
}
2525
}

tests/run/unused-5.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ foo
22
foo
33
foo
44
foo
5-
fun
5+
fun 42 42
66
foo
77
foo
88
foo
99
foo
10-
fun2
10+
fun2 42 42

tests/run/unused-5.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ object Test {
1111
}
1212

1313
def fun(a: Int)(unused b: Int)(c: Int)(unused d: Int): Unit = {
14-
println("fun")
14+
println("fun " + a + " " + c)
1515
}
1616

1717
def fun2(unused a2: Int)(b2: Int)(unused c2: Int)(d2: Int): Unit = {
18-
println("fun2")
18+
println("fun2 " + b2 + " " + d2)
1919
}
2020
}

0 commit comments

Comments
 (0)