diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 43 | ||||
-rw-r--r-- | test/files/pos/implicits.scala | 11 |
2 files changed, 38 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index c4c26e54b3..a8118242df 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1058,13 +1058,7 @@ self => Throw(expr()) } case IMPLICIT => - val start = in.skipToken() - val param0 = convertToParam(atPos(in.offset)(Ident(ident()))) - val param = treeCopy.ValDef(param0, param0.mods | Flags.IMPLICIT, param0.name, param0.tpt, param0.rhs) - atPos(start, in.offset) { - accept(ARROW) - Function(List(param), if (location != InBlock) expr() else block()) - } + implicitClosure(in.skipToken(), location) case _ => var t = postfixExpr() if (in.token == EQUALS) { @@ -1124,6 +1118,17 @@ self => stripParens(t) } + /** Expr ::= implicit Id => Expr + */ + def implicitClosure(start: Int, location: Int): Tree = { + val param0 = convertToParam(atPos(in.offset)(Ident(ident()))) + val param = treeCopy.ValDef(param0, param0.mods | Flags.IMPLICIT, param0.name, param0.tpt, param0.rhs) + atPos(start, in.offset) { + accept(ARROW) + Function(List(param), if (location != InBlock) expr() else block()) + } + } + /** PostfixExpr ::= InfixExpr [Id [nl]] * InfixExpr ::= PrefixExpr * | InfixExpr Id [nl] InfixExpr @@ -2560,12 +2565,15 @@ self => } */ - def localDef : List[Tree] = { + def localDef(implicitMod: Int): List[Tree] = { val annots = annotations(true, false) val pos = in.offset - val mods = localModifiers() withAnnotations annots - if (!(mods hasFlag ~(Flags.IMPLICIT | Flags.LAZY))) defOrDcl(pos, mods) - else List(tmplDef(pos, mods)) + val mods = (localModifiers() | implicitMod) withAnnotations annots + val defs = + if (!(mods hasFlag ~(Flags.IMPLICIT | Flags.LAZY))) defOrDcl(pos, mods) + else List(tmplDef(pos, mods)) + if (in.token != RBRACE && in.token != CASE) defs + else defs ::: List(Literal(()).setPos(o2p(in.offset))) } /** BlockStatSeq ::= { BlockStat semi } [ResultExpr] @@ -2584,11 +2592,14 @@ self => stats += statement(InBlock) if (in.token != RBRACE && in.token != CASE) acceptStatSep() } else if (isDefIntro || isLocalModifier || in.token == AT) { - stats ++= localDef - if (in.token == RBRACE || in.token == CASE) { - //syntaxError("block must end in result expression, not in definition", false) - stats += Literal(()).setPos(o2p(in.offset)) - } else acceptStatSep() + if (in.token == IMPLICIT) { + val start = in.skipToken() + if (isIdent) stats += implicitClosure(start, InBlock) + else stats ++= localDef(Flags.IMPLICIT) + } else { + stats ++= localDef(0) + } + if (in.token != RBRACE && in.token != CASE) acceptStatSep() } else if (isStatSep) { in.nextToken() } else { diff --git a/test/files/pos/implicits.scala b/test/files/pos/implicits.scala index 4979835e21..14241a2655 100644 --- a/test/files/pos/implicits.scala +++ b/test/files/pos/implicits.scala @@ -12,6 +12,17 @@ class C1435 { } } +// #1492 +class C1492 { + + class X + + def foo(x: X => X) {} + + foo ( implicit x => implicitly[X] ) + foo { implicit x => implicitly[X] } +} + // #1579 object Test1579 { class Column |