Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defer infer bool param #10761

Open
wants to merge 1 commit into
base: 2.13.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -1624,8 +1624,8 @@ self =>
accept(RPAREN)
if (isWildcard(r))
placeholderParams.head.tpt match {
case tpt @ TypeTree() => tpt.setType(definitions.BooleanTpe)
case _ =>
case TypeTree() => placeholderParams.head.updateAttachment(BooleanParameterType)
case _ =>
}
r
} else {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Expand Up @@ -3165,6 +3165,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// because I don't see how we could recurse after the `setError(vparam)` call below
if (vparam.tpt.isEmpty) {
if (isFullyDefined(argpt)) vparam.tpt setType argpt
else if (vparam.hasAttachment[BooleanParameterType.type]) vparam.tpt.setType(definitions.BooleanTpe) // `if (_)`
else paramsMissingType += vparam

if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus
Expand Down
3 changes: 3 additions & 0 deletions src/reflect/scala/reflect/internal/StdAttachments.scala
Expand Up @@ -176,4 +176,7 @@ trait StdAttachments {

/** Not a named arg in an application. Used for suspicious literal booleans. */
case object UnnamedArg extends PlainAttachment

/** Anonymous parameter of `if (_)` may be inferred as Boolean. */
case object BooleanParameterType extends PlainAttachment
}
1 change: 1 addition & 0 deletions src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
Expand Up @@ -88,6 +88,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.PermittedSubclassSymbols
this.NamePos
this.UnnamedArg
this.BooleanParameterType
this.noPrint
this.typeDebug
// inaccessible: this.posAssigner
Expand Down
20 changes: 20 additions & 0 deletions test/files/pos/ifunc.scala
Expand Up @@ -8,3 +8,23 @@ trait T {

val g = (b: () => Boolean) => while (b()) println() // less weird
}

import language.implicitConversions

class Setting {
def tap(f: this.type => Unit): this.type = { f(this); this }
}
class BooleanSetting extends Setting {
def tap2(f: BooleanSetting => Unit): BooleanSetting = { f(this); this }
}
object BooleanSetting {
implicit def cv(s: BooleanSetting): Boolean = true
}

object Test extends App {
val setting = new Setting().tap(println)
val boolean = new BooleanSetting().tap(if (_) println("yes"))
val bool1 = new BooleanSetting().tap(s => if (s) println("yes"))
val bool2a = new BooleanSetting().tap2(s => if (s) println("yes"))
val bool2b = new BooleanSetting().tap2(if (_) println("yes"))
}