Skip to content

Commit

Permalink
Accept implicit (x: Int)
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Feb 27, 2023
1 parent 22ef540 commit 4bbcc9b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 40 deletions.
75 changes: 37 additions & 38 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -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
}
Expand All @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions test/files/pos/t3672.scala
Expand Up @@ -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
}
}

0 comments on commit 4bbcc9b

Please sign in to comment.