Skip to content

Commit 54b2606

Browse files
author
Adriaan Moors
committed
introduce -Ypatmat-debug (no new functionality)
the setting is actually a no-op until I can figure out how to convince the inliner to inline patmatDebug (/cc @magarciaEPFL)
1 parent 171a1d8 commit 54b2606

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ trait ScalaSettings extends AbsScalaSettings
195195
val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.")
196196
val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _)
197197
val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.")
198+
val Ypatmatdebug = BooleanSetting("-Ypatmat-debug", "Trace pattern matching translation.")
198199

199200
/** Groups of Settings.
200201
*/

src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
4747

4848
val phaseName: String = "patmat"
4949

50-
def patmatDebug(msg: String) = println(msg)
50+
// TODO: the inliner fails to inline the closures to patmatDebug
51+
// private val printPatmat = settings.Ypatmatdebug.value
52+
// @inline final def patmatDebug(s: => String) = if (printPatmat) println(s)
5153

5254
def newTransformer(unit: CompilationUnit): Transformer =
5355
if (opt.virtPatmat) new MatchTransformer(unit)
@@ -309,13 +311,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
309311
if (!extractor.isTyped) ErrorUtils.issueNormalTypeError(patTree, "Could not typecheck extractor call: "+ extractor)(context)
310312
// if (extractor.resultInMonad == ErrorType) throw new TypeError(pos, "Unsupported extractor type: "+ extractor.tpe)
311313

314+
// patmatDebug("translateExtractorPattern checking parameter type: "+ (patBinder, patBinder.info.widen, extractor.paramType, patBinder.info.widen <:< extractor.paramType))
315+
312316
// must use type `tp`, which is provided by extractor's result, not the type expected by binder,
313317
// as b.info may be based on a Typed type ascription, which has not been taken into account yet by the translation
314318
// (it will later result in a type test when `tp` is not a subtype of `b.info`)
315319
// TODO: can we simplify this, together with the Bound case?
316-
(extractor.subPatBinders, extractor.subPatTypes).zipped foreach { case (b, tp) => b setInfo tp } // patmatDebug("changing "+ b +" : "+ b.info +" -> "+ tp);
320+
(extractor.subPatBinders, extractor.subPatTypes).zipped foreach { case (b, tp) =>
321+
// patmatDebug("changing "+ b +" : "+ b.info +" -> "+ tp)
322+
b setInfo tp
323+
}
317324

318-
// patmatDebug("translateExtractorPattern checking parameter type: "+ (patBinder, patBinder.info.widen, extractor.paramType, patBinder.info.widen <:< extractor.paramType))
319325
// example check: List[Int] <:< ::[Int]
320326
// TODO: extractor.paramType may contain unbound type params (run/t2800, run/t3530)
321327
val (typeTestTreeMaker, patBinderOrCasted) =
@@ -1481,7 +1487,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
14811487
// reverse substitution that would otherwise replace a variable we already encountered by a new variable
14821488
// NOTE: this forgets the more precise type we have for these later variables, but that's probably okay
14831489
normalize >>= Substitution(boundTo map (_.symbol), boundFrom map (CODE.REF(_)))
1484-
// patmatDebug("normalize: "+ normalize)
1490+
// patmatDebug("normalize subst: "+ normalize)
14851491

14861492
val okSubst = Substitution(unboundFrom, unboundTo map (normalize(_))) // it's important substitution does not duplicate trees here -- it helps to keep hash consing simple, anyway
14871493
pointsToBound ++= ((okSubst.from, okSubst.to).zipped filter { (f, t) => pointsToBound exists (sym => t.exists(_.symbol == sym)) })._1
@@ -1494,7 +1500,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
14941500
// hashconsing trees (modulo value-equality)
14951501
def unique(t: Tree, tpOverride: Type = NoType): Tree =
14961502
trees find (a => a.correspondsStructure(t)(sameValue)) match {
1497-
case Some(orig) => orig // patmatDebug("unique: "+ (t eq orig, orig));
1503+
case Some(orig) =>
1504+
// patmatDebug("unique: "+ (t eq orig, orig))
1505+
orig
14981506
case _ =>
14991507
trees += t
15001508
if (tpOverride != NoType) t setType tpOverride
@@ -1565,13 +1573,13 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
15651573
}
15661574

15671575
def showTreeMakers(cases: List[List[TreeMaker]]) = {
1568-
patmatDebug("treeMakers:")
1569-
patmatDebug(alignAcrossRows(cases, ">>"))
1576+
// patmatDebug("treeMakers:")
1577+
// patmatDebug(alignAcrossRows(cases, ">>"))
15701578
}
15711579

15721580
def showTests(testss: List[List[Test]]) = {
1573-
patmatDebug("tests: ")
1574-
patmatDebug(alignAcrossRows(testss, "&"))
1581+
// patmatDebug("tests: ")
1582+
// patmatDebug(alignAcrossRows(testss, "&"))
15751583
}
15761584
}
15771585

@@ -1740,7 +1748,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
17401748
override def hashCode = a.hashCode ^ b.hashCode
17411749
}
17421750

1743-
// patmatDebug("vars: "+ vars)
1751+
// patmatDebug("removeVarEq vars: "+ vars)
17441752
vars.foreach { v =>
17451753
val excludedPair = new collection.mutable.HashSet[ExcludedPair]
17461754

@@ -1759,7 +1767,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
17591767
val todo = syms filterNot (b => (b.const == sym.const) || excludedPair(ExcludedPair(b.const, sym.const)))
17601768
val (excluded, notExcluded) = todo partition (b => sym.const.excludes(b.const))
17611769
val implied = notExcluded filter (b => sym.const.implies(b.const))
1762-
// patmatDebug("implications: "+ (sym.const, excluded, implied, syms))
1770+
// patmatDebug("eq axioms for: "+ sym.const)
1771+
// patmatDebug("excluded: "+ excluded)
1772+
// patmatDebug("implied: "+ implied)
17631773

17641774
// when this symbol is true, what must hold...
17651775
implied foreach (impliedSym => addAxiom(Or(Not(sym), impliedSym)))
@@ -1773,7 +1783,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
17731783
}
17741784

17751785
// patmatDebug("eqAxioms:\n"+ cnfString(eqFreePropToSolvable(eqAxioms)))
1776-
// patmatDebug("pure:\n"+ cnfString(eqFreePropToSolvable(pure)))
1786+
// patmatDebug("pure:"+ pure.map(p => cnfString(eqFreePropToSolvable(p))).mkString("\n"))
17771787

17781788
Statistics.stopTimer(patmatAnaVarEq, start)
17791789

@@ -1915,7 +1925,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
19151925
def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]=
19161926
if (recursionDepthAllowed == 0) models
19171927
else {
1918-
// patmatDebug("solving\n"+ cnfString(f))
1928+
// patmatDebug("find all models for\n"+ cnfString(f))
19191929
val model = findModelFor(f)
19201930
// if we found a solution, conjunct the formula with the model's negation and recurse
19211931
if (model ne NoModel) {
@@ -1952,7 +1962,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
19521962
def findModelFor(f: Formula): Model = {
19531963
@inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b
19541964

1955-
// patmatDebug("dpll\n"+ cnfString(f))
1965+
// patmatDebug("DPLL\n"+ cnfString(f))
19561966

19571967
val start = Statistics.startTimer(patmatAnaDPLL)
19581968

@@ -2081,7 +2091,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
20812091
// a literal constant becomes ConstantType(Constant(v)) when the type allows it (roughly, anyval + string + null)
20822092
// equality between variables: SingleType(x) (note that pattern variables cannot relate to each other -- it's always patternVar == nonPatternVar)
20832093
object Const {
2084-
def resetUniques() = {_nextTypeId = 0; _nextValueId = 0; uniques.clear() ; trees.clear() } // patmatDebug("RESET")
2094+
def resetUniques() = {_nextTypeId = 0; _nextValueId = 0; uniques.clear() ; trees.clear()}
20852095

20862096
private var _nextTypeId = 0
20872097
def nextTypeId = {_nextTypeId += 1; _nextTypeId}
@@ -2093,9 +2103,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
20932103
private[SymbolicMatchAnalysis] def unique(tp: Type, mkFresh: => Const): Const =
20942104
uniques.get(tp).getOrElse(
20952105
uniques.find {case (oldTp, oldC) => oldTp =:= tp} match {
2096-
case Some((_, c)) => c
2106+
case Some((_, c)) =>
2107+
// patmatDebug("unique const: "+ (tp, c))
2108+
c
20972109
case _ =>
20982110
val fresh = mkFresh
2111+
// patmatDebug("uniqued const: "+ (tp, fresh))
20992112
uniques(tp) = fresh
21002113
fresh
21012114
})
@@ -2111,7 +2124,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
21112124
if (!t.symbol.isStable) t.tpe.narrow
21122125
else trees find (a => a.correspondsStructure(t)(sameValue)) match {
21132126
case Some(orig) =>
2114-
// patmatDebug("unique: "+ (orig, orig.tpe))
2127+
// patmatDebug("unique tp for tree: "+ (orig, orig.tpe))
21152128
orig.tpe
21162129
case _ =>
21172130
// duplicate, don't mutate old tree (TODO: use a map tree -> type instead?)
@@ -2154,7 +2167,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
21542167
case (_: TypeConst, _: TypeConst) => !((tp <:< other.tp) || (other.tp <:< tp))
21552168
case _ => false
21562169
}
2157-
// if(r) patmatDebug("excludes : "+(this, other))
2170+
// if(r) patmatDebug("excludes : "+(this, this.tp, other, other.tp, (tp <:< other.tp), (tp <:< other.wideTp), (other.tp <:< tp), (other.tp <:< wideTp)))
21582171
// else patmatDebug("NOT excludes: "+(this, other))
21592172
r
21602173
}
@@ -2225,7 +2238,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
22252238
// for Selects, which are handled by the next case, the prefix of the select varies independently of the symbol (see pos/virtpatmat_unreach_select.scala)
22262239
singleType(tp.prefix, p.symbol)
22272240
case _ =>
2228-
// patmatDebug("unique type for "+(p, Const.uniqueTpForTree(p)))
22292241
Const.uniqueTpForTree(p)
22302242
}
22312243

@@ -2337,8 +2349,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
23372349
var reachable = true
23382350
var caseIndex = 0
23392351

2340-
// patmatDebug("reachability, vars:\n"+ ((propsCasesFail flatMap gatherVariables) map (_.describe) mkString ("\n")))
2341-
// patmatDebug("equality axioms:\n"+ cnfString(eqAxiomsCNF))
2352+
// patmatDebug("reachability, vars:\n"+ ((propsCasesFail flatMap gatherVariables) map (_.describe) mkString ("\n")))
2353+
// patmatDebug("equality axioms:\n"+ cnfString(eqAxiomsCNF))
23422354

23432355
// invariant (prefixRest.length == current.length) && (prefix.reverse ++ prefixRest == symbolicCasesFail)
23442356
// termination: prefixRest.length decreases by 1
@@ -2379,7 +2391,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
23792391
case UnitClass =>
23802392
Some(List(UnitClass.tpe))
23812393
case BooleanClass =>
2382-
// patmatDebug("enum bool "+ tp)
23832394
Some(List(ConstantType(Constant(true)), ConstantType(Constant(false))))
23842395
// TODO case _ if tp.isTupleType => // recurse into component types
23852396
case modSym: ModuleClassSymbol =>
@@ -2394,7 +2405,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
23942405
// symbols which are both sealed and abstract need not be covered themselves, because
23952406
// all of their children must be and they cannot otherwise be created.
23962407
filterNot (x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x)))
2397-
// patmatDebug("subclasses "+ (sym, subclasses))
2408+
// patmatDebug("enum sealed -- subclasses: "+ (sym, subclasses))
23982409

23992410
val tpApprox = typer.infer.approximateAbstracts(tp)
24002411
val pre = tpApprox.prefix
@@ -2467,15 +2478,15 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
24672478
makeCond(tm)(recurse)
24682479
}
24692480
case ExtractorTreeMaker(_, _, _, _) =>
2470-
// patmatDebug("backing off due to "+ tm)
2481+
// patmatDebug("backing off due to "+ tm)
24712482
backoff = true
24722483
makeCond(tm)(recurse)
24732484
case GuardTreeMaker(guard) =>
24742485
guard.tpe match {
24752486
case ConstantType(Constant(true)) => Top
24762487
case ConstantType(Constant(false)) => Havoc
24772488
case _ =>
2478-
// patmatDebug("can't statically interpret guard: "+(guard, guard.tpe))
2489+
// patmatDebug("can't statically interpret guard: "+(guard, guard.tpe))
24792490
backoff = true
24802491
Havoc
24812492
}
@@ -2510,12 +2521,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
25102521

25112522
// debug output:
25122523
// patmatDebug("analysing:")
2513-
// showTreeMakers(cases)
2514-
// showTests(tests)
2515-
//
2516-
// val vars = gatherVariables(matchFails)
2517-
// patmatDebug("\nvars:\n"+ (vars map (_.describe) mkString ("\n")))
2518-
//
2524+
showTreeMakers(cases)
2525+
showTests(tests)
2526+
2527+
// patmatDebug("\nvars:\n"+ (gatherVariables(matchFails) map (_.describe) mkString ("\n")))
25192528
// patmatDebug("\nmatchFails as CNF:\n"+ cnfString(propToSolvable(matchFails)))
25202529

25212530
try {
@@ -2627,7 +2636,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
26272636
def chop(path: Tree): List[Symbol] = path match {
26282637
case Ident(_) => List(path.symbol)
26292638
case Select(pre, name) => chop(pre) :+ path.symbol
2630-
case _ => // patmatDebug("don't know how to chop "+ path)
2639+
case _ =>
2640+
// patmatDebug("don't know how to chop "+ path)
26312641
Nil
26322642
}
26332643

@@ -2844,8 +2854,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
28442854
// replace original treemakers that are reused (as determined when computing collapsed),
28452855
// by ReusedCondTreeMakers
28462856
val reusedMakers = collapsed mapConserve (_ mapConserve reusedOrOrig)
2847-
// patmatDebug("after CSE:")
2848-
// showTreeMakers(reusedMakers)
2857+
// patmatDebug("after CSE:")
2858+
showTreeMakers(reusedMakers)
28492859
reusedMakers
28502860
}
28512861

@@ -3073,7 +3083,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
30733083
sequence(switchableAlts) map { switchableAlts =>
30743084
CaseDef(Alternative(switchableAlts), guard, body)
30753085
}
3076-
case _ => // patmatDebug("can't emit switch for "+ makers)
3086+
case _ =>
3087+
// patmatDebug("can't emit switch for "+ makers)
30773088
None //failure (can't translate pattern to a switch)
30783089
}
30793090
}

0 commit comments

Comments
 (0)