summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/build/pack.xml39
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala3
-rw-r--r--src/compiler/scala/reflect/reify/utils/SymbolTables.scala21
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala63
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala143
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala21
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala22
-rw-r--r--test/files/neg/t4425.check5
-rw-r--r--test/files/neg/t4425.flags1
-rw-r--r--test/files/pos/inline-access-levels.flags1
-rw-r--r--test/files/pos/inline-access-levels/A_1.scala10
-rw-r--r--test/files/pos/inline-access-levels/Test_2.scala11
-rw-r--r--test/files/pos/t5756.scala6
-rw-r--r--test/files/pos/t6145.scala11
-rw-r--r--test/files/pos/t6204-a.scala9
-rw-r--r--test/files/pos/t6204-b.scala10
-rw-r--r--test/files/pos/t6205.scala18
-rw-r--r--test/files/run/inline-ex-handlers.check170
21 files changed, 412 insertions, 174 deletions
diff --git a/src/build/pack.xml b/src/build/pack.xml
index 564d290967..1735b93f3f 100644
--- a/src/build/pack.xml
+++ b/src/build/pack.xml
@@ -29,10 +29,15 @@ MAIN DISTRIBUTION PACKAGING
<tarfileset dir="${dist.dir}" prefix="${dist.name}" excludes="bin/**"/>
</tar>
<gzip src="${dists.dir}/archives/${dist.name}.tar" destfile="${dists.dir}/archives/${dist.name}.tgz"/>
- <exec executable="xz" failifexecutionfails="false">
- <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}.tar"/>
- </exec>
- <move file="${dists.dir}/archives/${dist.name}.tar.xz" tofile="${dists.dir}/archives/${dist.name}.txz" failonerror="false"/>
+ <if>
+ <not><equals arg1="${archives.skipxz}" arg2="true" /></not>
+ <then>
+ <exec executable="xz" failifexecutionfails="false">
+ <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}.tar"/>
+ </exec>
+ <move file="${dists.dir}/archives/${dist.name}.tar.xz" tofile="${dists.dir}/archives/${dist.name}.txz" failonerror="false"/>
+ </then>
+ </if>
<delete file="${dists.dir}/archives/${dist.name}.tar" />
<checksum fileext=".md5">
<fileset dir="${dists.dir}/archives">
@@ -54,10 +59,15 @@ MAIN DISTRIBUTION PACKAGING
<tarfileset dir="${dist.dir}/doc/scala-devel-docs" prefix="${dist.name}-devel-docs"/>
</tar>
<gzip src="${dists.dir}/archives/${dist.name}-devel-docs.tar" destfile="${dists.dir}/archives/${dist.name}-devel-docs.tgz"/>
- <exec executable="xz" failifexecutionfails="false">
- <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-devel-docs.tar"/>
- </exec>
- <move file="${dists.dir}/archives/${dist.name}-devel-docs.tar.xz" tofile="${dists.dir}/archives/${dist.name}-devel-docs.txz" failonerror="false"/>
+ <if>
+ <not><equals arg1="${archives.skipxz}" arg2="true" /></not>
+ <then>
+ <exec executable="xz" failifexecutionfails="false">
+ <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-devel-docs.tar"/>
+ </exec>
+ <move file="${dists.dir}/archives/${dist.name}-devel-docs.tar.xz" tofile="${dists.dir}/archives/${dist.name}-devel-docs.txz" failonerror="false"/>
+ </then>
+ </if>
<delete file="${dists.dir}/archives/${dist.name}-devel-docs.tar" />
<checksum fileext=".md5">
<fileset dir="${dists.dir}/archives">
@@ -84,10 +94,15 @@ MAIN DISTRIBUTION PACKAGING
</tarfileset>
</tar>
<gzip src="${dists.dir}/archives/${dist.name}-sources.tar" destfile="${dists.dir}/archives/${dist.name}-sources.tgz"/>
- <exec executable="xz" failifexecutionfails="false">
- <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-sources.tar"/>
- </exec>
- <move file="${dists.dir}/archives/${dist.name}-sources.tar.xz" tofile="${dists.dir}/archives/${dist.name}-sources.txz" failonerror="false"/>
+ <if>
+ <not><equals arg1="${archives.skipxz}" arg2="true" /></not>
+ <then>
+ <exec executable="xz" failifexecutionfails="false">
+ <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-sources.tar"/>
+ </exec>
+ <move file="${dists.dir}/archives/${dist.name}-sources.tar.xz" tofile="${dists.dir}/archives/${dist.name}-sources.txz" failonerror="false"/>
+ </then>
+ </if>
<delete file="${dists.dir}/archives/${dist.name}-sources.tar" />
<checksum fileext=".md5">
<fileset dir="${dists.dir}/archives">
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 59651bcdf9..7f066a2cc3 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -36,7 +36,8 @@ trait GenSymbols {
else if (sym.isEmptyPackageClass)
mirrorMirrorSelect(nme.EmptyPackageClass)
else if (sym.isModuleClass)
- Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass)
+ if (sym.sourceModule.isLocatable) Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass)
+ else reifySymDef(sym)
else if (sym.isPackage)
mirrorMirrorCall(nme.staticPackage, reify(sym.fullName))
else if (sym.isLocatable) {
diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
index a7ac299317..3892c86dd3 100644
--- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
+++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
@@ -174,15 +174,18 @@ trait SymbolTables {
if (sym.annotations.isEmpty) EmptyTree
else Apply(Select(currtab.symRef(sym), nme.setAnnotations), List(reifier.reify(sym.annotations)))
} else {
- import scala.reflect.internal.Flags._
- if (sym hasFlag LOCKED) {
- // [Eugene] better to have a symbol without a type signature, than to crash with a CyclicReference
- EmptyTree
- } else {
- val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(sym.info))
- if (sym.annotations.isEmpty) rset
- else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo))
- }
+ // SI-6204 don't reify signatures for incomplete symbols, because this might lead to cyclic reference errors
+ val signature =
+ if (sym.isInitialized) {
+ if (sym.isCapturedVariable) capturedVariableType(sym)
+ else sym.info
+ } else NoType
+ val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature))
+ // `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here
+ // also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible)
+ // so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above)
+ if (sym.annotations.isEmpty) rset
+ else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo))
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index d87a242f1b..5464b6fc3b 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -661,13 +661,15 @@ abstract class Inliners extends SubComponent {
*
* TODO handle more robustly the case of a trait var changed at the source-level from public to private[this]
* (eg by having ICodeReader use unpickler, see SI-5442).
- * */
+
+ DISABLED
+
def potentiallyPublicized(f: Symbol): Boolean = {
(m.sourceFile eq NoSourceFile) && f.name.containsChar('$')
}
+ */
- def checkField(f: Symbol) = check(f, potentiallyPublicized(f) ||
- (f.isPrivate && !canMakePublic(f)))
+ def checkField(f: Symbol) = check(f, f.isPrivate && !canMakePublic(f))
def checkSuper(n: Symbol) = check(n, n.isPrivate || !n.isClassConstructor)
def checkMethod(n: Symbol) = check(n, n.isPrivate)
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 6fba6dcc39..8e928dc9e6 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -497,16 +497,7 @@ abstract class ExplicitOuter extends InfoTransform
else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5)
case Select(qual, name) =>
- /** return closest enclosing method, unless shadowed by an enclosing class;
- * no use of closures here in the interest of speed.
- */
- def closestEnclMethod(from: Symbol): Symbol =
- if (from.isSourceMethod) from
- else if (from.isClass) NoSymbol
- else closestEnclMethod(from.owner)
-
- if (currentClass != sym.owner ||
- (closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass))
+ if (currentClass != sym.owner)
sym.makeNotPrivate(sym.owner)
val qsym = qual.tpe.widen.typeSymbol
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 574c2c7049..2831afc48e 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -28,9 +28,6 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
/** the following two members override abstract members in Transform */
val phaseName: String = "extmethods"
- /** The following flags may be set by this phase: */
- override def phaseNewFlags: Long = notPRIVATE
-
def newTransformer(unit: CompilationUnit): Transformer =
new Extender(unit)
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 1012ea845f..08c78706fe 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -294,17 +294,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
removeCPSAdaptAnnotations(origPt)
else origPt
- // we've packed the type for each case in typedMatch so that if all cases have the same existential case, we get a clean lub
- // here, we should open up the existential again
// relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
- // TODO: fix skolemizeExistential (it should preserve annotations, right?)
- val pt = repeatedToSeq(ptUnCPS.skolemizeExistential(context.owner, context.tree) withAnnotations ptUnCPS.annotations)
+ // pt is the skolemized version
+ val pt = repeatedToSeq(ptUnCPS)
+
+ // val packedPt = repeatedToSeq(typer.packedType(match_, context.owner))
// the alternative to attaching the default case override would be to simply
// append the default to the list of cases and suppress the unreachable case error that may arise (once we detect that...)
val matchFailGenOverride = match_.attachments.get[DefaultOverrideMatchAttachment].map{case DefaultOverrideMatchAttachment(default) => ((scrut: Tree) => default)}
- val selectorSym = freshSym(selector.pos, pureType(selectorTp)) setFlag treeInfo.SYNTH_CASE_FLAGS
+ val selectorSym = freshSym(selector.pos, pureType(selectorTp)) setFlag treeInfo.SYNTH_CASE_FLAGS
// pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental
val combined = combineCases(selector, selectorSym, cases map translateCase(selectorSym, pt), pt, matchOwner, matchFailGenOverride)
@@ -727,8 +727,15 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// binder has type paramType
def treeMaker(binder: Symbol, pos: Position): TreeMaker = {
+ val paramAccessors = binder.constrParamAccessors
+ // binders corresponding to mutable fields should be stored (SI-5158, SI-6070)
+ val mutableBinders =
+ if (paramAccessors exists (_.isMutable))
+ subPatBinders.zipWithIndex.collect{ case (binder, idx) if paramAccessors(idx).isMutable => binder }
+ else Nil
+
// checks binder ne null before chaining to the next extractor
- ProductExtractorTreeMaker(binder, lengthGuard(binder))(subPatBinders, subPatRefs(binder))
+ ProductExtractorTreeMaker(binder, lengthGuard(binder))(subPatBinders, subPatRefs(binder), mutableBinders)
}
// reference the (i-1)th case accessor if it exists, otherwise the (i-1)th tuple component
@@ -990,10 +997,27 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
atPos(pos)(casegen.flatMapCond(cond, res, nextBinder, substitution(next)))
}
- trait PreserveSubPatBinders extends NoNewBinders {
+ // unless we're optimizing, emit local variable bindings for all subpatterns of extractor/case class patterns
+ protected val debugInfoEmitVars = !settings.optimise.value
+
+ trait PreserveSubPatBinders extends TreeMaker {
val subPatBinders: List[Symbol]
val subPatRefs: List[Tree]
+ // unless `debugInfoEmitVars`, this set should contain the bare minimum for correctness
+ // mutable case class fields need to be stored regardless (SI-5158, SI-6070) -- see override in ProductExtractorTreeMaker
+ def storedBinders: Set[Symbol] = if (debugInfoEmitVars) subPatBinders.toSet else Set.empty
+
+ def emitVars = storedBinders.nonEmpty
+
+ private lazy val (stored, substed) = (subPatBinders, subPatRefs).zipped.partition{ case (sym, _) => storedBinders(sym) }
+
+ protected lazy val localSubstitution: Substitution = if (!emitVars) Substitution(subPatBinders, subPatRefs)
+ else {
+ val (subPatBindersSubstituted, subPatRefsSubstituted) = substed.unzip
+ Substitution(subPatBindersSubstituted.toList, subPatRefsSubstituted.toList)
+ }
+
/** The substitution that specifies the trees that compute the values of the subpattern binders.
*
* We pretend to replace the subpattern binders by subpattern refs
@@ -1003,7 +1027,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
Substitution(subPatBinders, subPatRefs) >> super.subPatternsAsSubstitution
import CODE._
- def bindSubPats(in: Tree): Tree = Block(map2(subPatBinders, subPatRefs)(VAL(_) === _), in)
+ def bindSubPats(in: Tree): Tree = if (!emitVars) in
+ else {
+ val (subPatBindersStored, subPatRefsStored) = stored.unzip
+ Block(map2(subPatBindersStored.toList, subPatRefsStored.toList)(VAL(_) === _), in)
+ }
}
/**
@@ -1064,11 +1092,16 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
*/
case class ProductExtractorTreeMaker(prevBinder: Symbol, extraCond: Option[Tree])(
val subPatBinders: List[Symbol],
- val subPatRefs: List[Tree]) extends FunTreeMaker with PreserveSubPatBinders {
+ val subPatRefs: List[Tree],
+ val mutableBinders: List[Symbol]) extends FunTreeMaker with PreserveSubPatBinders {
import CODE._
val nextBinder = prevBinder // just passing through
+ // mutable binders must be stored to avoid unsoundness or seeing mutation of fields after matching (SI-5158, SI-6070)
+ // (the implementation could be optimized by duplicating code from `super.storedBinders`, but this seems more elegant)
+ override def storedBinders: Set[Symbol] = super.storedBinders ++ mutableBinders.toSet
+
def chainBefore(next: Tree)(casegen: Casegen): Tree = {
val nullCheck = REF(prevBinder) OBJ_NE NULL
val cond = extraCond map (nullCheck AND _) getOrElse nullCheck
@@ -1391,7 +1424,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// local / context-free
def _asInstanceOf(b: Symbol, tp: Type): Tree
- def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree
+ def _asInstanceOf(t: Tree, tp: Type): Tree
def _equals(checker: Tree, binder: Symbol): Tree
def _isInstanceOf(b: Symbol, tp: Type): Tree
def and(a: Tree, b: Tree): Tree
@@ -1449,7 +1482,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
Typed(gen.mkAsInstanceOf(t, tp.withoutAnnotations, true, false), TypeTree() setType tp)
// the force is needed mainly to deal with the GADT typing hack (we can't detect it otherwise as tp nor pt need contain an abstract type, we're just casting wildly)
- def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tp)) t else mkCast(t, tp)
+ def _asInstanceOf(t: Tree, tp: Type): Tree = if (t.tpe != NoType && t.isTyped && typesConform(t.tpe, tp)) t else mkCast(t, tp)
def _asInstanceOf(b: Symbol, tp: Type): Tree = if (typesConform(b.info, tp)) REF(b) else mkCast(REF(b), tp)
def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), tp.withoutAnnotations, true, false)
// if (typesConform(b.info, tpX)) { patmatDebug("warning: emitted spurious isInstanceOf: "+(b, tp)); TRUE }
@@ -3542,7 +3575,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
*/
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree = {
val matchEnd = newSynthCaseLabel("matchEnd")
- val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations //
+ val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations
matchEnd setInfo MethodType(List(matchRes), restpe)
def newCaseSym = newSynthCaseLabel("case") setInfo MethodType(Nil, restpe)
@@ -3553,7 +3586,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
val nextCase = newCaseSym
_currCase = nextCase
- LabelDef(currCase, Nil, mkCase(new OptimizedCasegen(matchEnd, nextCase, restpe)))
+ LabelDef(currCase, Nil, mkCase(new OptimizedCasegen(matchEnd, nextCase)))
}
// must compute catchAll after caseLabels (side-effects nextCase)
@@ -3578,14 +3611,14 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
)
}
- class OptimizedCasegen(matchEnd: Symbol, nextCase: Symbol, restpe: Type) extends CommonCodegen with Casegen {
+ class OptimizedCasegen(matchEnd: Symbol, nextCase: Symbol) extends CommonCodegen with Casegen {
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree =
optimizedCodegen.matcher(scrut, scrutSym, restpe)(cases, matchFailGen)
// only used to wrap the RHS of a body
// res: T
// returns MatchMonad[T]
- def one(res: Tree): Tree = matchEnd APPLY (_asInstanceOf(res, restpe)) // need cast for GADT magic
+ def one(res: Tree): Tree = matchEnd APPLY (res) // a jump to a case label is special-cased in typedApply
protected def zero: Tree = nextCase APPLY ()
// prev: MatchMonad[T]
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 92c50a05c2..d2a89eb9ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -34,6 +34,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
/** the following two members override abstract members in Transform */
val phaseName: String = "superaccessors"
+ /** The following flags may be set by this phase: */
+ override def phaseNewFlags: Long = notPRIVATE
+
protected def newTransformer(unit: CompilationUnit): Transformer =
new SuperAccTransformer(unit)
@@ -192,9 +195,11 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
}
super.transform(tree)
+
case ModuleDef(_, _, _) =>
checkCompanionNameClashes(sym)
super.transform(tree)
+
case Template(_, _, body) =>
val ownAccDefs = new ListBuffer[Tree]
accDefs(currentOwner) = ownAccDefs
@@ -221,72 +226,85 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
typeDef.symbol.deSkolemize.setFlag(SPECIALIZED)
typeDef
- case sel @ Select(qual @ This(_), name) =>
- // warn if they are selecting a private[this] member which
- // also exists in a superclass, because they may be surprised
- // to find out that a constructor parameter will shadow a
- // field. See SI-4762.
- if (settings.lint.value) {
- if (sym.isPrivateLocal && sym.paramss.isEmpty) {
- qual.symbol.ancestors foreach { parent =>
- parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 =>
- if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
- unit.warning(sel.pos,
- sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
- + " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within "
- + sym.owner + " - you may want to give them distinct names."
- )
+ case sel @ Select(qual, name) =>
+ /** return closest enclosing method, unless shadowed by an enclosing class;
+ * no use of closures here in the interest of speed.
+ */
+ def closestEnclMethod(from: Symbol): Symbol =
+ if (from.isSourceMethod) from
+ else if (from.isClass) NoSymbol
+ else closestEnclMethod(from.owner)
+
+ if (closestEnclMethod(currentOwner) hasAnnotation definitions.ScalaInlineClass)
+ sym.makeNotPrivate(sym.owner)
+
+ qual match {
+ case This(_) =>
+ // warn if they are selecting a private[this] member which
+ // also exists in a superclass, because they may be surprised
+ // to find out that a constructor parameter will shadow a
+ // field. See SI-4762.
+ if (settings.lint.value) {
+ if (sym.isPrivateLocal && sym.paramss.isEmpty) {
+ qual.symbol.ancestors foreach { parent =>
+ parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 =>
+ if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
+ unit.warning(sel.pos,
+ sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
+ + " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within "
+ + sym.owner + " - you may want to give them distinct names.")
+ }
+ }
}
}
}
- }
- }
- // direct calls to aliases of param accessors to the superclass in order to avoid
- // duplicating fields.
- if (sym.isParamAccessor && sym.alias != NoSymbol) {
- val result = (localTyper.typedPos(tree.pos) {
- Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias)
- }).asInstanceOf[Select]
- debuglog("alias replacement: " + tree + " ==> " + result);//debug
- localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true))
- }
- else {
- /** A trait which extends a class and accesses a protected member
- * of that class cannot implement the necessary accessor method
- * because its implementation is in an implementation class (e.g.
- * Foo$class) which inherits nothing, and jvm access restrictions
- * require the call site to be in an actual subclass. So non-trait
- * classes inspect their ancestors for any such situations and
- * generate the accessors. See SI-2296.
- */
- // FIXME - this should be unified with needsProtectedAccessor, but some
- // subtlety which presently eludes me is foiling my attempts.
- val shouldEnsureAccessor = (
- currentClass.isTrait
- && sym.isProtected
- && sym.enclClass != currentClass
- && !sym.owner.isTrait
- && (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
- && (qual.symbol.info.member(sym.name) ne NoSymbol)
- )
- if (shouldEnsureAccessor) {
- log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass)
- ensureAccessor(sel)
- }
- else
- mayNeedProtectedAccessor(sel, List(EmptyTree), false)
- }
+ // direct calls to aliases of param accessors to the superclass in order to avoid
+ // duplicating fields.
+ if (sym.isParamAccessor && sym.alias != NoSymbol) {
+ val result = (localTyper.typedPos(tree.pos) {
+ Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias)
+ }).asInstanceOf[Select]
+ debuglog("alias replacement: " + tree + " ==> " + result); //debug
+ localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true))
+ } else {
+ /**
+ * A trait which extends a class and accesses a protected member
+ * of that class cannot implement the necessary accessor method
+ * because its implementation is in an implementation class (e.g.
+ * Foo$class) which inherits nothing, and jvm access restrictions
+ * require the call site to be in an actual subclass. So non-trait
+ * classes inspect their ancestors for any such situations and
+ * generate the accessors. See SI-2296.
+ */
+ // FIXME - this should be unified with needsProtectedAccessor, but some
+ // subtlety which presently eludes me is foiling my attempts.
+ val shouldEnsureAccessor = (
+ currentClass.isTrait
+ && sym.isProtected
+ && sym.enclClass != currentClass
+ && !sym.owner.isTrait
+ && (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
+ && (qual.symbol.info.member(sym.name) ne NoSymbol))
+ if (shouldEnsureAccessor) {
+ log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass)
+ ensureAccessor(sel)
+ } else
+ mayNeedProtectedAccessor(sel, List(EmptyTree), false)
+ }
- case sel @ Select(Super(_, mix), name) =>
- if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
- if (!settings.overrideVars.value)
- unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf)
- }
- else if (isDisallowed(sym)) {
- unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
+ case Super(_, mix) =>
+ if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
+ if (!settings.overrideVars.value)
+ unit.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf)
+ } else if (isDisallowed(sym)) {
+ unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
+ }
+ transformSuperSelect(sel)
+
+ case _ =>
+ mayNeedProtectedAccessor(sel, List(EmptyTree), true)
}
- transformSuperSelect(sel)
case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension =>
treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, withInvalidOwner(transform(rhs)))
@@ -294,9 +312,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case TypeApply(sel @ Select(qual, name), args) =>
mayNeedProtectedAccessor(sel, args, true)
- case sel @ Select(qual, name) =>
- mayNeedProtectedAccessor(sel, List(EmptyTree), true)
-
case Assign(lhs @ Select(qual, name), rhs) =>
if (lhs.symbol.isVariable &&
lhs.symbol.isJavaDefined &&
@@ -311,10 +326,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case Apply(fn, args) =>
assert(fn.tpe != null, tree)
treeCopy.Apply(tree, transform(fn), transformArgs(fn.tpe.params, args))
+
case Function(vparams, body) =>
withInvalidOwner {
treeCopy.Function(tree, vparams, transform(body))
}
+
case _ =>
super.transform(tree)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index a6d7424837..d05368bd5f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3052,7 +3052,19 @@ trait Typers extends Modes with Adaptations with Tags {
// target of a call. Since this information is no longer available from
// typedArg, it is recorded here.
checkDead.updateExpr(fun)
- val args1 = typedArgs(args, forArgMode(fun, mode), paramTypes, formals)
+
+ val args1 =
+ // no expected type when jumping to a match label -- anything goes (this is ok since we're typing the translation of well-typed code)
+ // ... except during erasure: we must take the expected type into account as it drives the insertion of casts!
+ // I've exhausted all other semi-clean approaches I could think of in balancing GADT magic, SI-6145, CPS type-driven transforms and other existential trickiness
+ // (the right thing to do -- packing existential types -- runs into limitations in subtyping existential types,
+ // casting breaks SI-6145,
+ // not casting breaks GADT typing as it requires sneaking ill-typed trees past typer)
+ if (!phase.erasedTypes && fun.symbol.isLabel && treeInfo.isSynthCaseSymbol(fun.symbol))
+ typedArgs(args, forArgMode(fun, mode))
+ else
+ typedArgs(args, forArgMode(fun, mode), paramTypes, formals)
+
// instantiate dependent method types, must preserve singleton types where possible (stableTypeFor) -- example use case:
// val foo = "foo"; def precise(x: String)(y: x.type): x.type = {...}; val bar : foo.type = precise(foo)(foo)
// precise(foo) : foo.type => foo.type
@@ -5040,10 +5052,11 @@ trait Typers extends Modes with Adaptations with Tags {
if (isPatternMode) {
val uncheckedTypeExtractor = extractorForUncheckedType(tpt.pos, tptTyped.tpe)
- val ownType = inferTypedPattern(tptTyped, tptTyped.tpe, pt, canRemedy = uncheckedTypeExtractor.nonEmpty)
- // println(s"Typed($expr, ${tpt.tpe}) : $pt --> $ownType (${isFullyDefined(ownType)}, ${makeFullyDefined(ownType)})")
+
// make fully defined to avoid bounded wildcard types that may be in pt from calling dropExistential (SI-2038)
- treeTyped setType (if (isFullyDefined(ownType)) ownType else makeFullyDefined(ownType)) //ownType
+ val ptDefined = if (isFullyDefined(pt)) pt else makeFullyDefined(pt)
+ val ownType = inferTypedPattern(tptTyped, tptTyped.tpe, ptDefined, canRemedy = uncheckedTypeExtractor.nonEmpty)
+ treeTyped setType ownType
uncheckedTypeExtractor match {
case None => treeTyped
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index 4074dd9e93..44a7de3d3a 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -22,17 +22,17 @@ abstract class Universe extends scala.reflect.api.Universe {
/** The extended API of symbols that's supported in macro context universes
*/
- trait SymbolContextApi extends SymbolApi with AttachableApi { this: Symbol =>
+ trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol =>
- def setFlags(flags: FlagSet): this.type
+ def setFlags(flags: FlagSet): Symbol
- def setTypeSignature(tpe: Type): this.type
+ def setTypeSignature(tpe: Type): Symbol
- def setAnnotations(annots: AnnotationInfo*): this.type
+ def setAnnotations(annots: AnnotationInfo*): Symbol
- def setName(name: Name): this.type
+ def setName(name: Name): Symbol
- def setPrivateWithin(sym: Symbol): this.type
+ def setPrivateWithin(sym: Symbol): Symbol
}
// Tree extensions ---------------------------------------------------------------
@@ -41,20 +41,20 @@ abstract class Universe extends scala.reflect.api.Universe {
/** The extended API of trees that's supported in macro context universes
*/
- trait TreeContextApi extends TreeApi with AttachableApi { this: Tree =>
+ trait TreeContextApi extends TreeApi with AttachableApi { self: Tree =>
/** ... */
def pos_=(pos: Position): Unit
/** ... */
- def setPos(newpos: Position): this.type
+ def setPos(newpos: Position): Tree
/** ... */
def tpe_=(t: Type): Unit
/** Set tpe to give `tp` and return this.
*/
- def setType(tp: Type): this.type
+ def setType(tp: Type): Tree
/** Like `setType`, but if this is a previously empty TypeTree that
* fact is remembered so that resetAllAttrs will snap back.
@@ -73,13 +73,13 @@ abstract class Universe extends scala.reflect.api.Universe {
* and therefore should be abandoned if the current line of type
* inquiry doesn't work out.
*/
- def defineType(tp: Type): this.type
+ def defineType(tp: Type): Tree
/** ... */
def symbol_=(sym: Symbol): Unit
/** ... */
- def setSymbol(sym: Symbol): this.type
+ def setSymbol(sym: Symbol): Tree
}
override type SymTree >: Null <: Tree with SymTreeContextApi
diff --git a/test/files/neg/t4425.check b/test/files/neg/t4425.check
index a6a1a1fad4..0f2fe6f2d1 100644
--- a/test/files/neg/t4425.check
+++ b/test/files/neg/t4425.check
@@ -1,5 +1,4 @@
-t4425.scala:3: error: error during expansion of this match (this is a scalac bug).
-The underlying error was: value _1 is not a member of object Foo.X
+t4425.scala:3: error: isInstanceOf cannot test if value types are references.
42 match { case _ X _ => () }
- ^
+ ^
one error found
diff --git a/test/files/neg/t4425.flags b/test/files/neg/t4425.flags
new file mode 100644
index 0000000000..1182725e86
--- /dev/null
+++ b/test/files/neg/t4425.flags
@@ -0,0 +1 @@
+-optimize \ No newline at end of file
diff --git a/test/files/pos/inline-access-levels.flags b/test/files/pos/inline-access-levels.flags
new file mode 100644
index 0000000000..882f40f050
--- /dev/null
+++ b/test/files/pos/inline-access-levels.flags
@@ -0,0 +1 @@
+-optimise -Xfatal-warnings -Yinline-warnings
diff --git a/test/files/pos/inline-access-levels/A_1.scala b/test/files/pos/inline-access-levels/A_1.scala
new file mode 100644
index 0000000000..479fe0fc71
--- /dev/null
+++ b/test/files/pos/inline-access-levels/A_1.scala
@@ -0,0 +1,10 @@
+package test
+
+object A {
+
+ private var x: Int = 0
+
+ @inline def actOnX(f: Int => Int) = {
+ x = f(x)
+ }
+}
diff --git a/test/files/pos/inline-access-levels/Test_2.scala b/test/files/pos/inline-access-levels/Test_2.scala
new file mode 100644
index 0000000000..12c9eb540f
--- /dev/null
+++ b/test/files/pos/inline-access-levels/Test_2.scala
@@ -0,0 +1,11 @@
+package test
+
+object Test {
+
+ def main(args: Array[String]) {
+
+ A.actOnX(_ + 1)
+
+ }
+
+}
diff --git a/test/files/pos/t5756.scala b/test/files/pos/t5756.scala
new file mode 100644
index 0000000000..45960fa8bd
--- /dev/null
+++ b/test/files/pos/t5756.scala
@@ -0,0 +1,6 @@
+import scala.reflect.runtime.universe._
+
+object Test extends App {
+ def tagme[T: TypeTag](x: T) = typeTag[T]
+ val foo = tagme{object Bar; Bar}
+} \ No newline at end of file
diff --git a/test/files/pos/t6145.scala b/test/files/pos/t6145.scala
new file mode 100644
index 0000000000..28334d4420
--- /dev/null
+++ b/test/files/pos/t6145.scala
@@ -0,0 +1,11 @@
+object Test {
+ // the existential causes a cast and the cast makes searchClass not be in tail position
+ // can we get rid of the useless cast?
+ @annotation.tailrec
+ final def searchClass: Class[_] = {
+ "packageName" match {
+ case _ =>
+ searchClass
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t6204-a.scala b/test/files/pos/t6204-a.scala
new file mode 100644
index 0000000000..bd8d5c437e
--- /dev/null
+++ b/test/files/pos/t6204-a.scala
@@ -0,0 +1,9 @@
+import scala.reflect.runtime.universe._
+
+object Bish {
+ def m {
+ object Bash {
+ typeOf[Option[_]]
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t6204-b.scala b/test/files/pos/t6204-b.scala
new file mode 100644
index 0000000000..86094d1a19
--- /dev/null
+++ b/test/files/pos/t6204-b.scala
@@ -0,0 +1,10 @@
+import scala.reflect.runtime.universe._
+
+object Bosh {
+ def Besh {
+ new {
+ val t = typeOf[Option[_]]
+ val x = t
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t6205.scala b/test/files/pos/t6205.scala
new file mode 100644
index 0000000000..02d924fe85
--- /dev/null
+++ b/test/files/pos/t6205.scala
@@ -0,0 +1,18 @@
+// original code by reporter
+class A[T]
+class Test1 {
+ def x(backing: Map[A[_], Any]) =
+ for( (k: A[kt], v) <- backing)
+ yield (k: A[kt])
+}
+
+// this tests same thing as above, but independent of library classes,
+// earlier expansions eliminated as well as variance (everything's invariant)
+case class Holder[A](a: A)
+class Mapped[A] { def map[T](f: Holder[A] => T): Iterable[T] = ??? }
+class Test2 {
+ def works(backing: Mapped[A[_]]): Iterable[A[_]]
+ = backing.map(x =>
+ x match {case Holder(k: A[kt]) => (k: A[kt])}
+ )
+} \ No newline at end of file
diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check
index 25e1b2a4dd..a4c9f215e8 100644
--- a/test/files/run/inline-ex-handlers.check
+++ b/test/files/run/inline-ex-handlers.check
@@ -13,6 +13,10 @@
< 92 JUMP 2
<
< 2:
+383c382
+< locals: value args, variable result, value ex6, value x4, value x5, value message, value x
+---
+> locals: value args, variable result, value ex6, value x4, value x5, value x
385c384
< blocks: [1,2,3,4,5,8,11,13,14,16]
---
@@ -34,11 +38,21 @@
< 101 JUMP 4
<
< 4:
-515c520
+438,441d442
+< 106 LOAD_LOCAL(value x5)
+< 106 CALL_METHOD MyException.message (dynamic)
+< 106 STORE_LOCAL(value message)
+< 106 SCOPE_ENTER value message
+443c444,445
+< 106 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+515c517
< blocks: [1,2,3,4,6,7,8,9,10]
---
> blocks: [1,2,3,4,6,7,8,9,10,11,12,13]
-544c549,554
+544c546,551
< 306 THROW(MyException)
---
> ? JUMP 11
@@ -47,7 +61,7 @@
> ? LOAD_LOCAL(variable monitor4)
> 305 MONITOR_EXIT
> ? JUMP 12
-550c560,566
+550c557,563
< ? THROW(Throwable)
---
> ? JUMP 12
@@ -57,7 +71,7 @@
> 304 MONITOR_EXIT
> ? STORE_LOCAL(value t)
> ? JUMP 13
-556c572,585
+556c569,582
< ? THROW(Throwable)
---
> ? STORE_LOCAL(value t)
@@ -74,19 +88,19 @@
> 310 CALL_PRIMITIVE(EndConcat)
> 310 CALL_METHOD scala.Predef.println (dynamic)
> 310 JUMP 2
-580c609
+580c606
< catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6
---
> catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6
-583c612
+583c609
< catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3
---
> catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3
-615c644
+615c641
< blocks: [1,2,3,4,5,6,7,9,10]
---
> blocks: [1,2,3,4,5,6,7,9,10,11,12]
-639c668,674
+639c665,671
< 78 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -96,7 +110,7 @@
> 81 LOAD_LOCAL(value e)
> ? STORE_LOCAL(variable exc1)
> ? JUMP 12
-668c703,717
+668c700,714
< 81 THROW(Exception)
---
> ? STORE_LOCAL(variable exc1)
@@ -114,15 +128,19 @@
> 84 STORE_LOCAL(variable result)
> 84 LOAD_LOCAL(variable exc1)
> 84 THROW(Throwable)
-690c739
+690c736
< catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3
---
> catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3
-716c765
+714c760
+< locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value message, value x, value ex6, value x4, value x5, value message, value x
+---
+> locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value x, value ex6, value x4, value x5, value x
+716c762
< blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31]
---
> blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34]
-740c789,796
+740c786,793
< 172 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
@@ -133,12 +151,27 @@
> 170 STORE_LOCAL(value x4)
> 170 SCOPE_ENTER value x4
> 170 JUMP 18
-798c854,855
+787,790d839
+< 175 LOAD_LOCAL(value x5)
+< 175 CALL_METHOD MyException.message (dynamic)
+< 175 STORE_LOCAL(value message)
+< 175 SCOPE_ENTER value message
+792c841,842
+< 176 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+796c846,847
+< 177 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+798c849,850
< 177 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
> ? JUMP 33
-802c859,866
+802c854,861
< 170 THROW(Throwable)
---
> ? STORE_LOCAL(value ex6)
@@ -149,17 +182,32 @@
> 169 STORE_LOCAL(value x4)
> 169 SCOPE_ENTER value x4
> 169 JUMP 5
-837c901,902
+826,829d884
+< 180 LOAD_LOCAL(value x5)
+< 180 CALL_METHOD MyException.message (dynamic)
+< 180 STORE_LOCAL(value message)
+< 180 SCOPE_ENTER value message
+831c886,887
+< 181 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+835c891,892
+< 182 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+837c894,895
< 182 THROW(MyException)
---
> ? STORE_LOCAL(variable exc2)
> ? JUMP 34
-841c906,907
+841c899,900
< 169 THROW(Throwable)
---
> ? STORE_LOCAL(variable exc2)
> ? JUMP 34
-842a909,921
+842a902,914
> 34:
> 184 LOAD_MODULE object Predef
> 184 CONSTANT("finally")
@@ -173,19 +221,23 @@
> 185 LOAD_LOCAL(variable exc2)
> 185 THROW(Throwable)
>
-863c942
+863c935
< catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4
---
> catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4
-866c945
+866c938
< catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3
---
> catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3
-892c971
+890c962
+< locals: value args, variable result, value e, value ex6, value x4, value x5, value message, value x
+---
+> locals: value args, variable result, value e, value ex6, value x4, value x5, value x
+892c964
< blocks: [1,2,3,6,7,8,11,14,16,17,19]
---
> blocks: [1,2,3,6,7,8,11,14,16,17,19,20]
-916c995,1002
+916c988,995
< 124 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
@@ -196,15 +248,29 @@
> 122 STORE_LOCAL(value x4)
> 122 SCOPE_ENTER value x4
> 122 JUMP 7
-979c1065
+945,948d1023
+< 127 LOAD_LOCAL(value x5)
+< 127 CALL_METHOD MyException.message (dynamic)
+< 127 STORE_LOCAL(value message)
+< 127 SCOPE_ENTER value message
+950c1025,1026
+< 127 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+979c1055
< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3
---
> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3
-1005c1091
+1003c1079
+< locals: value args, variable result, value ex6, value x4, value x5, value message, value x, value e
+---
+> locals: value args, variable result, value ex6, value x4, value x5, value x, value e
+1005c1081
< blocks: [1,2,3,4,5,8,11,15,16,17,19]
---
> blocks: [1,2,3,5,8,11,15,16,17,19,20]
-1029c1115,1124
+1029c1105,1114
< 148 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
@@ -217,15 +283,25 @@
> 154 LOAD_LOCAL(value x4)
> 154 IS_INSTANCE REF(class MyException)
> 154 CZJUMP (BOOL)NE ? 5 : 11
-1050,1052d1144
+1050,1052d1134
< 145 JUMP 4
<
< 4:
-1288c1380
+1066,1069d1147
+< 154 LOAD_LOCAL(value x5)
+< 154 CALL_METHOD MyException.message (dynamic)
+< 154 STORE_LOCAL(value message)
+< 154 SCOPE_ENTER value message
+1071c1149,1150
+< 154 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+1288c1367
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1312c1404,1411
+1312c1391,1398
< 38 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -236,16 +312,20 @@
> 42 CONSTANT("IllegalArgumentException")
> 42 CALL_METHOD scala.Predef.println (dynamic)
> 42 JUMP 2
-1361c1460
+1359c1445
+< locals: value args, variable result, value ex6, value x4, value x5, value message, value x
+---
+> locals: value args, variable result, value ex6, value x4, value x5, value x
+1361c1447
< blocks: [1,2,3,4,5,8,11,13,14,16,17,19]
---
> blocks: [1,2,3,5,8,11,13,14,16,17,19,20]
-1385c1484,1485
+1385c1471,1472
< 203 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
> ? JUMP 20
-1405c1505,1514
+1405c1492,1501
< 209 THROW(MyException)
---
> ? STORE_LOCAL(value ex6)
@@ -258,15 +338,25 @@
> 212 LOAD_LOCAL(value x4)
> 212 IS_INSTANCE REF(class MyException)
> 212 CZJUMP (BOOL)NE ? 5 : 11
-1418,1420d1526
+1418,1420d1513
< 200 JUMP 4
<
< 4:
-1483c1589
+1434,1437d1526
+< 212 LOAD_LOCAL(value x5)
+< 212 CALL_METHOD MyException.message (dynamic)
+< 212 STORE_LOCAL(value message)
+< 212 SCOPE_ENTER value message
+1439c1528,1529
+< 213 LOAD_LOCAL(value message)
+---
+> ? LOAD_LOCAL(value x5)
+> ? CALL_METHOD MyException.message (dynamic)
+1483c1573
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1507c1613,1620
+1507c1597,1604
< 58 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -277,11 +367,11 @@
> 62 CONSTANT("RuntimeException")
> 62 CALL_METHOD scala.Predef.println (dynamic)
> 62 JUMP 2
-1556c1669
+1556c1653
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1576c1689,1694
+1576c1673,1678
< 229 THROW(MyException)
---
> ? JUMP 5
@@ -290,19 +380,19 @@
> ? LOAD_LOCAL(variable monitor1)
> 228 MONITOR_EXIT
> 228 THROW(Throwable)
-1582c1700
+1582c1684
< ? THROW(Throwable)
---
> 228 THROW(Throwable)
-1610c1728
+1610c1712
< locals: value args, variable result, variable monitor2, variable monitorResult1
---
> locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1
-1612c1730
+1612c1714
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1635c1753,1761
+1635c1737,1745
< 245 THROW(MyException)
---
> ? STORE_LOCAL(value exception$1)
@@ -314,7 +404,7 @@
> ? LOAD_LOCAL(variable monitor2)
> 244 MONITOR_EXIT
> 244 THROW(Throwable)
-1641c1767
+1641c1751
< ? THROW(Throwable)
---
> 244 THROW(Throwable)