diff options
-rw-r--r-- | src/compiler/scala/tools/ant/templates/tool-unix.tmpl | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 113 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 | ||||
-rw-r--r-- | test/files/pos/t5399.scala | 45 |
6 files changed, 136 insertions, 86 deletions
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index 85bb5f2056..256b5088e9 100644 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -9,19 +9,14 @@ ############################################################################## findScalaHome () { - # see SI-2092 - local SOURCE="${BASH_SOURCE[0]}" - while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done - local bindir="$( dirname "$SOURCE" )" - if [[ -d "$bindir"/.. ]]; then - ( cd -P "$bindir"/.. && pwd ) - else - # See SI-5792 - local dir=$(dirname "${BASH_SOURCE[0]}") - local link=$(dirname "$(readlink "${BASH_SOURCE[0]}")") - local path="$dir/$link/.." - ( cd "$path" && pwd ) - fi + # see SI-2092 and SI-5792 + local source="${BASH_SOURCE[0]}" + while [ -h "$source" ] ; do + local linked="$(readlink "$source")" + local dir="$( cd -P $(dirname "$source") && cd -P $(dirname "$linked") && pwd )" + source="$dir/$(basename "$linked")" + done + ( cd -P "$(dirname "$source")/.." && pwd ) } execCommand () { [[ -n $SCALA_RUNNER_DEBUG ]] && echo "" && for arg in "$@@"; do echo "$arg"; done && echo ""; diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index ceb75b575d..271dca3157 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -343,8 +343,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def checkPhase = wasActive(settings.check) def logPhase = isActive(settings.log) - // Write *.icode files the setting was given. - def writeICode = settings.writeICode.isSetByUser && isActive(settings.writeICode) + // Write *.icode files right after GenICode when -Xprint-icode was given. + def writeICodeAtICode = settings.writeICode.isSetByUser && isActive(settings.writeICode) // showing/printing things def browsePhase = isActive(settings.browse) @@ -1384,14 +1384,22 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb val mixinPhase = phaseNamed("mixin") val cleanupPhase = phaseNamed("cleanup") val icodePhase = phaseNamed("icode") - // val inlinerPhase = phaseNamed("inliner") - // val inlineExceptionHandlersPhase = phaseNamed("inlineExceptionHandlers") - // val closelimPhase = phaseNamed("closelim") - // val dcePhase = phaseNamed("dce") + val inlinerPhase = phaseNamed("inliner") + val inlineExceptionHandlersPhase = phaseNamed("inlineExceptionHandlers") + val closelimPhase = phaseNamed("closelim") + val dcePhase = phaseNamed("dce") val jvmPhase = phaseNamed("jvm") + // val msilPhase = phaseNamed("msil") def runIsAt(ph: Phase) = globalPhase.id == ph.id def runIsPast(ph: Phase) = globalPhase.id > ph.id + // def runIsAtBytecodeGen = (runIsAt(jvmPhase) || runIsAt(msilPhase)) + def runIsAtOptimiz = { + runIsAt(inlinerPhase) || // listing phases in full for robustness when -Ystop-after has been given. + runIsAt(inlineExceptionHandlersPhase) || + runIsAt(closelimPhase) || + runIsAt(dcePhase) + } isDefined = true @@ -1536,15 +1544,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb informTime(globalPhase.description, startTime) phaseTimings(globalPhase) = currentTime - startTime - // write icode to *.icode files - if (opt.writeICode) + if (opt.writeICodeAtICode || (opt.printPhase && runIsAtOptimiz)) { + // Write *.icode files when -Xprint-icode or -Xprint:<some-optimiz-phase> was given. writeICode() - - // print trees - if (opt.printPhase || opt.printLate && runIsAt(cleanupPhase)) { + } else if (opt.printPhase || opt.printLate && runIsAt(cleanupPhase)) { + // print trees if (opt.showTrees) nodePrinters.printAll() else printAllUnits() } + // print the symbols presently attached to AST nodes if (opt.showSymbols) trackerFactory.snapshot() diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index a0524d6932..43560f9d8d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -162,9 +162,9 @@ self => def incompleteInputError(msg: String): Unit = throw new MalformedInput(source.content.length - 1, msg) /** the markup parser */ - lazy val xmlp = new MarkupParser(this, true) + lazy val xmlp = new MarkupParser(this, preserveWS = true) - object symbXMLBuilder extends SymbolicXMLBuilder(this, true) { // DEBUG choices + object symbXMLBuilder extends SymbolicXMLBuilder(this, preserveWS = true) { // DEBUG choices val global: self.global.type = self.global def freshName(prefix: String): Name = SourceFileParser.this.freshName(prefix) } @@ -735,9 +735,9 @@ self => } ts.toList } - @inline final def commaSeparated[T](part: => T): List[T] = tokenSeparated(COMMA, false, part) - @inline final def caseSeparated[T](part: => T): List[T] = tokenSeparated(CASE, true, part) - @inline final def readAnnots[T](part: => T): List[T] = tokenSeparated(AT, true, part) + @inline final def commaSeparated[T](part: => T): List[T] = tokenSeparated(COMMA, sepFirst = false, part) + @inline final def caseSeparated[T](part: => T): List[T] = tokenSeparated(CASE, sepFirst = true, part) + @inline final def readAnnots[T](part: => T): List[T] = tokenSeparated(AT, sepFirst = true, part) /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ @@ -776,8 +776,7 @@ self => syntaxError( offset, "left- and right-associative operators with same precedence may not be mixed", false) - def reduceStack(isExpr: Boolean, base: List[OpInfo], top0: Tree, - prec: Int, leftAssoc: Boolean): Tree = { + def reduceStack(isExpr: Boolean, base: List[OpInfo], top0: Tree, prec: Int, leftAssoc: Boolean): Tree = { var top = top0 if (opstack != base && precedence(opstack.head.operator) == prec) checkAssoc(opstack.head.offset, opstack.head.operator, leftAssoc) @@ -825,7 +824,7 @@ self => atPos(start, in.skipToken()) { makeFunctionTypeTree(ts, typ()) } else { ts foreach checkNotByNameOrVarargs - val tuple = atPos(start) { makeTupleType(ts, true) } + val tuple = atPos(start) { makeTupleType(ts, flattenUnary = true) } infixTypeRest( compoundTypeRest( annotTypeRest( @@ -887,10 +886,10 @@ self => def simpleType(): Tree = { val start = in.offset simpleTypeRest(in.token match { - case LPAREN => atPos(start)(makeTupleType(inParens(types()), true)) + case LPAREN => atPos(start)(makeTupleType(inParens(types()), flattenUnary = true)) case USCORE => wildcardType(in.skipToken()) case _ => - path(false, true) match { + path(thisOK = false, typeOK = true) match { case r @ SingletonTypeTree(_) => r case r => convertToTypeId(r) } @@ -900,7 +899,7 @@ self => private def typeProjection(t: Tree): Tree = { val hashOffset = in.skipToken() val nameOffset = in.offset - val name = identForType(false) + val name = identForType(skipIt = false) val point = if (name == tpnme.ERROR) hashOffset else nameOffset atPos(t.pos.startOrPoint, point)(SelectFromTypeTree(t, name)) } @@ -949,7 +948,7 @@ self => if (isIdent && in.name != nme.STAR) { val opOffset = in.offset val leftAssoc = treeInfo.isLeftAssoc(in.name) - if (mode != InfixMode.FirstOp) checkAssoc(opOffset, in.name, mode == InfixMode.LeftOp) + if (mode != InfixMode.FirstOp) checkAssoc(opOffset, in.name, leftAssoc = mode == InfixMode.LeftOp) val op = identForType() val tycon = atPos(opOffset) { Ident(op) } newLineOptWhenFollowing(isTypeIntroToken) @@ -986,7 +985,7 @@ self => syntaxErrorOrIncomplete(expectedMsg(IDENTIFIER), skipIt) nme.ERROR } - def ident(): Name = ident(true) + def ident(): Name = ident(skipIt = true) def rawIdent(): Name = try in.name finally in.nextToken() /** For when it's known already to be a type name. */ @@ -997,7 +996,7 @@ self => val point = in.offset //assert(t.pos.isDefined, t) if (t != EmptyTree) - Select(t, ident(false)) setPos r2p(t.pos.startOrPoint, point, in.lastOffset) + Select(t, ident(skipIt = false)) setPos r2p(t.pos.startOrPoint, point, in.lastOffset) else errorTermTree // has already been reported } @@ -1055,7 +1054,8 @@ self => if (typeOK && in.token == TYPE) { in.nextToken() atPos(t.pos.startOrPoint, dotOffset) { SingletonTypeTree(t) } - } else { + } + else { val t1 = selector(t) if (in.token == DOT) { selectors(t1, typeOK, in.skipToken()) } else t1 @@ -1076,7 +1076,7 @@ self => * }}} */ def stableId(): Tree = - path(false, false) + path(thisOK = false, typeOK = false) /** {{{ * QualId ::= Id {`.' Id} @@ -1085,7 +1085,7 @@ self => def qualId(): Tree = { val start = in.offset val id = atPos(start) { Ident(ident()) } - if (in.token == DOT) { selectors(id, false, in.skipToken()) } + if (in.token == DOT) { selectors(id, typeOK = false, in.skipToken()) } else id } /** Calls `qualId()` and manages some package state. */ @@ -1118,7 +1118,7 @@ self => if (in.token == SYMBOLLIT) Apply(scalaDot(nme.Symbol), List(finish(in.strVal))) else if (in.token == INTERPOLATIONID) - interpolatedString(inPattern) + interpolatedString(inPattern = inPattern) else finish(in.token match { case CHARLIT => in.charVal case INTLIT => in.intVal(isNegated).toInt @@ -1206,7 +1206,7 @@ self => else startInfixType() def annotTypeRest(t: Tree): Tree = - (t /: annotations(false)) (makeAnnotated) + (t /: annotations(skipNewLines = false)) (makeAnnotated) /** {{{ * WildcardType ::= `_' TypeBounds @@ -1385,7 +1385,7 @@ self => syntaxErrorOrIncomplete("`*' expected", true) } } else if (in.token == AT) { - t = (t /: annotations(false)) (makeAnnotated) + t = (t /: annotations(skipNewLines = false)) (makeAnnotated) } else { t = atPos(t.pos.startOrPoint, colonPos) { val tpt = typeOrInfixType(location) @@ -1451,7 +1451,7 @@ self => var top = prefixExpr() while (isIdent) { - top = reduceStack(true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) + top = reduceStack(isExpr = true, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) val op = in.name opstack = OpInfo(top, op, in.offset) :: opstack ident() @@ -1459,19 +1459,19 @@ self => if (isExprIntro) { val next = prefixExpr() if (next == EmptyTree) - return reduceStack(true, base, top, 0, true) + return reduceStack(isExpr = true, base, top, 0, leftAssoc = true) top = next } else { // postfix expression val topinfo = opstack.head opstack = opstack.tail - val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true)) + val od = stripParens(reduceStack(isExpr = true, base, topinfo.operand, 0, leftAssoc = true)) return atPos(od.pos.startOrPoint, topinfo.offset) { new PostfixSelect(od, topinfo.operator.encode) } } } - reduceStack(true, base, top, 0, true) + reduceStack(isExpr = true, base, top, 0, leftAssoc = true) } /** {{{ @@ -1482,9 +1482,10 @@ self => if (isUnaryOp) { atPos(in.offset) { val name = nme.toUnaryName(rawIdent()) - // val name = nme.toUnaryName(ident()) // val name: Name = "unary_" + ident() - if (name == nme.UNARY_- && isNumericLit) simpleExprRest(atPos(in.offset)(literal(isNegated = true)), true) - else Select(stripParens(simpleExpr()), name) + if (name == nme.UNARY_- && isNumericLit) + simpleExprRest(atPos(in.offset)(literal(isNegated = true)), canApply = true) + else + Select(stripParens(simpleExpr()), name) } } else simpleExpr() @@ -1512,7 +1513,7 @@ self => case XMLSTART => xmlLiteral() case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER => - path(true, false) + path(thisOK = true, typeOK = false) case USCORE => val start = in.offset val pname = freshName("x$") @@ -1531,14 +1532,14 @@ self => val nstart = in.skipToken() val npos = r2p(nstart, nstart, in.lastOffset) val tstart = in.offset - val (parents, argss, self, stats) = template(false) + val (parents, argss, self, stats) = template(isTrait = false) val cpos = r2p(tstart, tstart, in.lastOffset max tstart) makeNew(parents, self, stats, argss, npos, cpos) case _ => syntaxErrorOrIncomplete("illegal start of simple expression", true) errorTermTree } - simpleExprRest(t, canApply) + simpleExprRest(t, canApply = canApply) } def simpleExprRest(t: Tree, canApply: Boolean): Tree = { @@ -1546,7 +1547,7 @@ self => in.token match { case DOT => in.nextToken() - simpleExprRest(selector(stripParens(t)), true) + simpleExprRest(selector(stripParens(t)), canApply = true) case LBRACKET => val t1 = stripParens(t) t1 match { @@ -1555,7 +1556,7 @@ self => while (in.token == LBRACKET) app = atPos(app.pos.startOrPoint, in.offset)(TypeApply(app, exprTypeArgs())) - simpleExprRest(app, true) + simpleExprRest(app, canApply = true) case _ => t1 } @@ -1571,7 +1572,7 @@ self => } Apply(sel, argumentExprs()) } - simpleExprRest(app, true) + simpleExprRest(app, canApply = true) case USCORE => atPos(t.pos.startOrPoint, in.skipToken()) { Typed(stripParens(t), Function(Nil, EmptyTree)) @@ -1659,11 +1660,11 @@ self => */ def enumerators(): List[Enumerator] = { val enums = new ListBuffer[Enumerator] - generator(enums, false) + generator(enums, eqOK = false) while (isStatSep) { in.nextToken() if (in.token == IF) enums += makeFilter(in.offset, guard()) - else generator(enums, true) + else generator(enums, eqOK = true) } enums.toList } @@ -1827,13 +1828,13 @@ self => } val base = opstack while (isIdent && in.name != raw.BAR) { - top = reduceStack(false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) + top = reduceStack(isExpr = false, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) val op = in.name opstack = OpInfo(top, op, in.offset) :: opstack ident() top = simplePattern(badPattern3) } - stripParens(reduceStack(false, base, top, 0, true)) + stripParens(reduceStack(isExpr = false, base, top, 0, leftAssoc = true)) } def badPattern3(): Tree = { def isComma = in.token == COMMA @@ -2096,7 +2097,7 @@ self => var caseParam = ofCaseClass def param(): ValDef = { val start = in.offset - val annots = annotations(false) + val annots = annotations(skipNewLines = false) var mods = Modifiers(Flags.PARAM) if (owner.isTypeName) { mods = modifiers() | Flags.PARAMACCESSOR @@ -2244,7 +2245,7 @@ self => param } newLineOptWhenFollowedBy(LBRACKET) - if (in.token == LBRACKET) inBrackets(commaSeparated(typeParam(NoMods withAnnotations annotations(true)))) + if (in.token == LBRACKET) inBrackets(commaSeparated(typeParam(NoMods withAnnotations annotations(skipNewLines = true)))) else Nil } @@ -2401,7 +2402,7 @@ self => private def caseAwareTokenOffset = if (in.token == CASECLASS || in.token == CASEOBJECT) in.prev.offset else in.offset def nonLocalDefOrDcl : List[Tree] = { - val annots = annotations(true) + val annots = annotations(skipNewLines = true) defOrDcl(caseAwareTokenOffset, modifiers() withAnnotations annots) } @@ -2495,7 +2496,7 @@ self => in.nextToken if (in.token == THIS) { atPos(start, in.skipToken()) { - val vparamss = paramClauses(nme.CONSTRUCTOR, classContextBounds map (_.duplicate), false) + val vparamss = paramClauses(nme.CONSTRUCTOR, classContextBounds map (_.duplicate), ofCaseClass = false) newLineOptWhenFollowedBy(LBRACE) val rhs = in.token match { case LBRACE => atPos(in.offset) { constrBlock(vparamss) } @@ -2519,7 +2520,7 @@ self => // i.e. (B[T] or T => B) val contextBoundBuf = new ListBuffer[Tree] val tparams = typeParamClauseOpt(name, contextBoundBuf) - val vparamss = paramClauses(name, contextBoundBuf.toList, false) + val vparamss = paramClauses(name, contextBoundBuf.toList, ofCaseClass = false) newLineOptWhenFollowedBy(LBRACE) var restype = fromWithinReturnType(typedOpt()) val rhs = @@ -2618,7 +2619,7 @@ self => /** Hook for IDE, for top-level classes/objects. */ def topLevelTmplDef: Tree = { - val annots = annotations(true) + val annots = annotations(skipNewLines = true) val pos = caseAwareTokenOffset val mods = modifiers() withAnnotations annots tmplDef(pos, mods) @@ -2672,7 +2673,7 @@ self => val constrAnnots = constructorAnnotations() val (constrMods, vparamss) = if (mods.isTrait) (Modifiers(Flags.TRAIT), List()) - else (accessModifierOpt(), paramClauses(name, classContextBounds, mods.isCase)) + else (accessModifierOpt(), paramClauses(name, classContextBounds, ofCaseClass = mods.isCase)) var mods1 = mods if (mods.isTrait) { if (settings.YvirtClasses && in.token == SUBTYPE) mods1 |= Flags.DEFERRED @@ -2739,7 +2740,7 @@ self => newLineOptWhenFollowedBy(LBRACE) if (in.token == LBRACE) { // @S: pre template body cannot stub like post body can! - val (self, body) = templateBody(true) + val (self, body) = templateBody(isPre = true) if (in.token == WITH && self.isEmpty) { val earlyDefs: List[Tree] = body flatMap { case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred => @@ -2752,15 +2753,15 @@ self => case _ => List() } in.nextToken() - val (parents, argss) = templateParents(isTrait) - val (self1, body1) = templateBodyOpt(isTrait) + val (parents, argss) = templateParents(isTrait = isTrait) + val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait) (parents, argss, self1, earlyDefs ::: body1) } else { (List(), List(List()), self, body) } } else { - val (parents, argss) = templateParents(isTrait) - val (self, body) = templateBodyOpt(isTrait) + val (parents, argss) = templateParents(isTrait = isTrait) + val (self, body) = templateBodyOpt(traitParentSeen = isTrait) (parents, argss, self, body) } } @@ -2778,11 +2779,11 @@ self => val (parents0, argss, self, body) = ( if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) { in.nextToken() - template(mods.isTrait) + template(isTrait = mods.isTrait) } else { newLineOptWhenFollowedBy(LBRACE) - val (self, body) = templateBodyOpt(false) + val (self, body) = templateBodyOpt(traitParentSeen = false) (List(), List(List()), self, body) } ) @@ -2816,14 +2817,14 @@ self => * }}} * @param isPre specifies whether in early initializer (true) or not (false) */ - def templateBody(isPre: Boolean) = inBraces(templateStatSeq(isPre)) match { + def templateBody(isPre: Boolean) = inBraces(templateStatSeq(isPre = isPre)) match { case (self, Nil) => (self, List(EmptyTree)) case result => result } def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = { newLineOptWhenFollowedBy(LBRACE) if (in.token == LBRACE) { - templateBody(false) + templateBody(isPre = false) } else { if (in.token == LPAREN) syntaxError((if (traitParentSeen) "parents of traits" else "traits or objects")+ @@ -2920,7 +2921,7 @@ self => /** Informal - for the repl and other direct parser accessors. */ - def templateStats(): List[Tree] = templateStatSeq(false)._2 match { + def templateStats(): List[Tree] = templateStatSeq(isPre = false)._2 match { case Nil => List(EmptyTree) case stats => stats } @@ -3004,7 +3005,7 @@ self => def localDef : List[Tree] = { atEndPos { atStartPos(in.offset) { - val annots = annotations(true) + val annots = annotations(skipNewLines = true) val mods = localModifiers() withAnnotations annots if (!(mods hasFlag ~(Flags.IMPLICIT | Flags.LAZY))) defOrDcl(mods) else List(tmplDef(mods)) @@ -3014,7 +3015,7 @@ self => */ def localDef(implicitMod: Int): List[Tree] = { - val annots = annotations(true) + val annots = annotations(skipNewLines = true) val pos = in.offset val mods = (localModifiers() | implicitMod) withAnnotations annots val defs = diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 99832d1327..b8cf4eca9f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -433,10 +433,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters { }
private val majorVersion: Int = (classfileVersion & 0xFF)
+ private val emitStackMapFrame = (majorVersion >= 50)
private val extraProc: Int = mkFlags(
asm.ClassWriter.COMPUTE_MAXS,
- if(majorVersion >= 50) asm.ClassWriter.COMPUTE_FRAMES else 0
+ if(emitStackMapFrame) asm.ClassWriter.COMPUTE_FRAMES else 0
)
val JAVA_LANG_OBJECT = asm.Type.getObjectType("java/lang/Object")
@@ -580,14 +581,14 @@ abstract class GenASM extends SubComponent with BytecodeWriters { else { sym.javaSimpleName }
})
- if(hasInternalName) {
+ if(emitStackMapFrame && hasInternalName) {
val internalName = cachedJN.toString()
val trackedSym = jsymbol(sym)
reverseJavaName.get(internalName) match {
case None =>
reverseJavaName.put(internalName, trackedSym)
case Some(oldsym) =>
- assert((oldsym == trackedSym) || List(RuntimeNothingClass, RuntimeNullClass).contains(oldsym), // NothingClass, NullClass,
+ assert((oldsym == trackedSym) || (oldsym == RuntimeNothingClass) || (oldsym == RuntimeNullClass), // In contrast, neither NothingClass nor NullClass show up bytecode-level.
"how can getCommonSuperclass() do its job if different class symbols get the same bytecode-level internal name.")
}
}
@@ -2728,7 +2729,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { // TODO Logical's 2nd elem should be declared ValueTypeKind, to better approximate its allowed values (isIntSized, its comments appears to convey)
// TODO GenICode uses `toTypeKind` to define that elem, `toValueTypeKind` would be needed instead.
// TODO How about adding some asserts to Logical and similar ones to capture the remaining constraint (UNIT not allowed).
- case Logical(op, kind) => (op, kind) match {
+ case Logical(op, kind) => ((op, kind): @unchecked) match {
case (AND, LONG) => emit(Opcodes.LAND)
case (AND, INT) => emit(Opcodes.IAND)
case (AND, _) =>
@@ -2748,7 +2749,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { if (kind != BOOL) { emitT2T(INT, kind) }
}
- case Shift(op, kind) => (op, kind) match {
+ case Shift(op, kind) => ((op, kind): @unchecked) match {
case (LSL, LONG) => emit(Opcodes.LSHL)
case (LSL, INT) => emit(Opcodes.ISHL)
case (LSL, _) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e643a91da7..b0f6e44e88 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2237,7 +2237,7 @@ trait Typers extends Modes with Adaptations with Taggings { // takes untyped sub-trees of a match and type checks them def typedMatch(selector: Tree, cases: List[CaseDef], mode: Int, pt: Type, tree: Tree = EmptyTree): Match = { val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) - val selectorTp = packCaptured(selector1.tpe.widen) + val selectorTp = packCaptured(selector1.tpe.widen).skolemizeExistential(context.owner, selector) val casesTyped = typedCases(cases, selectorTp, pt) val (resTp, needAdapt) = diff --git a/test/files/pos/t5399.scala b/test/files/pos/t5399.scala new file mode 100644 index 0000000000..ebae7dbd9e --- /dev/null +++ b/test/files/pos/t5399.scala @@ -0,0 +1,45 @@ +class Test { + class A[T] + class B[T](val a: A[T]) + + case class CaseClass[T](x: T) + + def break(existB: B[_]) = + CaseClass(existB.a) match { case CaseClass(_) => } +} + +class Foo { + trait Init[T] + class ScopedKey[T] extends Init[T] + + trait Setting[T] { + val key: ScopedKey[T] + } + + case class ScopedKey1[T](val foo: Init[T]) extends ScopedKey[T] + + val scalaHome: Setting[Option[String]] = null + val scalaVersion: Setting[String] = null + + def testPatternMatch(s: Setting[_]) { + s.key match { + case ScopedKey1(scalaHome.key | scalaVersion.key) => () + } + } +} + +class Test2 { + type AnyCyclic = Execute[Task]#CyclicException[_] + + trait Task[T] + + trait Execute[A[_] <: AnyRef] { + class CyclicException[T](val caller: A[T], val target: A[T]) + } + + def convertCyclic(c: AnyCyclic): String = + (c.caller, c.target) match { + case (caller: Task[_], target: Task[_]) => "bazinga!" + } +} + |