@@ -477,7 +477,7 @@ self =>
477477
478478/* --------------- PLACEHOLDERS -------------------------------------------*/
479479
480- /** Theimplicit parameters introduced by `_` in the current expression.
480+ /** The parameters introduced by `_` "placeholder syntax" in the current expression.
481481 * Parameters appear in reverse order.
482482*/
483483var placeholderParams : List [ValDef ]= Nil
@@ -529,8 +529,8 @@ self =>
529529
530530@ tailrec
531531final def isWildcard (t :Tree ): Boolean = tmatch {
532- case Ident (name1)=> ! placeholderParams.isEmpty&& name1== placeholderParams.head.name
533- case Typed (t1, _)=> isWildcard(t1)
532+ case Ident (name1)=> ! placeholderParams.isEmpty&& name1== placeholderParams.head.name
533+ case Typed (t1, _)=> isWildcard(t1)
534534case Annotated (t1, _)=> isWildcard(t1)
535535case _=> false
536536 }
@@ -784,7 +784,7 @@ self =>
784784/** Convert tree to formal parameter.*/
785785def convertToParam (tree :Tree ): ValDef = atPos(tree.pos) {
786786def removeAsPlaceholder (name :Name ): Unit = {
787- placeholderParams= placeholderParams filter (_.name!= name)
787+ placeholderParams= placeholderParams. filter(_.name!= name)
788788 }
789789def errorParam = makeParam(nme.ERROR , errorTypeTree setPos o2p(tree.pos.end))
790790def propagateNoWarnAttachment (from :Tree ,to :ValDef ): to.type =
@@ -1711,54 +1711,52 @@ self =>
17111711case IMPLICIT =>
17121712 implicitClosure(in.skipToken(), location)
17131713case _=>
1714- def parseOther = {
1714+ def parseOther : Tree = {
17151715var t = postfixExpr()
1716- if (in.token== EQUALS ) {
1717- tmatch {
1718- case Ident (_)| Select (_, _)| Apply (_, _)=>
1719- t= atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) }
1720- case _=>
1721- }
1722- }else if (in.token== COLON ) {
1723- t= stripParens(t)
1724- val colonPos = in.skipToken()
1725- if (in.token== USCORE ) {
1726- // todo: need to handle case where USCORE is a wildcard in a type
1727- val uscorePos = 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+ case EQUALS =>
1718+ tmatch {
1719+ case Ident (_)| Select (_, _)| Apply (_, _)=>
1720+ t= atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) }
1721+ case _=>
17351722 }
1736- }else if (isAnnotation) {
1737- t= annotations(skipNewLines= false ).foldLeft(t)(makeAnnotated)
1738- }else {
1739- t= atPos(t.pos.start, colonPos) {
1740- val tpt = 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+ case COLON =>
1724+ t= stripParens(t)
1725+ val colonPos = in.skipToken()
1726+ if (in.token== USCORE ) {
1727+ // todo: need to handle case where USCORE is a wildcard in a type
1728+ val uscorePos = 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- }else if (in.token== MATCH ) {
1752- t= atPos(t.pos.start, in.skipToken())(Match (stripParens(t), inBracesOrNil(caseClauses())))
1737+ else if (isAnnotation)
1738+ t= annotations(skipNewLines= false ).foldLeft(t)(makeAnnotated)
1739+ else
1740+ t= atPos(t.pos.start, colonPos) {
1741+ val tpt = 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+ case MATCH =>
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.
17571758def lhsIsTypedParamList ()= tmatch {
1758- case Parens (List (Typed (This (_), _)))=> {
1759- reporter.error(t.pos," self-type annotation may not be in parentheses" )
1760- false
1761- }
1759+ case Parens (List (Typed (This (_), _)))=> reporter.error(t.pos," self-type annotation may not be in parentheses" );false
17621760case Parens (xs)=> xs.forall(isTypedParam)
17631761case _=> false
17641762 }
@@ -1779,15 +1777,15 @@ self =>
17791777 * Expr ::= implicit Id `=>` Expr
17801778 * }}}
17811779*/
1782-
17831780def implicitClosure (start :Offset ,location :Location ): Tree = {
17841781val param0 = convertToParam {
17851782 atPos(in.offset) {
1786- Ident (ident ())match {
1787- case expr if in.token== COLON =>
1788- in.nextToken() ; Typed (expr, typeOrInfixType(location) )
1789- case expr => expr
1783+ val p = 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 }
17931791val param = copyValDef(param0)(mods= param0.mods| Flags .IMPLICIT )
@@ -3507,7 +3505,7 @@ self =>
35073505else if (isDefIntro|| isLocalModifier|| isAnnotation) {
35083506if (in.token== IMPLICIT ) {
35093507val start = in.skipToken()
3510- if (isIdent) stats+= implicitClosure(start,InBlock )
3508+ if (isIdent|| in.token == USCORE ) stats+= implicitClosure(start,InBlock )
35113509else stats++= localDef(Flags .IMPLICIT )
35123510 }else {
35133511 stats++= localDef(0 )