Skip to content

Commit 57c7deb

Browse files
committed
Merge branch 'develop'
2 parents 0b3b12f + 631f60e commit 57c7deb

File tree

135 files changed

+962
-549
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+962
-549
lines changed

src/compiler/scala/reflect/internal/TreePrinters.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
103103
}
104104
}
105105

106+
def printLabelParams(ps: List[Ident]) {
107+
print("(")
108+
printSeq(ps){printLabelParam}{print(", ")}
109+
print(")")
110+
}
111+
112+
def printLabelParam(p: Ident) {
113+
print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe)
114+
}
115+
106116
def printValueParams(ts: List[ValDef]) {
107117
print("(")
108118
if (!ts.isEmpty) printFlags(ts.head.mods.flags & IMPLICIT, "")
@@ -219,7 +229,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
219229
}
220230

221231
case LabelDef(name, params, rhs) =>
222-
print(symName(tree, name)); printRow(params, "(", ",", ")"); printBlock(rhs)
232+
print(symName(tree, name)); printLabelParams(params); printBlock(rhs)
223233

224234
case Import(expr, selectors) =>
225235
// Is this selector remapping a name (i.e, {name1 => name2})

src/compiler/scala/reflect/internal/Trees.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
144144
* less than the whole tree.
145145
*/
146146
def summaryString: String = tree match {
147-
case Select(qual, name) => qual.summaryString + "." + name.decode
148-
case Ident(name) => name.longString
149147
case Literal(const) => "Literal(" + const + ")"
150-
case t: DefTree => t.shortClass + " `" + t.name.decode + "`"
151-
case t: RefTree => t.shortClass + " `" + t.name.longString + "`"
148+
case Select(qual, name) => qual.summaryString + "." + name.decode
149+
case t: NameTree => t.name.longString
152150
case t =>
153151
t.shortClass + (
154152
if (t.symbol != null && t.symbol != NoSymbol) " " + t.symbol

src/compiler/scala/reflect/internal/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ trait Types extends api.Types { self: SymbolTable =>
9797
*/
9898
private final val propagateParameterBoundsToTypeVars = sys.props contains "scalac.debug.prop-constraints"
9999

100-
protected val enableTypeVarExperimentals = settings.Xexperimental.value || settings.YvirtPatmat.value
100+
protected val enableTypeVarExperimentals = settings.Xexperimental.value || !settings.XoldPatmat.value
101101

102102
/** Empty immutable maps to avoid allocations. */
103103
private val emptySymMap = immutable.Map[Symbol, Symbol]()

src/compiler/scala/reflect/internal/settings/MutableSettings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ abstract class MutableSettings extends AbsSettings {
4343
def Yrecursion: IntSetting
4444
def maxClassfileName: IntSetting
4545
def Xexperimental: BooleanSetting
46-
def YvirtPatmat: BooleanSetting
46+
def XoldPatmat: BooleanSetting
4747
}

src/compiler/scala/reflect/runtime/Settings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ class Settings extends internal.settings.MutableSettings {
3434
val maxClassfileName = new IntSetting(255)
3535
val Xexperimental = new BooleanSetting(false)
3636
val deepCloning = new BooleanSetting (false)
37-
val YvirtPatmat = new BooleanSetting(false)
37+
val XoldPatmat = new BooleanSetting(false)
3838
}

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S
347347
override protected val etaExpandKeepsStar = settings.etaExpandKeepsStar.value
348348
// Here comes another one...
349349
override protected val enableTypeVarExperimentals = (
350-
settings.Xexperimental.value || settings.YvirtPatmat.value
350+
settings.Xexperimental.value || !settings.XoldPatmat.value
351351
)
352352

353353
// True if -Xscript has been set, indicating a script run.

src/compiler/scala/tools/nsc/ast/TreeGen.scala

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,18 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
7272
Annotated(Ident(nme.synthSwitch), expr)
7373
}
7474

75-
// must be kept in synch with the codegen in PatMatVirtualiser
76-
object VirtualCaseDef {
77-
def unapply(b: Block): Option[(Assign, Tree, Tree)] = b match {
78-
case Block(List(assign@Assign(keepGoingLhs, falseLit), matchRes), zero) => Some((assign, matchRes, zero)) // TODO: check tree annotation
79-
case _ => None
80-
}
81-
}
82-
8375
def hasSynthCaseSymbol(t: Tree) = (t.symbol ne null) && (t.symbol hasFlag (CASE | SYNTHETIC))
8476

8577
// TODO: would be so much nicer if we would know during match-translation (i.e., type checking)
8678
// whether we should emit missingCase-style apply (and isDefinedAt), instead of transforming trees post-factum
8779
class MatchMatcher {
8880
def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = unknownTree(orig)
8981
def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = unknownTree(orig)
90-
def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = unknownTree(orig)
82+
def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree): Tree = unknownTree(orig)
9183

92-
def apply(matchExpr: Tree): Tree = (matchExpr: @unchecked) match {
84+
def genVirtualizedMatch(prologue: List[Tree], cases: List[Tree], matchEndDef: Tree): Tree = Block(prologue ++ cases, matchEndDef)
85+
86+
def apply(matchExpr: Tree): Tree = matchExpr match {
9387
// old-style match or virtpatmat switch
9488
case Match(selector, cases) => // println("simple match: "+ (selector, cases) + "for:\n"+ matchExpr )
9589
caseMatch(matchExpr, selector, cases, identity)
@@ -100,11 +94,15 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
10094
case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), List(scrut)), List(matcher)) if opt.virtPatmat => // println("virt match: "+ (tgt, targs, scrut, matcher) + "for:\n"+ matchExpr )
10195
caseVirtualizedMatch(matchExpr, tgt, targs, scrut, matcher)
10296
// optimized version of virtpatmat
103-
case Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue) if opt.virtPatmat => // TODO: check tree annotation // println("virtopt match: "+ (zero, x, matchRes, keepGoing, stats) + "for:\n"+ matchExpr )
104-
caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, identity)
97+
case Block(stats, matchEndDef) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) =>
98+
// the assumption is once we encounter a case, the remainder of the block will consist of cases
99+
// the prologue may be empty, usually it is the valdef that stores the scrut
100+
val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef])
101+
caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, identity)
105102
// optimized version of virtpatmat
106-
case Block(outerStats, orig@Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue)) if opt.virtPatmat => // TODO: check tree annotation // println("virt opt block match: "+ (zero, x, matchRes, keepGoing, stats, outerStats) + "for:\n"+ matchExpr )
107-
caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, m => copyBlock(matchExpr, outerStats, m))
103+
case Block(outerStats, orig@Block(stats, matchEndDef)) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) =>
104+
val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef])
105+
caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, m => copyBlock(matchExpr, outerStats, m))
108106
case other =>
109107
unknownTree(other)
110108
}
@@ -120,35 +118,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
120118
}
121119
}
122120

123-
def withDefaultCase(matchExpr: Tree, defaultAction: Tree/*scrutinee*/ => Tree): Tree = {
124-
object withDefaultTransformer extends MatchMatcher {
125-
override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = {
126-
val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
127-
if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) orig
128-
else {
129-
val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(selector.duplicate))
130-
wrap(Match(selector, casesNoSynthCatchAll :+ defaultCase))
131-
}
132-
}
133-
override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { import CODE._
134-
((matcher APPLY (scrut)) DOT nme.getOrElse) APPLY (defaultAction(scrut.duplicate)) // TODO: pass targs
135-
}
136-
override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = { import CODE._
137-
wrap(Block(
138-
zero ::
139-
x ::
140-
matchRes ::
141-
keepGoing ::
142-
stats,
143-
// replace `if (keepGoing) throw new MatchError(...) else matchRes` by `if (keepGoing) ${defaultAction(`x`)} else matchRes`
144-
(IF (REF(keepGoing.symbol)) THEN defaultAction(x.rhs.duplicate) ELSE REF(matchRes.symbol))
145-
))
146-
}
147-
}
148-
withDefaultTransformer(matchExpr)
149-
}
150-
151-
152121
def mkCached(cvar: Symbol, expr: Tree): Tree = {
153122
val cvarRef = mkUnattributedRef(cvar)
154123
Block(

src/compiler/scala/tools/nsc/ast/Trees.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
255255

256256
def resetAllAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(false, leaveAlone).transform(x)
257257
def resetLocalAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone).transform(x)
258+
def resetLocalAttrsKeepLabels[A<:Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone, true).transform(x)
258259

259260
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
260261
* with special treatment of:
@@ -265,7 +266,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
265266
*
266267
* (bq:) This transformer has mutable state and should be discarded after use
267268
*/
268-
private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null) {
269+
private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null, keepLabels: Boolean = false) {
269270
val debug = settings.debug.value
270271
val trace = scala.tools.nsc.util.trace when debug
271272

@@ -328,18 +329,18 @@ trait Trees extends reflect.internal.Trees { self: Global =>
328329
case EmptyTree =>
329330
tree
330331
case _ =>
331-
if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)))
332+
if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
332333
tree.symbol = NoSymbol
333334
tree.tpe = null
334335
tree
335336
}
336337
}
337-
}
338+
}
338339
}
339340

340341
def transform[T <: Tree](x: T): T = {
341342
if (localOnly)
342-
new MarkLocals().traverse(x)
343+
new MarkLocals().traverse(x)
343344

344345
if (localOnly && debug) {
345346
assert(locals.size == orderedLocals.size)

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ trait ParsersCommon extends ScannersCommon {
7070

7171
@inline final def inBracesOrNil[T](body: => List[T]): List[T] = inBracesOrError(body, Nil)
7272
@inline final def inBracesOrUnit[T](body: => Tree): Tree = inBracesOrError(body, Literal(Constant()))
73+
@inline final def dropAnyBraces[T](body: => T): T =
74+
if (in.token == LBRACE) inBraces(body)
75+
else body
7376

7477
@inline final def inBrackets[T](body: => T): T = {
7578
accept(LBRACKET)
@@ -1106,7 +1109,7 @@ self =>
11061109
* }}}
11071110
* @note The returned tree does not yet have a position
11081111
*/
1109-
def literal(isNegated: Boolean = false): Tree = {
1112+
def literal(isNegated: Boolean = false, inPattern: Boolean = false): Tree = {
11101113
def finish(value: Any): Tree = {
11111114
val t = Literal(Constant(value))
11121115
in.nextToken()
@@ -1115,7 +1118,7 @@ self =>
11151118
if (in.token == SYMBOLLIT)
11161119
Apply(scalaDot(nme.Symbol), List(finish(in.strVal)))
11171120
else if (in.token == INTERPOLATIONID)
1118-
interpolatedString()
1121+
interpolatedString(inPattern)
11191122
else finish(in.token match {
11201123
case CHARLIT => in.charVal
11211124
case INTLIT => in.intVal(isNegated).toInt
@@ -1141,7 +1144,7 @@ self =>
11411144
}
11421145
}
11431146

1144-
private def interpolatedString(): Tree = atPos(in.offset) {
1147+
private def interpolatedString(inPattern: Boolean = false): Tree = atPos(in.offset) {
11451148
val start = in.offset
11461149
val interpolator = in.name
11471150

@@ -1151,8 +1154,11 @@ self =>
11511154
while (in.token == STRINGPART) {
11521155
partsBuf += literal()
11531156
exprBuf += {
1154-
if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident()))
1155-
else expr()
1157+
if (inPattern) dropAnyBraces(pattern())
1158+
else {
1159+
if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident()))
1160+
else expr()
1161+
}
11561162
}
11571163
}
11581164
if (in.token == STRINGLIT) partsBuf += literal()
@@ -1837,7 +1843,7 @@ self =>
18371843
case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT =>
18381844
t match {
18391845
case Ident(nme.MINUS) =>
1840-
return atPos(start) { literal(isNegated = true) }
1846+
return atPos(start) { literal(isNegated = true, inPattern = true) }
18411847
case _ =>
18421848
}
18431849
case _ =>
@@ -1855,7 +1861,7 @@ self =>
18551861
atPos(start, start) { Ident(nme.WILDCARD) }
18561862
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
18571863
STRINGLIT | INTERPOLATIONID | SYMBOLLIT | TRUE | FALSE | NULL =>
1858-
atPos(start) { literal() }
1864+
atPos(start) { literal(inPattern = true) }
18591865
case LPAREN =>
18601866
atPos(start)(makeParens(noSeq.patterns()))
18611867
case XMLSTART =>

src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private[tests] trait CoreTestDefs
8181
else {
8282
reporter.println("\naskHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + pos.source.file.name)
8383
val r = new Response[Position]
84-
// `tree.symbol.sourceFile` was discovered to be null when testing -Yvirtpatmat on the akka presentation test, where a position had shifted to point to `Int`
84+
// `tree.symbol.sourceFile` was discovered to be null when testing using virtpatmat on the akka presentation test, where a position had shifted to point to `Int`
8585
// askHyperlinkPos for `Int` at (73,19) pi.scala --> class Int in package scala has null sourceFile!
8686
val treePath = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.path else null
8787
val treeName = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.name else null

0 commit comments

Comments
 (0)