Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Add flag to disable withFilter pattern desugaring #1

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bincompat-forward.whitelist.conf
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ filter {
{
matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$2"
problemName=MissingMethodProblem
},
{
matchName="scala.reflect.runtime.Settings.ZirrefutableGeneratorPatterns"
problemName=MissingMethodProblem
}
]
}
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/CompilerCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
def usageMsg = createUsageMsg("where possible standard", shouldExplain = false, _.isStandard)
def xusageMsg = createUsageMsg("Possible advanced", shouldExplain = true, _.isAdvanced)
def yusageMsg = createUsageMsg("Possible private", shouldExplain = true, _.isPrivate)
def zusageMsg = createUsageMsg("Possible Typelevel", shouldExplain = true, _.isTypelevel)

/** For info settings, compiler should just print a message and quit. */
def shouldStopWithInfo = settings.isInfo
Expand All @@ -95,6 +96,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
else if (help) usageMsg + global.pluginOptionsHelp
else if (Xhelp) xusageMsg
else if (Yhelp) yusageMsg
else if (Zhelp) zusageMsg
else if (showPlugins) global.pluginDescriptions
else if (showPhases) global.phaseDescriptions + (
if (debug) "\n" + global.phaseFlagDescriptions else ""
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/settings/AbsSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ trait AbsSettings extends scala.reflect.internal.settings.AbsSettings {
*/
def isAdvanced = name match { case "-Y" => true ; case "-X" => false ; case _ => name startsWith "-X" }
def isPrivate = name match { case "-Y" => false ; case _ => name startsWith "-Y" }
def isTypelevel = name match { case "-Z" => false ; case _ => name startsWith "-Z" }
def isStandard = !isAdvanced && !isPrivate
def isForDebug = name endsWith "-debug" // by convention, i.e. -Ytyper-debug
def isDeprecated = deprecationMessage.isDefined
Expand Down
8 changes: 7 additions & 1 deletion src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ trait ScalaSettings extends AbsScalaSettings
def optimiseSettings = List[BooleanSetting](inline, inlineHandlers, Xcloselim, Xdce, YconstOptimization)

/** If any of these settings is enabled, the compiler should print a message and exit. */
def infoSettings = List[Setting](version, help, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph)
def infoSettings = List[Setting](version, help, Xhelp, Yhelp, Zhelp, showPlugins, showPhases, genPhaseGraph)

/** Any -multichoice:help? Nicer if any option could report that it had help to offer. */
private def multihelp = allSettings exists { case s: MultiChoiceSetting[_] => s.isHelping case _ => false }
Expand Down Expand Up @@ -237,6 +237,12 @@ trait ScalaSettings extends AbsScalaSettings

private def removalIn212 = "This flag is scheduled for removal in 2.12. If you have a case where you need this flag then please report a bug."

/**
* -Z Typelevel settings
*/
val Zhelp = BooleanSetting("-Z", "Print a synopsis of Typelevel options.")
val ZirrefutableGeneratorPatterns = BooleanSetting("-Zirrefutable-generator-patterns", "Treat patterns in for comprehensions as irrefutable. Do not add filter or withFilter calls.")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stupidly minor nitpick that probably isn't worth mentioning, but for comprehensions -> for-comprehensions


object YstatisticsPhases extends MultiChoiceEnumeration { val parser, typer, patmat, erasure, cleanup, jvm = Value }
val Ystatistics = {
val description = "Print compiler statistics for specific phases"
Expand Down
4 changes: 2 additions & 2 deletions src/reflect/scala/reflect/internal/TreeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ abstract class TreeGen {
body) setPos splitpos
case None =>
atPos(splitpos) {
mkVisitor(List(CaseDef(pat, EmptyTree, body)), checkExhaustive = false)
mkVisitor(List(CaseDef(pat, EmptyTree, body)), checkExhaustive = settings.ZirrefutableGeneratorPatterns)
}
}
}
Expand Down Expand Up @@ -768,7 +768,7 @@ abstract class TreeGen {
}

def mkCheckIfRefutable(pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator) =
if (treeInfo.isVarPatternDeep(pat)) rhs
if (treeInfo.isVarPatternDeep(pat) || settings.ZirrefutableGeneratorPatterns) rhs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a little bit too good to be true. Does the logic for detecting irrefutable patterns actually work and was just not applied properly?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larsrh: it appears this is not about detecting irrefutable patterns, it's about expecting them to be.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Blaisorblade exactly. Happy to clarify this if it's confusing somewhere.

else {
val cases = List(
CaseDef(pat.duplicate, EmptyTree, Literal(Constant(true))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ abstract class MutableSettings extends AbsSettings {
def maxClassfileName: IntSetting

def isScala211: Boolean

def ZirrefutableGeneratorPatterns: BooleanSetting
}

object MutableSettings {
Expand Down
2 changes: 2 additions & 0 deletions src/reflect/scala/reflect/runtime/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,6 @@ private[reflect] class Settings extends MutableSettings {
val Yrecursion = new IntSetting(0)
val maxClassfileName = new IntSetting(255)
def isScala211 = true

def ZirrefutableGeneratorPatterns = new BooleanSetting(false)
}
1 change: 1 addition & 0 deletions test/files/pos/Zirrefutable-generator-patterns.flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Zirrefutable-generator-patterns
11 changes: 11 additions & 0 deletions test/files/pos/Zirrefutable-generator-patterns.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
case class Foo[A](a: A) {
def map[B](f: A => B): Foo[B] = Foo(f(a))
def flatMap[B](f: A => Foo[B]): Foo[B] = Foo(f(a).a)
}

object Test {
for {
(a, b) <- Foo((1, 'd'))
(c, d, e) <- Foo((1, true, "three"))
} yield (a + c, e :+ b, !d)
}