Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd50b823

Browse files
committed
Accept implicit _, implicit (x: Int) in lambda
1 parent15538c7 commitd50b823

File tree

4 files changed

+71
-55
lines changed

4 files changed

+71
-55
lines changed

‎spec/06-expressions.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,8 +1182,8 @@ for `try { try { ´b´ } catch ´e_1´ } finally ´e_2´`.
11821182
##Anonymous Functions
11831183

11841184
```ebnf
1185-
Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
1186-
ResultExpr ::= (Bindings |([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
1185+
Expr ::= (Bindings | [‘implicit’](id | ‘_’)) ‘=>’ Expr
1186+
ResultExpr ::= (Bindings | [‘implicit’](id | ‘_’)[‘:’ CompoundType]) ‘=>’ Block
11871187
Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
11881188
Binding ::= (id | ‘_’) [‘:’ Type]
11891189
```

‎spec/13-syntax-summary.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ grammar:
144144
| ‘:’ Annotation {Annotation}
145145
| ‘:’ ‘_’ ‘*’
146146
147-
Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
147+
Expr ::= (Bindings | [‘implicit’](id | ‘_’)) ‘=>’ Expr
148148
| Expr1
149149
Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr]
150150
| ‘while’ ‘(’ Expr ‘)’ {nl} Expr
@@ -188,7 +188,7 @@ grammar:
188188
| Expr1
189189
|
190190
ResultExpr ::= Expr1
191-
| (Bindings |([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
191+
| (Bindings | [‘implicit’](id | ‘_’)[‘:’ CompoundType]) ‘=>’ Block
192192
193193
Enumerators ::= Generator {semi Generator}
194194
Generator ::= [‘case’] Pattern1 ‘<-’ Expr {[semi] Guard | semi Pattern1 ‘=’ Expr}

‎src/compiler/scala/tools/nsc/ast/parser/Parsers.scala‎

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ self =>
477477

478478
/* --------------- PLACEHOLDERS -------------------------------------------*/
479479

480-
/** Theimplicitparameters introduced by `_` in the current expression.
480+
/** The parameters introduced by `_` "placeholder syntax" in the current expression.
481481
* Parameters appear in reverse order.
482482
*/
483483
varplaceholderParams:List[ValDef]=Nil
@@ -529,8 +529,8 @@ self =>
529529

530530
@tailrec
531531
finaldefisWildcard(t:Tree):Boolean= tmatch {
532-
caseIdent(name1)=>!placeholderParams.isEmpty&& name1== placeholderParams.head.name
533-
caseTyped(t1, _)=> isWildcard(t1)
532+
caseIdent(name1)=>!placeholderParams.isEmpty&& name1== placeholderParams.head.name
533+
caseTyped(t1, _)=> isWildcard(t1)
534534
caseAnnotated(t1, _)=> isWildcard(t1)
535535
case _=>false
536536
}
@@ -784,7 +784,7 @@ self =>
784784
/** Convert tree to formal parameter.*/
785785
defconvertToParam(tree:Tree):ValDef= atPos(tree.pos) {
786786
defremoveAsPlaceholder(name:Name):Unit= {
787-
placeholderParams= placeholderParamsfilter(_.name!= name)
787+
placeholderParams= placeholderParams.filter(_.name!= name)
788788
}
789789
deferrorParam= makeParam(nme.ERROR, errorTypeTree setPos o2p(tree.pos.end))
790790
defpropagateNoWarnAttachment(from:Tree,to:ValDef): to.type=
@@ -1711,54 +1711,52 @@ self =>
17111711
caseIMPLICIT=>
17121712
implicitClosure(in.skipToken(), location)
17131713
case _=>
1714-
defparseOther= {
1714+
defparseOther:Tree= {
17151715
vart= postfixExpr()
1716-
if (in.token==EQUALS) {
1717-
tmatch {
1718-
caseIdent(_)|Select(_, _)|Apply(_, _)=>
1719-
t= atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) }
1720-
case _=>
1721-
}
1722-
}elseif (in.token==COLON) {
1723-
t= stripParens(t)
1724-
valcolonPos= in.skipToken()
1725-
if (in.token==USCORE) {
1726-
//todo: need to handle case where USCORE is a wildcard in a type
1727-
valuscorePos= in.skipToken()
1728-
if (isIdent&& in.name== nme.STAR) {
1729-
in.nextToken()
1730-
t= atPos(t.pos.start, colonPos) {
1731-
Typed(t, atPos(uscorePos) {Ident(tpnme.WILDCARD_STAR) })
1732-
}
1733-
}else {
1734-
syntaxErrorOrIncomplete("`*` expected", skipIt=true)
1716+
in.tokenmatch {
1717+
caseEQUALS=>
1718+
tmatch {
1719+
caseIdent(_)|Select(_, _)|Apply(_, _)=>
1720+
t= atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) }
1721+
case _=>
17351722
}
1736-
}elseif (isAnnotation) {
1737-
t= annotations(skipNewLines=false).foldLeft(t)(makeAnnotated)
1738-
}else {
1739-
t= atPos(t.pos.start, colonPos) {
1740-
valtpt= typeOrInfixType(location)
1741-
if (isWildcard(t))
1742-
(placeholderParams:@unchecked)match {
1743-
case (vd@ValDef(mods, name, _, _)):: rest=>
1744-
placeholderParams= treeCopy.ValDef(vd, mods, name, tpt.duplicate,EmptyTree):: rest
1723+
caseCOLON=>
1724+
t= stripParens(t)
1725+
valcolonPos= in.skipToken()
1726+
if (in.token==USCORE) {
1727+
//todo: need to handle case where USCORE is a wildcard in a type
1728+
valuscorePos= in.skipToken()
1729+
if (isIdent&& in.name== nme.STAR) {
1730+
in.nextToken()
1731+
t= atPos(t.pos.start, colonPos) {
1732+
Typed(t, atPos(uscorePos) {Ident(tpnme.WILDCARD_STAR) })
17451733
}
1746-
// this does not correspond to syntax, but is necessary to
1747-
// accept closures. We might restrict closures to be between {...} only.
1748-
Typed(t, tpt)
1734+
}
1735+
else syntaxErrorOrIncomplete("`*` expected", skipIt=true)
17491736
}
1750-
}
1751-
}elseif (in.token==MATCH) {
1752-
t= atPos(t.pos.start, in.skipToken())(Match(stripParens(t), inBracesOrNil(caseClauses())))
1737+
elseif (isAnnotation)
1738+
t= annotations(skipNewLines=false).foldLeft(t)(makeAnnotated)
1739+
else
1740+
t= atPos(t.pos.start, colonPos) {
1741+
valtpt= typeOrInfixType(location)
1742+
// for placeholder syntax `(_: Int) + 1`; function literal `(_: Int) => 42` uses `t` below
1743+
if (isWildcard(t))
1744+
(placeholderParams:@unchecked)match {
1745+
case (vd@ValDef(mods, name, _, _)):: rest=>
1746+
placeholderParams= treeCopy.ValDef(vd, mods, name, tpt.duplicate,EmptyTree):: rest
1747+
}
1748+
// this does not correspond to syntax, but is necessary to accept closures. See below & convertToParam.
1749+
Typed(t, tpt)
1750+
}
1751+
caseMATCH=>
1752+
t= atPos(t.pos.start, in.skipToken())(Match(stripParens(t), inBracesOrNil(caseClauses())))
1753+
case _=>
17531754
}
17541755
// disambiguate between self types "x: Int =>" and orphan function literals "(x: Int) => ???"
17551756
// "(this: Int) =>" is parsed as an erroneous function literal but emits special guidance on
17561757
// what's probably intended.
17571758
deflhsIsTypedParamList()= tmatch {
1758-
caseParens(List(Typed(This(_), _)))=> {
1759-
reporter.error(t.pos,"self-type annotation may not be in parentheses")
1760-
false
1761-
}
1759+
caseParens(List(Typed(This(_), _)))=> reporter.error(t.pos,"self-type annotation may not be in parentheses");false
17621760
caseParens(xs)=> xs.forall(isTypedParam)
17631761
case _=>false
17641762
}
@@ -1779,15 +1777,15 @@ self =>
17791777
* Expr ::= implicit Id `=>` Expr
17801778
* }}}
17811779
*/
1782-
17831780
defimplicitClosure(start:Offset,location:Location):Tree= {
17841781
valparam0= convertToParam {
17851782
atPos(in.offset) {
1786-
Ident(ident())match {
1787-
case exprif in.token==COLON=>
1788-
in.nextToken() ;Typed(expr, typeOrInfixType(location))
1789-
case expr=> expr
1783+
valp= stripParens(postfixExpr())//if (in.token == USCORE) freshPlaceholder() else Ident(ident())
1784+
if(in.token==COLON) {
1785+
in.nextToken()
1786+
Typed(p, typeOrInfixType(location))
17901787
}
1788+
else p
17911789
}
17921790
}
17931791
valparam= copyValDef(param0)(mods= param0.mods|Flags.IMPLICIT)
@@ -3507,7 +3505,7 @@ self =>
35073505
elseif (isDefIntro|| isLocalModifier|| isAnnotation) {
35083506
if (in.token==IMPLICIT) {
35093507
valstart= in.skipToken()
3510-
if (isIdent) stats+= implicitClosure(start,InBlock)
3508+
if (isIdent|| in.token==USCORE) stats+= implicitClosure(start,InBlock)
35113509
else stats++= localDef(Flags.IMPLICIT)
35123510
}else {
35133511
stats++= localDef(0)

‎test/files/pos/t3672.scala‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
objectTest {
2-
deffoo(f:Int=>Int)= () ; foo {implicitx :Int=> x+1 }
3-
defbar(f:Int=>Int)= () ; foo {x :Int=> x+1 }
2+
deffoo(f:Int=>Int)= ()
3+
deftest():Unit= {
4+
foo { x=> x+1 }
5+
foo {implicit x=> x+1 }
6+
foo {x:Int=> x+1 }
7+
foo {implicitx:Int=> x+1 }
8+
foo { _=>42 }
9+
foo {implicit _=> implicitly[Int]+1 }// scala 2 deficit
10+
foo {_:Int=>42 }
11+
foo {implicit_:Int=> implicitly[Int]+1 }// scala 2 deficit
12+
13+
foo(x=> x+1)
14+
foo(implicit x=> x+1)
15+
foo((x:Int)=> x+1)
16+
foo(implicit (x:Int)=> x+1)// scala 3
17+
foo(_=>42)
18+
foo(implicit _=> implicitly[Int]+1)// scala 2 deficit
19+
foo((_:Int)=>42)
20+
foo(implicit (_:Int)=> implicitly[Int]+1)// scala 3
21+
}
422
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp