diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 4bca0f196079..cf8b278818da 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1713,51 +1713,50 @@ self => case _ => def parseOther: Tree = { var t = postfixExpr() - if (in.token == EQUALS) { - t match { - case Ident(_) | Select(_, _) | Apply(_, _) => - t = atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) } - case _ => - } - } else if (in.token == COLON) { - t = stripParens(t) - val colonPos = in.skipToken() - if (in.token == USCORE) { - //todo: need to handle case where USCORE is a wildcard in a type - val uscorePos = in.skipToken() - if (isIdent && in.name == nme.STAR) { - in.nextToken() - t = atPos(t.pos.start, colonPos) { - Typed(t, atPos(uscorePos) { Ident(tpnme.WILDCARD_STAR) }) - } - } else { - syntaxErrorOrIncomplete("`*` expected", skipIt = true) + in.token match { + case EQUALS => + t match { + case Ident(_) | Select(_, _) | Apply(_, _) => + t = atPos(t.pos.start, in.skipToken()) { gen.mkAssign(t, expr()) } + case _ => } - } else if (isAnnotation) { - t = annotations(skipNewLines = false).foldLeft(t)(makeAnnotated) - } else { - t = atPos(t.pos.start, colonPos) { - val tpt = typeOrInfixType(location) - // for placeholder syntax `(_: Int) + 1`; function literal `(_: Int) => 42` uses `t` below - if (isWildcard(t)) - (placeholderParams: @unchecked) match { - case (vd @ ValDef(mods, name, _, _)) :: rest => - placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.duplicate, EmptyTree) :: rest + case COLON => + t = stripParens(t) + val colonPos = in.skipToken() + if (in.token == USCORE) { + //todo: need to handle case where USCORE is a wildcard in a type + val uscorePos = in.skipToken() + if (isIdent && in.name == nme.STAR) { + in.nextToken() + t = atPos(t.pos.start, colonPos) { + Typed(t, atPos(uscorePos) { Ident(tpnme.WILDCARD_STAR) }) } - // this does not correspond to syntax, but is necessary to accept closures. See below & convertToParam. - Typed(t, tpt) + } + else syntaxErrorOrIncomplete("`*` expected", skipIt = true) } - } - } else if (in.token == MATCH) { - t = atPos(t.pos.start, in.skipToken())(Match(stripParens(t), inBracesOrNil(caseClauses()))) + else if (isAnnotation) + t = annotations(skipNewLines = false).foldLeft(t)(makeAnnotated) + else + t = atPos(t.pos.start, colonPos) { + val tpt = typeOrInfixType(location) + // for placeholder syntax `(_: Int) + 1`; function literal `(_: Int) => 42` uses `t` below + if (isWildcard(t)) + (placeholderParams: @unchecked) match { + case (vd @ ValDef(mods, name, _, _)) :: rest => + placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.duplicate, EmptyTree) :: rest + } + // this does not correspond to syntax, but is necessary to accept closures. See below & convertToParam. + Typed(t, tpt) + } + case MATCH => + t = atPos(t.pos.start, in.skipToken())(Match(stripParens(t), inBracesOrNil(caseClauses()))) + case _ => } // disambiguate between self types "x: Int =>" and orphan function literals "(x: Int) => ???" // "(this: Int) =>" is parsed as an erroneous function literal but emits special guidance on // what's probably intended. def lhsIsTypedParamList() = t match { - case Parens(List(Typed(This(_), _))) => - reporter.error(t.pos, "self-type annotation may not be in parentheses") - false + case Parens(List(Typed(This(_), _))) => reporter.error(t.pos, "self-type annotation may not be in parentheses"); false case Parens(xs) => xs.forall(isTypedParam) case _ => false } @@ -1781,7 +1780,7 @@ self => def implicitClosure(start: Offset, location: Location): Tree = { val param0 = convertToParam { atPos(in.offset) { - val p = if (in.token == USCORE) freshPlaceholder() else Ident(ident()) + val p = stripParens(postfixExpr()) //if (in.token == USCORE) freshPlaceholder() else Ident(ident()) if (in.token == COLON) { in.nextToken() Typed(p, typeOrInfixType(location)) diff --git a/test/files/pos/t3672.scala b/test/files/pos/t3672.scala index 25cecd2263e2..2c17a17ff8b1 100644 --- a/test/files/pos/t3672.scala +++ b/test/files/pos/t3672.scala @@ -13,10 +13,10 @@ object Test { foo(x => x + 1) foo(implicit x => x + 1) foo((x: Int) => x + 1) - //foo(implicit (x: Int) => x + 1) // scala 3 + foo(implicit (x: Int) => x + 1) // scala 3 foo(_ => 42) foo(implicit _ => implicitly[Int] + 1) // scala 2 deficit foo((_: Int) => 42) - //foo(implicit (_: Int) => implicitly[Int] + 1) // scala 3 + foo(implicit (_: Int) => implicitly[Int] + 1) // scala 3 } }