Skip to content

Commit 5b618dd

Browse files
committed
Fix unused/implicit fixed order
1 parent 248c1c7 commit 5b618dd

File tree

3 files changed

+39
-35
lines changed

3 files changed

+39
-35
lines changed

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

+28-33
Original file line numberDiff line numberDiff line change
@@ -730,24 +730,23 @@ object Parsers {
730730
}
731731
}
732732

733-
/** Type ::= [`implicit'] [`unused'] FunArgTypes `=>' Type
733+
/** Type ::= [FunArgMods] FunArgTypes `=>' Type
734734
* | HkTypeParamClause `->' Type
735735
* | InfixType
736+
* FunArgMods ::= `implicit' FunArgMods
737+
* | `unused' FunArgMods
736738
* FunArgTypes ::= InfixType
737739
* | `(' [ FunArgType {`,' FunArgType } ] `)'
738740
*/
739741
def typ(): Tree = {
740742
val start = in.offset
741-
val isImplicit = in.token == IMPLICIT
742-
if (isImplicit) in.nextToken()
743-
val isUnused = in.token == UNUSED
744-
if (isUnused) in.nextToken()
743+
val imods = allFunctionMods(EmptyModifiers)
745744
def functionRest(params: List[Tree]): Tree =
746745
atPos(start, accept(ARROW)) {
747746
val t = typ()
748-
if (isImplicit && isUnused) new UnusedImplicitFunction(params, t)
749-
else if (isImplicit) new ImplicitFunction(params, t)
750-
else if (isUnused) new UnusedFunction(params, t)
747+
if (imods.is(Implicit) && imods.is(Unused)) new UnusedImplicitFunction(params, t)
748+
else if (imods.is(Implicit)) new ImplicitFunction(params, t)
749+
else if (imods.is(Unused)) new UnusedFunction(params, t)
751750
else Function(params, t)
752751
}
753752
val t =
@@ -762,7 +761,7 @@ object Parsers {
762761
val ts = commaSeparated(funArgType)
763762
openParens.change(LPAREN, -1)
764763
accept(RPAREN)
765-
if (isImplicit || in.token == ARROW) functionRest(ts)
764+
if (imods.is(Implicit) || in.token == ARROW) functionRest(ts)
766765
else {
767766
for (t <- ts)
768767
if (t.isInstanceOf[ByNameTypeTree])
@@ -789,7 +788,7 @@ object Parsers {
789788
case ARROW => functionRest(t :: Nil)
790789
case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
791790
case _ =>
792-
if (isImplicit && !t.isInstanceOf[ImplicitFunction])
791+
if (imods.is(Implicit) && !t.isInstanceOf[ImplicitFunction])
793792
syntaxError("Types with implicit keyword can only be function types", Position(start, start + nme.IMPLICITkw.asSimpleName.length))
794793
t
795794
}
@@ -1016,14 +1015,16 @@ object Parsers {
10161015
}
10171016
}
10181017

1019-
/** Expr ::= [`implicit'] FunParams `=>' Expr
1018+
/** Expr ::= [FunArgMods] FunParams =>' Expr
10201019
* | Expr1
1020+
* FunArgMods ::= `implicit' FunArgMods
1021+
* | `unused' FunArgMods
10211022
* FunParams ::= Bindings
10221023
* | id
10231024
* | `_'
10241025
* ExprInParens ::= PostfixExpr `:' Type
10251026
* | Expr
1026-
* BlockResult ::= [`implicit'] FunParams `=>' Block
1027+
* BlockResult ::= [FunArgMods] FunParams =>' Block
10271028
* | Expr1
10281029
* Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
10291030
* | `if' Expr `then' Expr [[semi] else Expr]
@@ -1052,9 +1053,7 @@ object Parsers {
10521053
def expr(location: Location.Value): Tree = {
10531054
val start = in.offset
10541055
if (in.token == IMPLICIT || in.token == UNUSED) {
1055-
var imods = EmptyModifiers
1056-
if (in.token == IMPLICIT) imods = implicitMods(imods)
1057-
if (in.token == UNUSED) imods = unusedMods(imods)
1056+
val imods = allFunctionMods(EmptyModifiers)
10581057
implicitClosure(start, location, imods)
10591058
} else {
10601059
val saved = placeholderParams
@@ -1751,11 +1750,14 @@ object Parsers {
17511750
normalize(loop(start))
17521751
}
17531752

1754-
def implicitMods(imods: Modifiers = EmptyModifiers): Modifiers =
1755-
addMod(imods, atPos(accept(IMPLICIT)) { Mod.Implicit() })
1756-
1757-
def unusedMods(imods: Modifiers = EmptyModifiers): Modifiers =
1758-
addMod(imods, atPos(accept(UNUSED)) { Mod.Unused() })
1753+
def allFunctionMods(imods: Modifiers, doIfImplicit: () => Unit = () => ()): Modifiers = {
1754+
if (in.token == IMPLICIT) {
1755+
doIfImplicit()
1756+
allFunctionMods(addMod(imods, atPos(accept(IMPLICIT)) { Mod.Implicit() }), doIfImplicit)
1757+
} else if (in.token == UNUSED)
1758+
allFunctionMods(addMod(imods, atPos(accept(UNUSED)) { Mod.Unused() }), doIfImplicit)
1759+
else imods
1760+
}
17591761

17601762
/** Wrap annotation or constructor in New(...).<init> */
17611763
def wrapNew(tpt: Tree) = Select(New(tpt), nme.CONSTRUCTOR)
@@ -1843,11 +1845,11 @@ object Parsers {
18431845
def typeParamClauseOpt(ownerKind: ParamOwner.Value): List[TypeDef] =
18441846
if (in.token == LBRACKET) typeParamClause(ownerKind) else Nil
18451847

1846-
/** ClsParamClauses ::= {ClsParamClause} [[nl] `(' `implicit' [`unused'] ClsParams `)']
1848+
/** ClsParamClauses ::= {ClsParamClause} [[nl] `(' [`unused'] `implicit' [`unused'] ClsParams `)']
18471849
* ClsParamClause ::= [nl] `(' [`unused'] [ClsParams] ')'
18481850
* ClsParams ::= ClsParam {`' ClsParam}
18491851
* ClsParam ::= {Annotation} [{Modifier} (`val' | `var') | `inline'] Param
1850-
* DefParamClauses ::= {DefParamClause} [[nl] `(' `implicit' [`unused'] DefParams `)']
1852+
* DefParamClauses ::= {DefParamClause} [[nl] `(' [`unused'] `implicit' DefParams `)']
18511853
* DefParamClause ::= [nl] `(' [`unused'] [DefParams] ')'
18521854
* DefParams ::= DefParam {`,' DefParam}
18531855
* DefParam ::= {Annotation} [`inline'] Param
@@ -1906,14 +1908,9 @@ object Parsers {
19061908
def paramClause(): List[ValDef] = inParens {
19071909
if (in.token == RPAREN) Nil
19081910
else {
1909-
if (in.token == IMPLICIT || in.token == UNUSED) {
1910-
if (in.token == IMPLICIT) {
1911-
implicitOffset = in.offset
1912-
imods = implicitMods(imods)
1913-
}
1914-
if (in.token == UNUSED)
1915-
imods = unusedMods(imods)
1916-
}
1911+
if (in.token == IMPLICIT || in.token == UNUSED)
1912+
imods = allFunctionMods(imods, () => implicitOffset = in.offset)
1913+
19171914
commaSeparated(param)
19181915
}
19191916
}
@@ -2505,9 +2502,7 @@ object Parsers {
25052502
else if (isDefIntro(localModifierTokens))
25062503
if (in.token == IMPLICIT || in.token == UNUSED) {
25072504
val start = in.offset
2508-
var imods = EmptyModifiers
2509-
if (in.token == IMPLICIT) imods = implicitMods(imods)
2510-
if (in.token == UNUSED) imods = unusedMods(imods)
2505+
var imods = allFunctionMods(EmptyModifiers)
25112506
if (isBindingIntro) stats += implicitClosure(start, Location.InBlock, imods)
25122507
else stats +++= localDef(start, imods)
25132508
} else {

tests/run/unused-23.check

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
lambda
1+
lambda1
2+
lambda2

tests/run/unused-23.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ object Test {
22

33
def main(args: Array[String]): Unit = {
44
fun { implicit unused (x: Int) =>
5-
println("lambda")
5+
println("lambda1")
66
"abc"
77
}
88

9+
fun2 { unused implicit (x: Int) =>
10+
println("lambda2")
11+
"abc"
12+
}
913
}
1014

1115
def fun(f: implicit unused Int => String): String = {
1216
f(35)
1317
}
18+
19+
def fun2(f: unused implicit Int => String): String = {
20+
f(36)
21+
}
1422
}

0 commit comments

Comments
 (0)