summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala6
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala14
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala5
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala55
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala112
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala150
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala4
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaScanners.scala4
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaTokens.scala176
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala17
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala40
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/PostErasure.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala36
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala4
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala13
-rw-r--r--src/compiler/scala/tools/reflect/ReflectGlobal.scala7
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala15
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala59
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala2
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala16
-rw-r--r--src/library-aux/scala/AnyRef.scala4
-rw-r--r--src/library/scala/collection/Iterable.scala2
-rw-r--r--src/library/scala/collection/Iterator.scala2
-rw-r--r--src/library/scala/collection/Map.scala2
-rw-r--r--src/library/scala/collection/Seq.scala2
-rw-r--r--src/library/scala/collection/Set.scala2
-rw-r--r--src/library/scala/collection/Traversable.scala2
-rw-r--r--src/library/scala/collection/immutable/Map.scala6
-rw-r--r--src/library/scala/collection/mutable/AnyRefMap.scala27
-rw-r--r--src/library/scala/collection/mutable/Buffer.scala2
-rw-r--r--src/library/scala/collection/mutable/Iterable.scala2
-rw-r--r--src/library/scala/collection/mutable/Map.scala2
-rw-r--r--src/library/scala/collection/mutable/Seq.scala2
-rw-r--r--src/library/scala/collection/mutable/Set.scala2
-rw-r--r--src/library/scala/io/StdIn.scala3
-rw-r--r--src/library/scala/sys/process/ProcessBuilder.scala40
-rw-r--r--src/library/scala/sys/process/ProcessBuilderImpl.scala10
-rw-r--r--src/library/scala/util/matching/Regex.scala7
-rw-r--r--src/reflect/scala/reflect/api/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala2
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Required.scala3
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala22
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala250
-rw-r--r--src/reflect/scala/reflect/internal/tpe/FindMembers.scala288
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala8
-rw-r--r--src/reflect/scala/reflect/internal/transform/PostErasure.scala19
-rw-r--r--src/reflect/scala/reflect/internal/transform/Transforms.scala11
-rw-r--r--src/reflect/scala/reflect/macros/Evals.scala6
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala6
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala5
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala240
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverse.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala31
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala27
-rw-r--r--test/disabled/run/t7843-jsr223-service.scala18
-rw-r--r--test/files/neg/forgot-interpolator.check5
-rw-r--r--test/files/neg/forgot-interpolator.scala2
-rw-r--r--test/files/neg/names-defaults-neg.check2
-rw-r--r--test/files/neg/t0764b.check63
-rw-r--r--test/files/neg/t0764b.scala64
-rw-r--r--test/files/neg/t6260-named.check13
-rw-r--r--test/files/neg/t6260-named.scala15
-rw-r--r--test/files/neg/t6260.check13
-rw-r--r--test/files/neg/t6260b.check7
-rw-r--r--test/files/neg/t7475c.check7
-rw-r--r--test/files/neg/t7475c.scala9
-rw-r--r--test/files/neg/t7475d.check7
-rw-r--r--test/files/neg/t7475e.check4
-rw-r--r--test/files/neg/t7475e.scala12
-rw-r--r--test/files/neg/t7475f.check10
-rw-r--r--test/files/neg/t7475f.scala28
-rw-r--r--test/files/neg/t7507.check2
-rw-r--r--test/files/neg/t8207.check7
-rw-r--r--test/files/neg/t8207.scala3
-rw-r--r--test/files/neg/t8219-any-any-ref-equals.check10
-rw-r--r--test/files/neg/t8219-any-any-ref-equals.scala8
-rw-r--r--test/files/neg/t8237-default.check13
-rw-r--r--test/files/neg/t8237-default.scala29
-rw-r--r--test/files/pos/annotated-original/M_1.scala2
-rw-r--r--test/files/pos/annotated-treecopy/Impls_Macros_1.scala2
-rw-r--r--test/files/pos/delambdafy_t6260_method.check (renamed from test/files/neg/delambdafy_t6260_method.check)0
-rw-r--r--test/files/pos/delambdafy_t6260_method.flags (renamed from test/files/neg/delambdafy_t6260_method.flags)0
-rw-r--r--test/files/pos/delambdafy_t6260_method.scala (renamed from test/files/neg/delambdafy_t6260_method.scala)0
-rw-r--r--test/files/pos/t1786-counter.scala38
-rw-r--r--test/files/pos/t261-ab.scala9
-rw-r--r--test/files/pos/t261-ba.scala9
-rw-r--r--test/files/pos/t6169/Exist.java4
-rw-r--r--test/files/pos/t6169/ExistF.java4
-rw-r--r--test/files/pos/t6169/ExistIndir.java4
-rw-r--r--test/files/pos/t6169/OP.java1
-rw-r--r--test/files/pos/t6169/Skin.java1
-rw-r--r--test/files/pos/t6169/Skinnable.java3
-rw-r--r--test/files/pos/t6169/skinnable.scala14
-rw-r--r--test/files/pos/t6169/t6169.scala7
-rw-r--r--test/files/pos/t6260.flags (renamed from test/files/neg/t6260.flags)0
-rw-r--r--test/files/pos/t6260.scala (renamed from test/files/neg/t6260.scala)0
-rw-r--r--test/files/pos/t6260b.scala (renamed from test/files/neg/t6260b.scala)0
-rw-r--r--test/files/pos/t6948.scala10
-rw-r--r--test/files/pos/t7377/Macro_1.scala2
-rw-r--r--test/files/pos/t7475a.scala11
-rw-r--r--test/files/pos/t7475b.scala8
-rw-r--r--test/files/pos/t7475d.scala11
-rw-r--r--test/files/pos/t7475e.scala13
-rw-r--r--test/files/pos/t7516/A_1.scala2
-rw-r--r--test/files/pos/t8064/Macro_1.scala2
-rw-r--r--test/files/pos/t8207.scala6
-rw-r--r--test/files/pos/t8209a.check0
-rw-r--r--test/files/pos/t8209a/Macros_1.scala17
-rw-r--r--test/files/pos/t8209a/Test_2.scala4
-rw-r--r--test/files/pos/t8209b.check0
-rw-r--r--test/files/pos/t8209b/Macros_1.scala17
-rw-r--r--test/files/pos/t8209b/Test_2.scala4
-rw-r--r--test/files/pos/t8219.scala15
-rw-r--r--test/files/pos/t8219b.scala49
-rw-r--r--test/files/pos/t8237.scala29
-rw-r--r--test/files/pos/t8237b.scala10
-rw-r--r--test/files/presentation/callcc-interpreter.check4
-rw-r--r--test/files/presentation/completion-implicit-chained.check4
-rw-r--r--test/files/presentation/ide-bug-1000349.check4
-rw-r--r--test/files/presentation/ide-bug-1000475.check12
-rw-r--r--test/files/presentation/ide-bug-1000531.check4
-rw-r--r--test/files/presentation/implicit-member.check4
-rw-r--r--test/files/presentation/ping-pong.check8
-rw-r--r--test/files/presentation/scope-completion-3.check28
-rw-r--r--test/files/presentation/scope-completion-import.check16
-rw-r--r--test/files/presentation/t5708.check4
-rw-r--r--test/files/presentation/visibility.check21
-rw-r--r--test/files/run/inferred-type-constructors.check56
-rw-r--r--test/files/run/inferred-type-constructors.scala125
-rw-r--r--test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala2
-rw-r--r--test/files/run/reflection-magicsymbols-invoke.check7
-rw-r--r--test/files/run/reflection-sorted-members.check1
-rw-r--r--test/files/run/t261.check2
-rw-r--r--test/files/run/t261.scala11
-rw-r--r--test/files/run/t6260-delambdafy.check4
-rw-r--r--test/files/run/t6260-delambdafy.flags1
-rw-r--r--test/files/run/t6260-delambdafy.scala12
-rw-r--r--test/files/run/t6260c.check5
-rw-r--r--test/files/run/t6260c.scala17
-rw-r--r--test/files/run/t6411a.check96
-rw-r--r--test/files/run/t6411a.scala81
-rw-r--r--test/files/run/t6411b.check1
-rw-r--r--test/files/run/t6411b.scala12
-rw-r--r--test/files/run/t7240/Macros_1.scala2
-rw-r--r--test/files/run/t7319.check2
-rw-r--r--test/files/run/t7328.check4
-rw-r--r--test/files/run/t7328.scala18
-rw-r--r--test/files/run/t7475b.check2
-rw-r--r--test/files/run/t7475b.scala11
-rw-r--r--test/files/run/t7507.scala4
-rw-r--r--test/files/run/t7570a.check1
-rw-r--r--test/files/run/t7570a.scala11
-rw-r--r--test/files/run/t7570b.check1
-rw-r--r--test/files/run/t7570b.scala17
-rw-r--r--test/files/run/t7570c.check2
-rw-r--r--test/files/run/t7570c.scala13
-rw-r--r--test/files/run/t7843-jsr223-service.check (renamed from test/disabled/run/t7843-jsr223-service.check)0
-rw-r--r--test/files/run/t7843-jsr223-service.scala8
-rw-r--r--test/files/run/t7933.check2
-rw-r--r--test/files/run/t7933.scala11
-rw-r--r--test/files/run/t8245.scala14
-rw-r--r--test/files/scalacheck/quasiquotes/PatternConstructionProps.scala6
-rw-r--r--test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala5
-rw-r--r--test/junit/scala/collection/SetMapConsistencyTest.scala21
-rw-r--r--test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala1
-rw-r--r--test/pending/pos/t1786.scala (renamed from test/files/pos/t1786.scala)8
-rw-r--r--test/pending/pos/t5459.scala (renamed from test/files/pos/t5459.scala)0
-rw-r--r--test/pending/run/idempotency-partial-functions.scala2
184 files changed, 2317 insertions, 921 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index cd3db74016..c1ab17027f 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -46,9 +46,7 @@ trait Typers {
universe.analyzer.inferImplicit(tree, viewTpe, true, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg))
}
- def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(universe.duplicateAndKeepPositions(tree))
+ def resetLocalAttrs(tree: Tree): Tree = universe.resetAttrs(universe.duplicateAndKeepPositions(tree))
- def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(universe.duplicateAndKeepPositions(tree))
-
- def untypecheck(tree: Tree): Tree = universe.resetLocalAttrs(universe.duplicateAndKeepPositions(tree))
+ def untypecheck(tree: Tree): Tree = resetLocalAttrs(tree)
}
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index ad0632f93e..6b0a0ee8d7 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -86,7 +86,7 @@ abstract class Reifier extends States
throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString))
}
- // todo. why do we resetAllAttrs?
+ // todo. why do we reset attrs?
//
// typically we do some preprocessing before reification and
// the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is
@@ -109,19 +109,11 @@ abstract class Reifier extends States
//
// todo. this is a common problem with non-trivial macros in our current macro system
// needs to be solved some day
- // maybe try `resetLocalAttrs` once the dust settles
- var importantSymbols = Set[Symbol](
- NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
- ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, runDefinitions.ReflectRuntimeCurrentMirror)
- importantSymbols ++= importantSymbols map (_.companionSymbol)
- importantSymbols ++= importantSymbols map (_.moduleClass)
- importantSymbols ++= importantSymbols map (_.linkedClassOfClass)
- def isImportantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym)
- val untyped = resetAllAttrs(result, leaveAlone = {
+ // upd. a new hope: https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ
+ val untyped = resetAttrs(result, leaveAlone = {
case ValDef(_, u, _, _) if u == nme.UNIVERSE_SHORT => true
case ValDef(_, m, _, _) if m == nme.MIRROR_SHORT => true
case tree if symtab.syms contains tree.symbol => true
- case tree if isImportantSymbol(tree.symbol) => true
case _ => false
})
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index f6b3c42ca9..b082796757 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -140,7 +140,7 @@ trait GenTrees {
if (sym == NoSymbol) {
// this sometimes happens, e.g. for binds that don't have a body
// or for untyped code generated during previous phases
- // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
+ // (see a comment in Reifiers about the latter, starting with "why do we reset attrs?")
mirrorCall(nme.Ident, reify(name))
}
else if (!sym.isLocalToReifee) {
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index df5952a4cf..c2caed70a0 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -98,6 +98,11 @@ trait CompilationUnits { global: Global =>
override def toString = map.toString
}
+ // namer calls typer.computeType(rhs) on DefDef / ValDef when tpt is empty. the result
+ // is cached here and re-used in typedDefDef / typedValDef
+ // Also used to cache imports type-checked by namer.
+ val transformed = new mutable.AnyRefMap[Tree, Tree]
+
/** things to check at end of compilation unit */
val toCheck = new ListBuffer[() => Unit]
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 5492e563dd..1617db7517 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -81,6 +81,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase
+ def erasurePhase: Phase = if (currentRun.isDefined) currentRun.erasurePhase else NoPhase
+
// platform specific elements
protected class GlobalPlatform extends {
@@ -527,7 +529,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
} with Erasure
// phaseName = "posterasure"
- object postErasure extends {
+ override object postErasure extends {
val global: Global.this.type = Global.this
val runsAfter = List("erasure")
val runsRightAfter = Some("erasure")
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 24bce0636d..7a7d4ac0b2 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -176,13 +176,24 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
}
}
- /** resets symbol and tpe fields in a tree, @see ResetAttrs
- */
-// def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
-// def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
-
- def resetAllAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(false, leaveAlone).transform(x)
- def resetLocalAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(true, leaveAlone).transform(x)
+ // Finally, noone resetAllAttrs it anymore, so I'm removing it from the compiler.
+ // Even though it's with great pleasure I'm doing that, I'll leave its body here to warn future generations about what happened in the past.
+ //
+ // So what actually happened in the past is that we used to have two flavors of resetAttrs: resetAllAttrs and resetLocalAttrs.
+ // resetAllAttrs destroyed all symbols and types in the tree in order to reset its state to something suitable for retypechecking
+ // and/or embedding into bigger trees / different lexical scopes. (Btw here's some background on why people would want to use
+ // reset attrs in the first place: https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ).
+ //
+ // However resetAllAttrs was more of a poison than of a treatment, because along with locally defined symbols that are the cause
+ // for almost every or maybe even every case of tree corruption, it erased external bindings that sometimes could not be restored.
+ // This is how we came up with resetLocalAttrs that left external bindings alone, and that was a big step forward.
+ // Then slowly but steadily we've evicted all usages of resetAllAttrs from our codebase in favor of resetLocalAttrs
+ // and have been living happily ever after.
+ //
+ // def resetAllAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(localOnly = false, leaveAlone).transform(x)
+
+ /** @see ResetAttrs */
+ def resetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(leaveAlone).transform(x)
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
* with special treatment of:
@@ -193,7 +204,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
*
* (bq:) This transformer has mutable state and should be discarded after use
*/
- private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null, keepLabels: Boolean = false) {
+ private class ResetAttrs(leaveAlone: Tree => Boolean = null) {
// this used to be based on -Ydebug, but the need for logging in this code is so situational
// that I've reverted to a hard-coded constant here.
val debug = false
@@ -277,29 +288,18 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// vetoXXX local variables declared below describe the conditions under which we cannot erase symbols.
//
// The first reason to not erase symbols is the threat of non-idempotency (SI-5464).
- // Here we take care of labels (SI-5562) and references to package classes (SI-5705).
+ // Here we take care of references to package classes (SI-5705).
// There are other non-idempotencies, but they are not worked around yet.
//
- // The second reason has to do with the fact that resetAttrs itself has limited usefulness.
- //
- // First of all, why do we need resetAttrs? Gor one, it's absolutely required to move trees around.
- // One cannot just take a typed tree from one lexical context and transplant it somewhere else.
- // Most likely symbols defined by those trees will become borked and the compiler will blow up (SI-5797).
- // To work around we just erase all symbols and types and then hope that we'll be able to correctly retypecheck.
- // For ones who're not affected by scalac Stockholm syndrome, this might seem to be an extremely naive fix, but well...
- //
- // Of course, sometimes erasing everything won't work, because if a given identifier got resolved to something
- // in one lexical scope, it can get resolved to something else.
- //
- // What do we do in these cases? Enter the workaround for the workaround: resetLocalAttrs, which only destroys
- // locally defined symbols, but doesn't touch references to stuff declared outside of a given tree.
- // That's what localOnly and vetoScope are for.
+ // The second reason has to do with the fact that resetAttrs needs to be less destructive.
+ // Erasing locally-defined symbols is useful to prevent tree corruption, but erasing external bindings is not,
+ // therefore we want to retain those bindings, especially given that restoring them can be impossible
+ // if we move these trees into lexical contexts different from their original locations.
if (dupl.hasSymbol) {
val sym = dupl.symbol
- val vetoScope = localOnly && !(locals contains sym)
- val vetoLabel = keepLabels && sym.isLabel
+ val vetoScope = !(locals contains sym)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
- if (!(vetoScope || vetoLabel || vetoThis)) dupl.symbol = NoSymbol
+ if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol
}
dupl.clearType()
}
@@ -308,10 +308,9 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
}
def transform(x: Tree): Tree = {
- if (localOnly)
new MarkLocals().traverse(x)
- if (localOnly && debug) {
+ if (debug) {
assert(locals.size == orderedLocals.size)
val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString EOL
trace("locals (%d total): %n".format(orderedLocals.size))(msg)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala b/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala
new file mode 100644
index 0000000000..5fcb02814b
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala
@@ -0,0 +1,112 @@
+package scala.tools.nsc
+package ast.parser
+
+/** Common code between Scala's Tokens and JavaTokens. */
+abstract class CommonTokens {
+
+ def isIdentifier(code: Int): Boolean
+ def isLiteral(code: Int): Boolean
+
+ /** special tokens */
+ final val EMPTY = -3
+ final val UNDEF = -2
+ final val ERROR = -1
+ final val EOF = 0
+
+ /** literals */
+ final val CHARLIT = 1
+ final val INTLIT = 2
+ final val LONGLIT = 3
+ final val FLOATLIT = 4
+ final val DOUBLELIT = 5
+ final val STRINGLIT = 6
+
+ /** keywords */
+ final val NEW = 20
+ final val THIS = 21
+ final val SUPER = 23
+
+ final val NULL = 24
+ final val TRUE = 25
+ final val FALSE = 26
+
+ // J: INSTANCEOF = 27
+ // J: CONST = 28
+
+ /** modifiers */
+ // S: IMPLICIT = 40
+ // S: OVERRIDE = 41
+ // J: PUBLIC = 42
+ final val PROTECTED = 43
+ final val PRIVATE = 44
+ // S: SEALED = 45
+ final val ABSTRACT = 46
+ // J: DEFAULT = 47
+ // J: STATIC = 48
+ final val FINAL = 49
+ // J: TRANSIENT = 50
+ // J: VOLATILE = 51
+ // J: SYNCHRONIZED = 52
+ // J: NATIVE = 53
+ // J: STRICTFP = 54
+ // S: LAZY = 55
+ // J: THROWS = 56
+ // S: MACRO = 57
+
+ /** templates */
+ final val PACKAGE = 60
+ final val IMPORT = 61
+ final val CLASS = 62
+ // S: CASECLASS = 63
+ // S: OBJECT = 64
+ // S: CASEOBJECT = 65
+ // S: TRAIT, J: INTERFACE = 66
+ // J: ENUM = 67
+ final val EXTENDS = 68
+ // S: WITH, J: IMPLEMENTS = 69
+ // S: TYPE = 70
+ // S: FORSOME = 71
+ // S: DEF = 72
+ // S: VAL = 73
+ // S: VAR = 74
+
+ /** control structures */
+ final val IF = 80
+ // S: THEN = 81
+ final val ELSE = 82
+ final val WHILE = 83
+ final val DO = 84
+ final val FOR = 85
+ // S: YIELD = 86
+ // J: BREAK = 87
+ // J: CONTINUE = 88
+ // J: GOTO = 89
+ final val THROW = 90
+ final val TRY = 91
+ final val CATCH = 92
+ final val FINALLY = 93
+ // J: SWITCH = 94
+ // S: MATCH = 95
+ final val CASE = 96
+ final val RETURN = 97
+ // J: ASSERT = 98
+
+ /** parenthesis */
+ final val LPAREN = 100
+ final val RPAREN = 101
+ final val LBRACKET = 102
+ final val RBRACKET = 103
+ final val LBRACE = 104
+ final val RBRACE = 105
+
+ /** special symbols */
+ final val COMMA = 120
+ final val SEMI = 121
+ final val DOT = 122
+ final val COLON = 123
+ final val EQUALS = 124
+ final val AT = 125
+ // S: <special symbols> = 130 - 139
+ // J: <special symbols> = 140 - 179
+ // J: <primitive types> = 180 - 189
+}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
index 5a7dc4950d..e624aec88c 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
@@ -6,123 +6,57 @@
package scala.tools.nsc
package ast.parser
-/** Common code between JavaTokens and Tokens. Not as much (and not as concrete)
- * as one might like because JavaTokens for no clear reason chose new numbers for
- * identical token sets.
- */
-abstract class Tokens {
- /** special tokens */
- final val EMPTY = -3
- final val UNDEF = -2
- final val ERROR = -1
- final val EOF = 0
-
- /** literals */
- final val CHARLIT = 1
- final val INTLIT = 2
- final val LONGLIT = 3
- final val FLOATLIT = 4
- final val DOUBLELIT = 5
- final val STRINGLIT = 6
-
- def LPAREN: Int
- def RBRACE: Int
-
- def isIdentifier(code: Int): Boolean
- def isLiteral(code: Int): Boolean
-}
-
-object Tokens extends Tokens {
- final val STRINGPART = 7 // a part of an interpolated string
+object Tokens extends CommonTokens {
+ final val STRINGPART = 7 // a part of an interpolated string
final val SYMBOLLIT = 8
final val INTERPOLATIONID = 9 // the lead identifier of an interpolated string
- def isLiteral(code: Int) =
- code >= CHARLIT && code <= INTERPOLATIONID
+ def isLiteral(code: Int) = code >= CHARLIT && code <= INTERPOLATIONID
/** identifiers */
final val IDENTIFIER = 10
final val BACKQUOTED_IDENT = 11
- def isIdentifier(code: Int) = code >= IDENTIFIER && code <= BACKQUOTED_IDENT // used by ide
-
- /** keywords */
- final val IF = 20
- final val FOR = 21
- final val ELSE = 22
- final val THIS = 23
- final val NULL = 24
- final val NEW = 25
- final val WITH = 26
- final val SUPER = 27
- final val CASE = 28
- final val CASECLASS = 29
- final val CASEOBJECT = 30
- final val VAL = 31
- final val ABSTRACT = 32
- final val FINAL = 33
- final val PRIVATE = 34
- final val PROTECTED = 35
- final val OVERRIDE = 36
- final val IMPLICIT = 37
- final val VAR = 38
- final val DEF = 39
- final val TYPE = 40
- final val EXTENDS = 41
- final val TRUE = 42
- final val FALSE = 43
- final val OBJECT = 44
- final val CLASS = 45
-
- final val IMPORT = 46
- final val PACKAGE = 47
- final val YIELD = 48
- final val DO = 49
- final val TRAIT = 50
- final val SEALED = 51
- final val THROW = 52
- final val TRY = 53
- final val CATCH = 54
- final val FINALLY = 55
- final val WHILE = 56
- final val RETURN = 57
- final val MATCH = 58
- final val FORSOME = 59
- final val LAZY = 61
- final val MACRO = 62 // not yet used in 2.10
- final val THEN = 63 // not yet used in 2.10
+ def isIdentifier(code: Int) = code == IDENTIFIER || code == BACKQUOTED_IDENT // used by ide
+
+ /** modifiers */
+ final val IMPLICIT = 40
+ final val OVERRIDE = 41
+ final val SEALED = 45
+ final val LAZY = 55
+ final val MACRO = 57
+
+ /** templates */
+ final val CASECLASS = 63
+ final val OBJECT = 64
+ final val CASEOBJECT = 65
+ final val TRAIT = 66
+ final val WITH = 69
+ final val TYPE = 70
+ final val FORSOME = 71
+ final val DEF = 72
+ final val VAL = 73
+ final val VAR = 74
+
+ /** control structures */
+ final val THEN = 81
+ final val YIELD = 86
+ final val MATCH = 95
/** special symbols */
- final val COMMA = 70
- final val SEMI = 71
- final val DOT = 72
- final val USCORE = 73
- final val COLON = 74
- final val EQUALS = 75
- final val LARROW = 76
- final val ARROW = 77
- final val NEWLINE = 78
- final val NEWLINES = 79
- final val SUBTYPE = 80
- final val SUPERTYPE = 81
- final val HASH = 82
- final val AT = 83
- final val VIEWBOUND = 84
-
- /** parenthesis */
- final val LPAREN = 90
- final val RPAREN = 91
- final val LBRACKET = 92
- final val RBRACKET = 93
- final val LBRACE = 94
- final val RBRACE = 95
-
- /** XML mode */
- final val XMLSTART = 96
+ final val HASH = 130
+ final val USCORE = 131
+ final val ARROW = 132
+ final val LARROW = 133
+ final val SUBTYPE = 134
+ final val SUPERTYPE = 135
+ final val VIEWBOUND = 136
+ final val NEWLINE = 137
+ final val NEWLINES = 138
+ final val XMLSTART = 139
/** for IDE only */
- final val COMMENT = 97
-
- final val WHITESPACE = 105
- final val IGNORE = 106
- final val ESCAPE = 109
+ final val COMMENT = 200
+ final val WHITESPACE = 201
+ final val IGNORE = 202
+ final val ESCAPE = 203
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index eb40e1dbde..b03519ce7d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -171,10 +171,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
var pickledBytes = 0 // statistics
- val javaNameCache = perRunCaches.newMap[Symbol, Name]()
+ val javaNameCache = perRunCaches.newAnyRefMap[Symbol, Name]()
// unlike javaNameCache, reverseJavaName contains entries only for class symbols and their internal names.
- val reverseJavaName = perRunCaches.newMap[String, Symbol]()
+ val reverseJavaName = perRunCaches.newAnyRefMap[String, Symbol]()
private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
private def hasPublicBitSet(flags: Int) = (flags & asm.Opcodes.ACC_PUBLIC) != 0
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 9875d27047..a61ad392ee 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -190,7 +190,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
case GTGTGT => GTGT
case GTGTEQ => GTEQ
case GTGT => GT
- case GTEQ => ASSIGN
+ case GTEQ => EQUALS
}
if (closers isDefinedAt in.token) in.token = closers(in.token)
else accept(GT)
@@ -538,7 +538,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
in.nextToken()
if (in.token == IDENTIFIER) { // if there's an ident after the comma ...
val name = ident()
- if (in.token == ASSIGN || in.token == SEMI) { // ... followed by a `=` or `;`, we know it's a real variable definition
+ if (in.token == EQUALS || in.token == SEMI) { // ... followed by a `=` or `;`, we know it's a real variable definition
buf ++= maybe
buf += varDecl(in.currentPos, mods, tpt.duplicate, name.toTermName)
maybe.clear()
@@ -563,7 +563,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def varDecl(pos: Position, mods: Modifiers, tpt: Tree, name: TermName): ValDef = {
val tpt1 = optArrayBrackets(tpt)
- if (in.token == ASSIGN && !mods.isParameter) skipTo(COMMA, SEMI)
+ if (in.token == EQUALS && !mods.isParameter) skipTo(COMMA, SEMI)
val mods1 = if (mods.isFinal) mods &~ Flags.FINAL else mods | Flags.MUTABLE
atPos(pos) {
ValDef(mods1, name, tpt1, blankExpr)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index b7ea70e2c7..c5401219dd 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -155,7 +155,6 @@ trait JavaScanners extends ast.parser.ScannersCommon {
case AMP => "`&'"
case AMPAMP => "`&&'"
case AMPEQ => "`&='"
- case ASSIGN => "`='"
case ASTERISK => "`*'"
case ASTERISKEQ => "`*='"
case AT => "`@'"
@@ -169,6 +168,7 @@ trait JavaScanners extends ast.parser.ScannersCommon {
case DOT => "`.'"
case DOTDOTDOT => "`...'"
case EQEQ => "`=='"
+ case EQUALS => "`='"
case GT => "`>'"
case GTEQ => "`>='"
case GTGT => "`>>'"
@@ -337,7 +337,7 @@ trait JavaScanners extends ast.parser.ScannersCommon {
return
case '=' =>
- token = ASSIGN
+ token = EQUALS
in.next()
if (in.ch == '=') {
token = EQEQ
diff --git a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
index 953a3c6d82..9b31e6e8a2 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
@@ -6,117 +6,89 @@
package scala.tools.nsc
package javac
-object JavaTokens extends ast.parser.Tokens {
+object JavaTokens extends ast.parser.CommonTokens {
- def isLiteral(code : Int) =
+ def isLiteral(code: Int) =
code >= CHARLIT && code <= STRINGLIT
/** identifiers */
final val IDENTIFIER = 10
- def isIdentifier(code : Int) =
+ def isIdentifier(code: Int) =
code == IDENTIFIER
/** keywords */
- final val ABSTRACT = 20
- final val ASSERT = 21
- final val BOOLEAN = 22
- final val BREAK = 23
- final val BYTE = 24
- final val CASE = 25
- final val CATCH = 26
- final val CHAR = 27
- final val CLASS = 28
- final val CONST = 29
- final val CONTINUE = 30
- final val DEFAULT = 31
- final val DO = 32
- final val DOUBLE = 33
- final val ELSE = 34
- final val ENUM = 35
- final val EXTENDS = 36
- final val FINAL = 37
- final val FINALLY = 38
- final val FLOAT = 39
- final val FOR = 40
- final val IF = 41
- final val GOTO = 42
- final val IMPLEMENTS = 43
- final val IMPORT = 44
- final val INSTANCEOF = 45
- final val INT = 46
- final val INTERFACE = 47
- final val LONG = 48
- final val NATIVE = 49
- final val NEW = 50
- final val PACKAGE = 51
- final val PRIVATE = 52
- final val PROTECTED = 53
- final val PUBLIC = 54
- final val RETURN = 55
- final val SHORT = 56
- final val STATIC = 57
- final val STRICTFP = 58
- final val SUPER = 59
- final val SWITCH = 60
- final val SYNCHRONIZED = 61
- final val THIS = 62
- final val THROW = 63
- final val THROWS = 64
- final val TRANSIENT = 65
- final val TRY = 66
- final val VOID = 67
- final val VOLATILE = 68
- final val WHILE = 69
+ final val INSTANCEOF = 27
+ final val CONST = 28
+
+ /** modifiers */
+ final val PUBLIC = 42
+ final val DEFAULT = 47
+ final val STATIC = 48
+ final val TRANSIENT = 50
+ final val VOLATILE = 51
+ final val SYNCHRONIZED = 52
+ final val NATIVE = 53
+ final val STRICTFP = 54
+ final val THROWS = 56
+
+ /** templates */
+ final val INTERFACE = 66
+ final val ENUM = 67
+ final val IMPLEMENTS = 69
+
+ /** control structures */
+ final val BREAK = 87
+ final val CONTINUE = 88
+ final val GOTO = 89
+ final val SWITCH = 94
+ final val ASSERT = 98
/** special symbols */
- final val COMMA = 70
- final val SEMI = 71
- final val DOT = 72
- final val AT = 73
- final val COLON = 74
- final val ASSIGN = 75
- final val EQEQ = 76
- final val BANGEQ = 77
- final val LT = 78
- final val GT = 79
- final val LTEQ = 80
- final val GTEQ = 81
- final val BANG = 82
- final val QMARK = 83
- final val AMP = 84
- final val BAR = 85
- final val PLUS = 86
- final val MINUS = 87
- final val ASTERISK = 88
- final val SLASH = 89
- final val PERCENT = 90
- final val HAT = 91
- final val LTLT = 92
- final val GTGT = 93
- final val GTGTGT = 94
- final val AMPAMP = 95
- final val BARBAR = 96
- final val PLUSPLUS = 97
- final val MINUSMINUS = 98
- final val TILDE = 99
- final val DOTDOTDOT = 100
- final val AMPEQ = 104
- final val BAREQ = 105
- final val PLUSEQ = 106
- final val MINUSEQ = 107
- final val ASTERISKEQ = 1010
- final val SLASHEQ = 109
- final val PERCENTEQ = 110
- final val HATEQ = 111
- final val LTLTEQ = 112
- final val GTGTEQ = 113
- final val GTGTGTEQ = 114
+ final val EQEQ = 140
+ final val BANGEQ = 141
+ final val LT = 142
+ final val GT = 143
+ final val LTEQ = 144
+ final val GTEQ = 145
+ final val BANG = 146
+ final val QMARK = 147
+ final val AMP = 148
+ final val BAR = 149
+ final val PLUS = 150
+ final val MINUS = 151
+ final val ASTERISK = 152
+ final val SLASH = 153
+ final val PERCENT = 154
+ final val HAT = 155
+ final val LTLT = 156
+ final val GTGT = 157
+ final val GTGTGT = 158
+ final val AMPAMP = 159
+ final val BARBAR = 160
+ final val PLUSPLUS = 161
+ final val MINUSMINUS = 162
+ final val TILDE = 163
+ final val DOTDOTDOT = 164
+ final val AMPEQ = 165
+ final val BAREQ = 166
+ final val PLUSEQ = 167
+ final val MINUSEQ = 168
+ final val ASTERISKEQ = 169
+ final val SLASHEQ = 170
+ final val PERCENTEQ = 171
+ final val HATEQ = 172
+ final val LTLTEQ = 173
+ final val GTGTEQ = 174
+ final val GTGTGTEQ = 175
- /** parenthesis */
- final val LPAREN = 115
- final val RPAREN = 116
- final val LBRACKET = 117
- final val RBRACKET = 118
- final val LBRACE = 119
- final val RBRACE = 120
+ /** primitive types */
+ final val VOID = 180
+ final val BOOLEAN = 181
+ final val BYTE = 182
+ final val SHORT = 183
+ final val CHAR = 184
+ final val INT = 185
+ final val LONG = 186
+ final val FLOAT = 187
+ final val DOUBLE = 188
}
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 933a2f70a1..d81a5d5755 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -232,6 +232,10 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val parents = addSerializable(abstractFunctionErasedType)
val funOwner = originalFunction.symbol.owner
+ // TODO harmonize the naming of delamdafy anon-fun classes with those spun up by Uncurry
+ // - make `anonClass.isAnonymousClass` true.
+ // - use `newAnonymousClassSymbol` or push the required variations into a similar factory method
+ // - reinstate the assertion in `Erasure.resolveAnonymousBridgeClash`
val suffix = "$lambda$" + (
if (funOwner.isPrimaryConstructor) ""
else "$" + funOwner.name
@@ -282,18 +286,11 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
if (sym == NoSymbol) sym.toString
else s"$sym: ${sym.tpe} in ${sym.owner}"
- def clashError(bm: Symbol) = {
- unit.error(
- applyMethodDef.symbol.pos,
- sm"""bridge generated for member ${fulldef(applyMethodDef.symbol)}
- |which overrides ${fulldef(getMember(abstractFunctionErasedType.typeSymbol, nme.apply))}
- |clashes with definition of the member itself;
- |both have erased type ${exitingPostErasure(bm.tpe)}""")
- }
-
bridgeMethod foreach (bm =>
+ // TODO SI-6260 maybe just create the apply method with the signature (Object => Object) in all cases
+ // rather than the method+bridge pair.
if (bm.symbol.tpe =:= applyMethodDef.symbol.tpe)
- clashError(bm.symbol)
+ erasure.resolveAnonymousBridgeClash(applyMethodDef.symbol, bm.symbol)
)
val body = members ++ List(constr, applyMethodDef) ++ bridgeMethod
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index ccfddab94a..60c1553ef3 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -403,19 +403,19 @@ abstract class Erasure extends AddInterfaces
* @param other The overidden symbol for which the bridge was generated
* @param bridge The bridge
*/
- def checkBridgeOverrides(member: Symbol, other: Symbol, bridge: Symbol): Boolean = {
+ def checkBridgeOverrides(member: Symbol, other: Symbol, bridge: Symbol): Seq[(Position, String)] = {
def fulldef(sym: Symbol) =
if (sym == NoSymbol) sym.toString
else s"$sym: ${sym.tpe} in ${sym.owner}"
var noclash = true
+ val clashErrors = mutable.Buffer[(Position, String)]()
def clashError(what: String) = {
- noclash = false
- unit.error(
- if (member.owner == root) member.pos else root.pos,
- sm"""bridge generated for member ${fulldef(member)}
- |which overrides ${fulldef(other)}
- |clashes with definition of $what;
- |both have erased type ${exitingPostErasure(bridge.tpe)}""")
+ val pos = if (member.owner == root) member.pos else root.pos
+ val msg = sm"""bridge generated for member ${fulldef(member)}
+ |which overrides ${fulldef(other)}
+ |clashes with definition of $what;
+ |both have erased type ${exitingPostErasure(bridge.tpe)}"""
+ clashErrors += Tuple2(pos, msg)
}
for (bc <- root.baseClasses) {
if (settings.debug)
@@ -440,7 +440,7 @@ abstract class Erasure extends AddInterfaces
}
}
}
- noclash
+ clashErrors
}
/** TODO - work through this logic with a fine-toothed comb, incorporating
@@ -478,8 +478,18 @@ abstract class Erasure extends AddInterfaces
bridge setInfo (otpe cloneInfo bridge)
bridgeTarget(bridge) = member
- if (!(member.tpe exists (_.typeSymbol.isDerivedValueClass)) ||
- checkBridgeOverrides(member, other, bridge)) {
+ def sigContainsValueClass = (member.tpe exists (_.typeSymbol.isDerivedValueClass))
+
+ val shouldAdd = (
+ !sigContainsValueClass
+ || (checkBridgeOverrides(member, other, bridge) match {
+ case Nil => true
+ case es if member.owner.isAnonymousClass => resolveAnonymousBridgeClash(member, bridge); true
+ case es => for ((pos, msg) <- es) unit.error(pos, msg); false
+ })
+ )
+
+ if (shouldAdd) {
exitingErasure(root.info.decls enter bridge)
if (other.owner == root) {
exitingErasure(root.info.decls.unlink(other))
@@ -1127,5 +1137,13 @@ abstract class Erasure extends AddInterfaces
}
}
+ final def resolveAnonymousBridgeClash(sym: Symbol, bridge: Symbol) {
+ // TODO reinstate this after Delambdafy generates anonymous classes that meet this requirement.
+ // require(sym.owner.isAnonymousClass, sym.owner)
+ log(s"Expanding name of ${sym.debugLocationString} as it clashes with bridge. Renaming deemed safe because the owner is anonymous.")
+ sym.expandName(sym.owner)
+ bridge.resetFlag(BRIDGE)
+ }
+
private class TypeRefAttachment(val tpe: TypeRef)
}
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 870eafbf20..bbd11efa7e 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -24,7 +24,12 @@ abstract class OverridingPairs extends SymbolPairs {
/** Symbols to exclude: Here these are constructors and private/artifact symbols,
* including bridges. But it may be refined in subclasses.
*/
- override protected def exclude(sym: Symbol) = sym.isPrivateLocal || sym.isArtifact || sym.isConstructor
+ override protected def exclude(sym: Symbol) = (
+ sym.isPrivateLocal
+ || sym.isArtifact
+ || sym.isConstructor
+ || (sym.isPrivate && sym.owner != base) // Privates aren't inherited. Needed for pos/t7475a.scala
+ )
/** Types always match. Term symbols match if their member types
* relative to `self` match.
diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
index cc78e27282..32987fed8c 100644
--- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
@@ -8,7 +8,7 @@ package transform
/** This phase maps ErasedValueTypes to the underlying unboxed representation and
* performs peephole optimizations.
*/
-trait PostErasure extends InfoTransform with TypingTransformers {
+trait PostErasure extends InfoTransform with TypingTransformers with scala.reflect.internal.transform.PostErasure {
val global: Global
import global._
@@ -19,16 +19,6 @@ trait PostErasure extends InfoTransform with TypingTransformers {
def newTransformer(unit: CompilationUnit): Transformer = new PostErasureTransformer(unit)
override def changesBaseClasses = false
- object elimErasedValueType extends TypeMap {
- def apply(tp: Type) = tp match {
- case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp)))
- case ErasedValueType(_, underlying) => underlying
- case _ => mapOver(tp)
- }
- }
-
- def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp)
-
class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
override def transform(tree: Tree) = {
def finish(res: Tree) = logResult(s"Posterasure reduction\n Old: $tree\n New")(res)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index e5907e1a0f..c065fb54b7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -89,6 +89,8 @@ trait Contexts { self: Analyzer =>
if (settings.noimports) Nil
else if (unit.isJava) RootImports.javaList
else if (settings.nopredef || treeInfo.noPredefImportForUnit(unit.body)) {
+ // SI-8258 Needed for the presentation compiler using -sourcepath, otherwise cycles can occur. See the commit
+ // message for this ticket for an example.
debuglog("Omitted import of Predef._ for " + unit)
RootImports.javaAndScalaList
}
@@ -457,7 +459,9 @@ trait Contexts { self: Analyzer =>
c.prefix = prefixInChild
c.enclClass = if (isTemplateOrPackage) c else enclClass
c(ConstructorSuffix) = !isTemplateOrPackage && c(ConstructorSuffix)
- c.enclMethod = if (isDefDef) c else enclMethod
+
+ // SI-8245 `isLazy` need to skip lazy getters to ensure `return` binds to the right place
+ c.enclMethod = if (isDefDef && !owner.isLazy) c else enclMethod
registerContext(c.asInstanceOf[analyzer.Context])
debuglog("[context] ++ " + c.unit + " / " + tree.summaryString)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 997fd6fc65..2d6c94349b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -174,7 +174,8 @@ trait Infer extends Checkable {
private lazy val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR)
/** The context-dependent inferencer part */
- class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable {
+ abstract class Inferencer extends InferencerContextErrors with InferCheckable {
+ def context: Context
import InferErrorGen._
/* -- Error Messages --------------------------------------------------- */
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index cf82d6baac..677c94e063 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -620,9 +620,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
val expanded1 = atPos(enclosingMacroPosition.makeTransparent)(Typed(expanded0, TypeTree(innerPt)))
typecheck("blackbox typecheck", expanded1, outerPt)
} else {
- val expanded1 = expanded0
- val expanded2 = typecheck("whitebox typecheck #1", expanded1, outerPt)
- typecheck("whitebox typecheck #2", expanded2, innerPt)
+ // whitebox expansions need to be typechecked against WildcardType first in order to avoid SI-6992 and SI-8048
+ // then we typecheck against innerPt, not against outerPt in order to prevent SI-8209
+ val expanded1 = typecheck("whitebox typecheck #0", expanded0, WildcardType)
+ val expanded2 = typecheck("whitebox typecheck #1", expanded1, innerPt)
+ typecheck("whitebox typecheck #2", expanded2, outerPt)
}
}
override def onDelayed(delayed: Tree) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index ec2b7d49f5..ba183fe3e6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -427,7 +427,7 @@ trait MethodSynthesis {
override def derivedSym = basisSym.lazyAccessor
override def derivedTree: DefDef = {
val ValDef(_, _, tpt0, rhs0) = tree
- val rhs1 = transformed.getOrElse(rhs0, rhs0)
+ val rhs1 = context.unit.transformed.getOrElse(rhs0, rhs0)
val body = (
if (tree.symbol.owner.isTrait || hasUnitType(basisSym)) rhs1
else gen.mkAssignAndReturn(basisSym, rhs1)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 645f267a21..60cae0c880 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1205,7 +1205,7 @@ trait Namers extends MethodSynthesis {
* flag.
*/
private def addDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef], overriddenSymbol: => Symbol) {
- val DefDef(_, _, rtparams0, rvparamss0, _, _) = resetLocalAttrs(ddef.duplicate)
+ val DefDef(_, _, rtparams0, rvparamss0, _, _) = resetAttrs(ddef.duplicate)
// having defs here is important to make sure that there's no sneaky tree sharing
// in methods with multiple default parameters
def rtparams = rtparams0.map(_.duplicate)
@@ -1292,7 +1292,7 @@ trait Namers extends MethodSynthesis {
return // fix #3649 (prevent crash in erroneous source code)
}
}
- val ClassDef(_, _, rtparams, _) = resetLocalAttrs(cdef.duplicate)
+ val ClassDef(_, _, rtparams, _) = resetAttrs(cdef.duplicate)
defTparams = rtparams.map(rt => copyTypeDef(rt)(mods = rt.mods &~ (COVARIANT | CONTRAVARIANT)))
nmr
}
@@ -1408,12 +1408,18 @@ trait Namers extends MethodSynthesis {
if (expr1.isErrorTyped)
ErrorType
else {
- if (!treeInfo.isStableIdentifierPattern(expr1))
- typer.TyperErrorGen.UnstableTreeError(expr1)
+ expr1 match {
+ case This(_) =>
+ // SI-8207 okay, typedIdent expands Ident(self) to C.this which doesn't satisfy the next case
+ // TODO should we change `typedIdent` not to expand to the `Ident` to a `This`?
+ case _ if treeInfo.isStableIdentifierPattern(expr1) =>
+ case _ =>
+ typer.TyperErrorGen.UnstableTreeError(expr1)
+ }
val newImport = treeCopy.Import(imp, expr1, selectors).asInstanceOf[Import]
checkSelectors(newImport)
- transformed(imp) = newImport
+ context.unit.transformed(imp) = newImport
// copy symbol and type attributes back into old expression
// so that the structure builder will find it.
expr setSymbol expr1.symbol setType expr1.tpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 46ff98875f..6a4df415ae 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -173,7 +173,7 @@ trait NamesDefaults { self: Analyzer =>
// setSymbol below is important because the 'selected' function might be overloaded. by
// assigning the correct method symbol, typedSelect will just assign the type. the reason
// to still call 'typed' is to correctly infer singleton types, SI-5259.
- val selectPos =
+ val selectPos =
if(qual.pos.isRange && baseFun.pos.isRange) qual.pos.union(baseFun.pos).withStart(Math.min(qual.pos.end, baseFun.pos.end))
else baseFun.pos
val f = blockTyper.typedOperator(Select(newQual, selected).setSymbol(baseFun1.symbol).setPos(selectPos))
@@ -287,7 +287,7 @@ trait NamesDefaults { self: Analyzer =>
}
else {
// TODO In 83c9c764b, we tried to a stable type here to fix SI-7234. But the resulting TypeTree over a
- // singleton type without an original TypeTree fails to retypecheck after a resetLocalAttrs (SI-7516),
+ // singleton type without an original TypeTree fails to retypecheck after a resetAttrs (SI-7516),
// which is important for (at least) macros.
arg.tpe
}
@@ -310,7 +310,7 @@ trait NamesDefaults { self: Analyzer =>
new ChangeOwnerTraverser(context.owner, sym) traverse arg // fixes #4502
if (repeated) arg match {
case WildcardStarArg(expr) => expr
- case _ => blockTyper typed gen.mkSeqApply(resetLocalAttrs(arg))
+ case _ => blockTyper typed gen.mkSeqApply(resetAttrs(arg))
} else arg
}
Some(atPos(body.pos)(ValDef(sym, body).setType(NoType)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index f7684b93af..2125e281f0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1414,7 +1414,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case TypeRef(pre, sym, args) =>
tree match {
case tt: TypeTree if tt.original == null => // SI-7783 don't warn about inferred types
- // FIXME: reconcile this check with one in resetAllAttrs
+ // FIXME: reconcile this check with one in resetAttrs
case _ => checkUndesiredProperties(sym, tree.pos)
}
if(sym.isJavaDefined)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 101e1526fe..1a53fef4aa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -13,7 +13,7 @@ package scala
package tools.nsc
package typechecker
-import scala.collection.{ mutable, immutable }
+import scala.collection.{mutable, immutable}
import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance }
import mutable.ListBuffer
import symtab.Flags._
@@ -39,7 +39,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// namer calls typer.computeType(rhs) on DefDef / ValDef when tpt is empty. the result
// is cached here and re-used in typedDefDef / typedValDef
// Also used to cache imports type-checked by namer.
- val transformed = new mutable.HashMap[Tree, Tree]
+ val transformed = new mutable.AnyRefMap[Tree, Tree]
final val shortenImports = false
@@ -52,7 +52,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
//println("resetTyper called")
resetContexts()
resetImplicits()
- transformed.clear()
resetDocComments()
}
@@ -108,7 +107,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val runDefinitions = currentRun.runDefinitions
import runDefinitions._
- val infer = new Inferencer(context0) {
+ private val transformed: mutable.Map[Tree, Tree] = unit.transformed
+
+ val infer = new Inferencer {
+ def context = Typer.this.context
// See SI-3281 re undoLog
override def isCoercible(tp: Type, pt: Type) = undoLog undo viewExists(tp, pt)
}
@@ -832,7 +834,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
else tpr.typed(withImplicitArgs, mode, pt)
}
orElse { _ =>
- val resetTree = resetLocalAttrs(original)
+ val resetTree = resetAttrs(original)
debuglog(s"fallback on implicits: ${tree}/$resetTree")
val tree1 = typed(resetTree, mode)
// Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
@@ -2307,7 +2309,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
context.scope.unlink(ldef.symbol)
val sym2 = namer.enterInScope(
context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe))
- val rhs2 = typed(resetAllAttrs(ldef.rhs), restpe)
+ val LabelDef(_, _, rhs1) = resetAttrs(ldef)
+ val rhs2 = typed(rhs1, restpe)
ldef.params foreach (param => param setType param.symbol.tpe)
deriveLabelDef(ldef)(_ => rhs2) setSymbol sym2 setType restpe
}
@@ -2589,7 +2592,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
//
// Well behaved trees satisfy the property:
//
- // typed(tree) == typed(resetLocalAttrs(typed(tree))
+ // typed(tree) == typed(resetAttrs(typed(tree))
//
// Trees constructed without low-level symbol manipulation get this for free;
// references to local symbols are cleared by `ResetAttrs`, but bind to the
@@ -4888,20 +4891,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
asym setInfo logResult(s"Updating bounds of ${asym.fullLocationString} in $tree from '$abounds' to")(TypeBounds(lo, hi))
}
if (asym != null && asym.isAbstractType) {
- // See pos/t1786 to follow what's happening here.
- def canEnhanceIdent = (
- asym.hasCompleteInfo
- && tparam.exists /* sometimes it is NoSymbol */
- && tparam.hasCompleteInfo /* SI-2940 */
- && !tparam.isFBounded /* SI-2251 */
- && !tparam.isHigherOrderTypeParameter
- && !(abounds.hi <:< tbounds.hi)
- && asym.isSynthetic /* this limits us to placeholder tparams, excluding named ones */
- )
arg match {
- case Bind(_, _) => enhanceBounds()
- case Ident(name) if canEnhanceIdent => enhanceBounds()
- case _ =>
+ // I removed the Ident() case that partially fixed SI-1786,
+ // because the stricter bounds being inferred broke e.g., slick
+ // worse, the fix was compilation order-dependent
+ // sharpenQuantifierBounds (used in skolemizeExistential) has an alternative fix (SI-6169) that's less invasive
+ case Bind(_, _) => enhanceBounds()
+ case _ =>
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index ffac29b4b8..cc2d9141ce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -52,13 +52,13 @@ trait Unapplies extends ast.TreeDSL {
}
private def constrParamss(cdef: ClassDef): List[List[ValDef]] = {
- val ClassDef(_, _, _, Template(_, _, body)) = resetLocalAttrs(cdef.duplicate)
+ val ClassDef(_, _, _, Template(_, _, body)) = resetAttrs(cdef.duplicate)
val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor body
vparamss
}
private def constrTparamsInvariant(cdef: ClassDef): List[TypeDef] = {
- val ClassDef(_, _, tparams, _) = resetLocalAttrs(cdef.duplicate)
+ val ClassDef(_, _, tparams, _) = resetAttrs(cdef.duplicate)
val tparamsInvariant = tparams.map(tparam => copyTypeDef(tparam)(mods = tparam.mods &~ (COVARIANT | CONTRAVARIANT)))
tparamsInvariant
}
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index 4237f36ade..bd95fdbb50 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -7,7 +7,7 @@ package scala
package tools
package nsc
-import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter }
+import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter, Reader }
package object util {
// forwarder for old code that builds against 2.9 and 2.10
@@ -46,6 +46,17 @@ package object util {
(result, ts2 filterNot (ts1 contains _))
}
+ def stringFromReader(reader: Reader) = {
+ val writer = new StringWriter()
+ var c = reader.read()
+ while(c != -1) {
+ writer.write(c)
+ c = reader.read()
+ }
+ reader.close()
+ writer.toString()
+ }
+
/** Generate a string using a routine that wants to write on a stream. */
def stringFromWriter(writer: PrintWriter => Unit): String = {
val stringWriter = new StringWriter()
diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
index f8ded56ec6..6f369212ad 100644
--- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
@@ -12,9 +12,10 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val
extends Global(currentSettings, reporter) with scala.tools.reflect.ReflectSetup with scala.reflect.runtime.SymbolTable {
override def transformedType(sym: Symbol) =
- erasure.transformInfo(sym,
- uncurry.transformInfo(sym,
- refChecks.transformInfo(sym, sym.info)))
+ postErasure.transformInfo(sym,
+ erasure.transformInfo(sym,
+ uncurry.transformInfo(sym,
+ refChecks.transformInfo(sym, sym.info))))
override def isCompilerUniverse = true
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index 4c1bc794bc..4a3db09909 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -71,12 +71,6 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*/
def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree
- /** Recursively resets symbols and types in a given tree.
- * WARNING: Don't use this API, go for [[untypecheck]] instead.
- */
- @deprecated("Use `tb.untypecheck` instead", "2.11.0")
- def resetAllAttrs(tree: u.Tree): u.Tree
-
/** Recursively resets locally defined symbols and types in a given tree.
* WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
@@ -102,6 +96,15 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*/
def compile(tree: u.Tree): () => Any
+ /** Defines a top-level class, trait or module in this ToolBox,
+ * putting it into a uniquely-named package and returning a symbol that references the defined entity.
+ * For a ClassDef, a ClassSymbol is returned, and for a ModuleDef, a ModuleSymbol is returned (not a module class, but a module itself).
+ *
+ * This method can be used to generate definitions that will later be re-used by subsequent calls to
+ * `compile`, `define` or `eval`. To refer to the generated definition in a tree, use q"$sym".
+ */
+ def define(tree: u.ImplDef): u.Symbol
+
/** Compiles and runs a tree using this ToolBox.
* Is equivalent to `compile(tree)()`.
*/
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 4a8c91bd1b..7bae3203c2 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -193,6 +193,19 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg))
})
+ private def wrapInPackageAndCompile(packageName: TermName, tree: ImplDef): Symbol = {
+ val pdef = PackageDef(Ident(packageName), List(tree))
+ val unit = new CompilationUnit(NoSourceFile)
+ unit.body = pdef
+
+ val run = new Run
+ reporter.reset()
+ run.compileUnits(List(unit), run.namerPhase)
+ throwIfErrors()
+
+ tree.symbol
+ }
+
def compile(expr0: Tree): () => Any = {
val expr = wrapIntoTerm(expr0)
@@ -200,7 +213,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order
verify(expr)
- def wrap(expr0: Tree): ModuleDef = {
+ def wrapInModule(expr0: Tree): ModuleDef = {
val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true)
val (obj, _) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol(
@@ -236,22 +249,15 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
NoPosition))
trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
- val cleanedUp = resetLocalAttrs(moduledef)
+ val cleanedUp = resetAttrs(moduledef)
trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value))
cleanedUp.asInstanceOf[ModuleDef]
}
- val mdef = wrap(expr)
- val pdef = PackageDef(Ident(mdef.name), List(mdef))
- val unit = new CompilationUnit(NoSourceFile)
- unit.body = pdef
+ val mdef = wrapInModule(expr)
+ val msym = wrapInPackageAndCompile(mdef.name, mdef)
- val run = new Run
- reporter.reset()
- run.compileUnits(List(unit), run.namerPhase)
- throwIfErrors()
-
- val className = mdef.symbol.fullName
+ val className = msym.fullName
if (settings.debug) println("generated: "+className)
def moduleFileName(className: String) = className + "$"
val jclazz = jClass.forName(moduleFileName(className), true, classLoader)
@@ -278,6 +284,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
}
+ def define(tree: ImplDef): Symbol = {
+ val freeTerms = tree.freeTerms
+ if (freeTerms.nonEmpty) throw ToolBoxError(s"reflective toolbox has failed: cannot have free terms in a top-level definition")
+ verify(tree)
+ wrapInPackageAndCompile(nextWrapperModuleName(), tree)
+ }
+
def parse(code: String): Tree = {
reporter.reset()
val tree = gen.mkTreeOrBlock(newUnitParser(code, "<toolbox>").parseStatsOrPackages())
@@ -385,18 +398,10 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
uitree
}
- def resetAllAttrs(tree: u.Tree): u.Tree = withCompilerApi { compilerApi =>
- import compilerApi._
- val ctree: compiler.Tree = importer.importTree(tree)
- val ttree: compiler.Tree = compiler.resetAllAttrs(ctree)
- val uttree = exporter.importTree(ttree)
- uttree
- }
-
def resetLocalAttrs(tree: u.Tree): u.Tree = withCompilerApi { compilerApi =>
import compilerApi._
val ctree: compiler.Tree = importer.importTree(tree)
- val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree)
+ val ttree: compiler.Tree = compiler.resetAttrs(ctree)
val uttree = exporter.importTree(ttree)
uttree
}
@@ -421,6 +426,18 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
compiler.compile(ctree)
}
+ def define(tree: u.ImplDef): u.Symbol = withCompilerApi { compilerApi =>
+ import compilerApi._
+
+ if (compiler.settings.verbose) println("importing "+tree)
+ val ctree: compiler.ImplDef = importer.importTree(tree).asInstanceOf[compiler.ImplDef]
+
+ if (compiler.settings.verbose) println("defining "+ctree)
+ val csym: compiler.Symbol = compiler.define(ctree)
+ val usym = exporter.importSymbol(csym)
+ usym
+ }
+
def eval(tree: u.Tree): Any = compile(tree)()
}
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
index fcb8734644..9f6807fe17 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
@@ -200,7 +200,7 @@ trait Parsers { self: Quasiquotes =>
object PatternParser extends Parser {
def entryPoint = { parser =>
- val pat = parser.noSeq.pattern1()
+ val pat = parser.noSeq.pattern()
gen.patvarTransformer.transform(pat)
}
}
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index 0e897d6492..95027a26b1 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -534,7 +534,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
threadId += 1
compileRunner = new PresentationCompilerThread(this, projectName)
compileRunner.setDaemon(true)
- compileRunner.start()
compileRunner
}
@@ -638,6 +637,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
unit.problems.clear()
unit.body = EmptyTree
unit.status = NotLoaded
+ unit.transformed.clear()
}
/** Parse unit and create a name index, unless this has already been done before */
@@ -1252,11 +1252,21 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
forceSymbolsUsedByParser()
+ /** Start the compiler background thread and turn on thread confinement checks */
+ private def finishInitialization(): Unit = {
+ // this flag turns on `assertCorrectThread checks`
+ initializing = false
+
+ // Only start the thread if initialization was successful. A crash while forcing symbols (for example
+ // if the Scala library is not on the classpath) can leave running threads behind. See Scala IDE #1002016
+ compileRunner.start()
+ }
+
/** The compiler has been initialized. Constructors are evaluated in textual order,
- * so this is set to true only after all super constructors and the primary constructor
+ * if we reached here, all super constructors and the primary constructor
* have been executed.
*/
- initializing = false
+ finishInitialization()
}
object CancelException extends Exception
diff --git a/src/library-aux/scala/AnyRef.scala b/src/library-aux/scala/AnyRef.scala
index 362fbcf0f5..8c1862e729 100644
--- a/src/library-aux/scala/AnyRef.scala
+++ b/src/library-aux/scala/AnyRef.scala
@@ -76,8 +76,8 @@ trait AnyRef extends Any {
* @param arg0 the object to compare against this object for equality.
* @return `true` if the receiver object is equivalent to the argument; `false` otherwise.
*/
- final def ==(that: AnyRef): Boolean =
- if (this eq null) that eq null
+ final def ==(that: Any): Boolean =
+ if (this eq null) that.asInstanceOf[AnyRef] eq null
else this equals that
/** Create a copy of the receiver object.
diff --git a/src/library/scala/collection/Iterable.scala b/src/library/scala/collection/Iterable.scala
index 973efc447e..a5ab8efd5c 100644
--- a/src/library/scala/collection/Iterable.scala
+++ b/src/library/scala/collection/Iterable.scala
@@ -51,4 +51,4 @@ object Iterable extends TraversableFactory[Iterable] {
}
/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractIterable[+A] extends AbstractTraversable[A] with Iterable[A]
+abstract class AbstractIterable[+A] extends AbstractTraversable[A] with Iterable[A]
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 72a23a0dd0..01a0aa3b51 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -1171,4 +1171,4 @@ trait Iterator[+A] extends TraversableOnce[A] {
}
/** Explicit instantiation of the `Iterator` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractIterator[+A] extends Iterator[A]
+abstract class AbstractIterator[+A] extends Iterator[A]
diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala
index 761b65723c..1e40fd8c24 100644
--- a/src/library/scala/collection/Map.scala
+++ b/src/library/scala/collection/Map.scala
@@ -56,4 +56,4 @@ object Map extends MapFactory[Map] {
}
/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractMap[A, +B] extends AbstractIterable[(A, B)] with Map[A, B]
+abstract class AbstractMap[A, +B] extends AbstractIterable[(A, B)] with Map[A, B]
diff --git a/src/library/scala/collection/Seq.scala b/src/library/scala/collection/Seq.scala
index b21acdd9b7..2f4b3e5f8a 100644
--- a/src/library/scala/collection/Seq.scala
+++ b/src/library/scala/collection/Seq.scala
@@ -38,4 +38,4 @@ object Seq extends SeqFactory[Seq] {
}
/** Explicit instantiation of the `Seq` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractSeq[+A] extends AbstractIterable[A] with Seq[A]
+abstract class AbstractSeq[+A] extends AbstractIterable[A] with Seq[A]
diff --git a/src/library/scala/collection/Set.scala b/src/library/scala/collection/Set.scala
index 46d5dfa056..f74c26571a 100644
--- a/src/library/scala/collection/Set.scala
+++ b/src/library/scala/collection/Set.scala
@@ -44,4 +44,4 @@ object Set extends SetFactory[Set] {
}
/** Explicit instantiation of the `Set` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A]
+abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A]
diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala
index 61d9a42f04..b53724c568 100644
--- a/src/library/scala/collection/Traversable.scala
+++ b/src/library/scala/collection/Traversable.scala
@@ -101,4 +101,4 @@ object Traversable extends TraversableFactory[Traversable] { self =>
}
/** Explicit instantiation of the `Traversable` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractTraversable[+A] extends Traversable[A]
+abstract class AbstractTraversable[+A] extends Traversable[A]
diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala
index 8933c7cf77..5178d5a862 100644
--- a/src/library/scala/collection/immutable/Map.scala
+++ b/src/library/scala/collection/immutable/Map.scala
@@ -32,9 +32,9 @@ trait Map[A, +B] extends Iterable[(A, B)]
with MapLike[A, B, Map[A, B]] { self =>
override def empty: Map[A, B] = Map.empty
-
+
/** Returns this $coll as an immutable map.
- *
+ *
* A new map will not be built; lazy collections will stay lazy.
*/
@deprecatedOverriding("Immutable maps should do nothing on toMap except return themselves cast as a map.", "2.11.0")
@@ -191,4 +191,4 @@ object Map extends ImmutableMapFactory[Map] {
}
/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractMap[A, +B] extends scala.collection.AbstractMap[A, B] with Map[A, B]
+abstract class AbstractMap[A, +B] extends scala.collection.AbstractMap[A, B] with Map[A, B]
diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala
index 29c92a111c..47fb66744e 100644
--- a/src/library/scala/collection/mutable/AnyRefMap.scala
+++ b/src/library/scala/collection/mutable/AnyRefMap.scala
@@ -22,9 +22,9 @@ import generic.CanBuildFrom
* on a map that will no longer have elements removed but will be
* used heavily may save both time and storage space.
*
- * This map is not indended to contain more than 2^29 entries (approximately
- * 500 million). The maximum capacity is 2^30, but performance will degrade
- * rapidly as 2^30 is approached.
+ * This map is not intended to contain more than 2^29^ entries (approximately
+ * 500 million). The maximum capacity is 2^30^, but performance will degrade
+ * rapidly as 2^30^ is approached.
*
*/
final class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initialBufferSize: Int, initBlank: Boolean)
@@ -291,24 +291,21 @@ extends AbstractMap[K, V]
private[this] val vz = _values
private[this] var index = 0
- private[this] var found = false
- def hasNext = found || (index<hz.length && {
+ def hasNext: Boolean = index<hz.length && {
var h = hz(index)
- if (h+h != 0) found = true
- else {
+ while (h+h == 0) {
index += 1
- while (index < hz.length && { h = hz(index); h+h == 0 }) index += 1
- found = (index < hz.length)
+ if (index >= hz.length) return false
+ h = hz(index)
}
- found
- })
+ true
+ }
- def next = {
- if (found || hasNext) {
- val ans = (_keys(index).asInstanceOf[K], _values(index).asInstanceOf[V])
+ def next: (K, V) = {
+ if (hasNext) {
+ val ans = (kz(index).asInstanceOf[K], vz(index).asInstanceOf[V])
index += 1
- found = false
ans
}
else throw new NoSuchElementException("next")
diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala
index d2e33badbe..7ec7b06333 100644
--- a/src/library/scala/collection/mutable/Buffer.scala
+++ b/src/library/scala/collection/mutable/Buffer.scala
@@ -46,4 +46,4 @@ object Buffer extends SeqFactory[Buffer] {
}
/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A]
+abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A]
diff --git a/src/library/scala/collection/mutable/Iterable.scala b/src/library/scala/collection/mutable/Iterable.scala
index f7a794e357..92313c9ccd 100644
--- a/src/library/scala/collection/mutable/Iterable.scala
+++ b/src/library/scala/collection/mutable/Iterable.scala
@@ -38,4 +38,4 @@ object Iterable extends TraversableFactory[Iterable] {
}
/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractIterable[A] extends scala.collection.AbstractIterable[A] with Iterable[A]
+abstract class AbstractIterable[A] extends scala.collection.AbstractIterable[A] with Iterable[A]
diff --git a/src/library/scala/collection/mutable/Map.scala b/src/library/scala/collection/mutable/Map.scala
index 01f6f725ab..fe29ce4221 100644
--- a/src/library/scala/collection/mutable/Map.scala
+++ b/src/library/scala/collection/mutable/Map.scala
@@ -89,4 +89,4 @@ object Map extends MutableMapFactory[Map] {
}
/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractMap[A, B] extends scala.collection.AbstractMap[A, B] with Map[A, B]
+abstract class AbstractMap[A, B] extends scala.collection.AbstractMap[A, B] with Map[A, B]
diff --git a/src/library/scala/collection/mutable/Seq.scala b/src/library/scala/collection/mutable/Seq.scala
index 11fbdd13f3..eafde70a2d 100644
--- a/src/library/scala/collection/mutable/Seq.scala
+++ b/src/library/scala/collection/mutable/Seq.scala
@@ -45,4 +45,4 @@ object Seq extends SeqFactory[Seq] {
}
/** Explicit instantiation of the `Seq` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractSeq[A] extends scala.collection.AbstractSeq[A] with Seq[A]
+abstract class AbstractSeq[A] extends scala.collection.AbstractSeq[A] with Seq[A]
diff --git a/src/library/scala/collection/mutable/Set.scala b/src/library/scala/collection/mutable/Set.scala
index 4439880976..97574718e8 100644
--- a/src/library/scala/collection/mutable/Set.scala
+++ b/src/library/scala/collection/mutable/Set.scala
@@ -43,4 +43,4 @@ object Set extends MutableSetFactory[Set] {
}
/** Explicit instantiation of the `Set` trait to reduce class file size in subclasses. */
-private[scala] abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A]
+abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A]
diff --git a/src/library/scala/io/StdIn.scala b/src/library/scala/io/StdIn.scala
index 36568b59b7..64836ecd6e 100644
--- a/src/library/scala/io/StdIn.scala
+++ b/src/library/scala/io/StdIn.scala
@@ -17,7 +17,7 @@ private[scala] trait StdIn {
*/
def readLine(): String = in.readLine()
- /** Print formatted text to the default output and read a full line from the default input.
+ /** Print and flush formatted text to the default output, and read a full line from the default input.
* Returns `null` if the end of the input stream has been reached.
*
* @param text the format of the text to print out, as in `printf`.
@@ -26,6 +26,7 @@ private[scala] trait StdIn {
*/
def readLine(text: String, args: Any*): String = {
printf(text, args: _*)
+ out.flush()
readLine()
}
diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala
index 88c0cf8e58..ac86495001 100644
--- a/src/library/scala/sys/process/ProcessBuilder.scala
+++ b/src/library/scala/sys/process/ProcessBuilder.scala
@@ -30,9 +30,7 @@ import ProcessBuilder._
* "ls".!
*
* // Execute "ls" and assign a `Stream[String]` of its output to "contents".
- * // Because [[scala.Predef]] already defines a `lines` method for `String`,
- * // we use [[scala.sys.process.Process]]'s object companion to create it.
- * val contents = Process("ls").lines
+ * val contents = Process("ls").lineStream
*
* // Here we use a `Seq` to make the parameter whitespace-safe
* def contentsOf(dir: String): String = Seq("ls", dir).!!
@@ -82,11 +80,11 @@ import ProcessBuilder._
* of the last one in the chain of execution.
* - `!!`: blocks until all external commands exit, and returns a `String`
* with the output generated.
- * - `lines`: returns immediately like `run`, and the output being generared
+ * - `lineStream`: returns immediately like `run`, and the output being generated
* is provided through a `Stream[String]`. Getting the next element of that
* `Stream` may block until it becomes available. This method will throw an
* exception if the return code is different than zero -- if this is not
- * desired, use the `lines_!` method.
+ * desired, use the `lineStream_!` method.
*
* ==Handling Input and Output==
*
@@ -131,6 +129,14 @@ import ProcessBuilder._
*
* Note: though it is not shown above, the equivalent of a shell's `;` would be
* `###`. The reason for this name is that `;` is a reserved token in Scala.
+ *
+ * Note: the `lines` method, though deprecated, may conflict with the `StringLike`
+ * method of the same name. To avoid this, one may wish to call the builders in
+ * `Process` instead of importing `scala.sys.process._`. The example above would be
+ * {{{
+ * import scala.sys.process.Process
+ * Process("find src -name *.scala -exec grep null {} ;") #| Process("xargs test -z") #&& Process("echo null-free") #|| Process("echo null detected") !
+ * }}}
*/
trait ProcessBuilder extends Source with Sink {
/** Starts the process represented by this builder, blocks until it exits, and
@@ -165,7 +171,11 @@ trait ProcessBuilder extends Source with Sink {
* with a non-zero value, the Stream will provide all lines up to termination
* and then throw an exception.
*/
- def lines: Stream[String]
+ def lineStream: Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream` instead. */
+ @deprecated("Use lineStream instead.", "2.11.0")
+ def lines: Stream[String] = lineStream
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -173,7 +183,11 @@ trait ProcessBuilder extends Source with Sink {
* process exits with a non-zero value, the Stream will provide all lines up
* to termination and then throw an exception.
*/
- def lines(log: ProcessLogger): Stream[String]
+ def lineStream(log: ProcessLogger): Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream(log: ProcessLogger)` instead. */
+ @deprecated("Use stream instead.", "2.11.0")
+ def lines(log: ProcessLogger): Stream[String] = lineStream(log)
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -181,7 +195,11 @@ trait ProcessBuilder extends Source with Sink {
* with a non-zero value, the Stream will provide all lines up to termination
* but will not throw an exception.
*/
- def lines_! : Stream[String]
+ def lineStream_! : Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream_!` instead. */
+ @deprecated("Use lineStream_! instead.", "2.11.0")
+ def lines_! : Stream[String] = lineStream_!
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -189,7 +207,11 @@ trait ProcessBuilder extends Source with Sink {
* process exits with a non-zero value, the Stream will provide all lines up
* to termination but will not throw an exception.
*/
- def lines_!(log: ProcessLogger): Stream[String]
+ def lineStream_!(log: ProcessLogger): Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream_!(log: ProcessLogger)` instead. */
+ @deprecated("Use stream_! instead.", "2.11.0")
+ def lines_!(log: ProcessLogger): Stream[String] = lineStream_!(log)
/** Starts the process represented by this builder, blocks until it exits, and
* returns the exit code. Standard output and error are sent to the console.
diff --git a/src/library/scala/sys/process/ProcessBuilderImpl.scala b/src/library/scala/sys/process/ProcessBuilderImpl.scala
index adf6d1e724..236baaf038 100644
--- a/src/library/scala/sys/process/ProcessBuilderImpl.scala
+++ b/src/library/scala/sys/process/ProcessBuilderImpl.scala
@@ -104,10 +104,10 @@ private[process] trait ProcessBuilderImpl {
def !!< = slurp(None, withIn = true)
def !!<(log: ProcessLogger) = slurp(Some(log), withIn = true)
- def lines: Stream[String] = lines(withInput = false, nonZeroException = true, None)
- def lines(log: ProcessLogger): Stream[String] = lines(withInput = false, nonZeroException = true, Some(log))
- def lines_! : Stream[String] = lines(withInput = false, nonZeroException = false, None)
- def lines_!(log: ProcessLogger): Stream[String] = lines(withInput = false, nonZeroException = false, Some(log))
+ def lineStream: Stream[String] = lineStream(withInput = false, nonZeroException = true, None)
+ def lineStream(log: ProcessLogger): Stream[String] = lineStream(withInput = false, nonZeroException = true, Some(log))
+ def lineStream_! : Stream[String] = lineStream(withInput = false, nonZeroException = false, None)
+ def lineStream_!(log: ProcessLogger): Stream[String] = lineStream(withInput = false, nonZeroException = false, Some(log))
def ! = run(connectInput = false).exitValue()
def !(io: ProcessIO) = run(io).exitValue()
@@ -132,7 +132,7 @@ private[process] trait ProcessBuilderImpl {
else scala.sys.error("Nonzero exit value: " + code)
}
- private[this] def lines(
+ private[this] def lineStream(
withInput: Boolean,
nonZeroException: Boolean,
log: Option[ProcessLogger]
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
index b70426a145..6743b9e42a 100644
--- a/src/library/scala/util/matching/Regex.scala
+++ b/src/library/scala/util/matching/Regex.scala
@@ -647,9 +647,10 @@ object Regex {
/** A class to step through a sequence of regex matches.
*
* All methods inherited from [[scala.util.matching.Regex.MatchData]] will throw
- * an [[java.lang.IllegalStateException]] until the matcher is initialized by
- * calling `hasNext` or `next()` or causing these methods to be called, such as
- * by invoking `toString` or iterating through the iterator's elements.
+ * a [[java.lang.IllegalStateException]] until the matcher is initialized. The
+ * matcher can be initialized by calling `hasNext` or `next()` or causing these
+ * methods to be called, such as by invoking `toString` or iterating through
+ * the iterator's elements.
*
* @see [[java.util.regex.Matcher]]
*/
diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala
index 5667d93e29..6539137cee 100644
--- a/src/reflect/scala/reflect/api/Importers.scala
+++ b/src/reflect/scala/reflect/api/Importers.scala
@@ -52,7 +52,7 @@ package api
* val imported = importer.importTree(tree)
*
* // after the tree is imported, it can be evaluated as usual
- * val tree = toolBox.resetAllAttrs(imported.duplicate)
+ * val tree = toolBox.untypecheck(imported.duplicate)
* val valueOfX = toolBox.eval(imported).asInstanceOf[T]
* ...
* }
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index 5a03996dd9..a1292d04ef 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -143,7 +143,7 @@ trait StandardLiftables { self: Universe =>
case Apply(ScalaDot(symbol), List(Literal(Constant(name: String)))) if symbol == nme.Symbol => scala.Symbol(name)
}
- implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name}
+ implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name }
implicit def unliftType: Unliftable[Type] = Unliftable[Type] { case tt: TypeTree if tt.tpe != null => tt.tpe }
implicit def unliftConstant: Unliftable[Constant] = Unliftable[Constant] { case Literal(const) => const }
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 83da5141b9..60e00ca5fd 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -1066,7 +1066,7 @@ trait Trees { self: Universe =>
* UnApply(
* // a dummy node that carries the type of unapplication to patmat
* // the <unapply-selector> here doesn't have an underlying symbol
- * // it only has a type assigned, therefore after `resetAllAttrs` this tree is no longer typeable
+ * // it only has a type assigned, therefore after `untypecheck` this tree is no longer typeable
* Apply(Select(Ident(Foo), newTermName("unapply")), List(Ident(newTermName("<unapply-selector>")))),
* // arguments of the unapply => nothing synthetic here
* List(Bind(newTermName("x"), Ident(nme.WILDCARD)))),
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index 7457910226..be76758224 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -134,7 +134,7 @@ import scala.language.implicitConversions
* reflection APIs provided by Java (for classes) and Scala (for types).</li>
*
* <li>'''Certain manifest operations(i.e., <:<, >:> and typeArguments) are not
- * supported.''' <br/>Instead, one culd use the reflection APIs provided by Java (for
+ * supported.''' <br/>Instead, one could use the reflection APIs provided by Java (for
* classes) and Scala (for types).</li>
*</ul>
*
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 7a0c70caf6..78e639fdff 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -35,7 +35,8 @@ trait Definitions extends api.StandardDefinitions {
private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long): MethodSymbol = {
val msym = owner.newMethod(name.encode, NoPosition, flags)
val params = msym.newSyntheticValueParams(formals)
- msym setInfo MethodType(params, restpe) markAllCompleted
+ val info = if (owner.isJavaDefined) JavaMethodType(params, restpe) else MethodType(params, restpe)
+ msym setInfo info markAllCompleted
}
private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol =
owner.info.decls enter newMethod(owner, name, formals, restpe, flags)
@@ -904,8 +905,14 @@ trait Definitions extends api.StandardDefinitions {
existentialAbstraction(clazz.unsafeTypeParams, clazz.tpe_*)
// members of class scala.Any
+
+ // TODO these aren't final! They are now overriden in AnyRef/Object. Prior to the fix
+ // for SI-8129, they were actually *overloaded* by the members in AnyRef/Object.
+ // We should unfinalize these, override in AnyValClass, and make the overrides final.
+ // Refchecks never actually looks at these, so its just for consistency.
lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, AnyTpe :: Nil, BooleanTpe, FINAL)
lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, AnyTpe :: Nil, BooleanTpe, FINAL)
+
lazy val Any_equals = enterNewMethod(AnyClass, nme.equals_, AnyTpe :: Nil, BooleanTpe)
lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, IntTpe)
lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, StringTpe)
@@ -1012,8 +1019,8 @@ trait Definitions extends api.StandardDefinitions {
// members of class java.lang.{ Object, String }
lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, IntTpe, FINAL)
- lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, AnyRefTpe :: Nil, BooleanTpe, FINAL)
- lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, AnyRefTpe :: Nil, BooleanTpe, FINAL)
+ lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, AnyTpe :: Nil, BooleanTpe, FINAL)
+ lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, AnyTpe :: Nil, BooleanTpe, FINAL)
lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, AnyRefTpe :: Nil, BooleanTpe, FINAL)
lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, AnyRefTpe :: Nil, BooleanTpe, FINAL)
lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC | ARTIFACT)(_ => BooleanTpe)
diff --git a/src/reflect/scala/reflect/internal/Required.scala b/src/reflect/scala/reflect/internal/Required.scala
index 14db252a16..009bc39d4c 100644
--- a/src/reflect/scala/reflect/internal/Required.scala
+++ b/src/reflect/scala/reflect/internal/Required.scala
@@ -6,6 +6,9 @@ import settings.MutableSettings
trait Required { self: SymbolTable =>
def picklerPhase: Phase
+
+ def erasurePhase: Phase
+
def settings: MutableSettings
@deprecated("Interactive is implemented with a custom Global; this flag is ignored", "2.11.0") def forInteractive = false
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 571c4cfa5d..802bd18a4e 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -371,6 +371,8 @@ abstract class SymbolTable extends macros.Universe
def newMap[K, V]() = recordCache(mutable.HashMap[K, V]())
def newSet[K]() = recordCache(mutable.HashSet[K]())
def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]())
+
+ def newAnyRefMap[K <: AnyRef, V]() = recordCache(mutable.AnyRefMap[K, V]())
def newGeneric[T](f: => T): () => T = {
val NoCached: T = null.asInstanceOf[T]
var cached: T = NoCached
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 7bab15b0f4..8cad2497c1 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -735,6 +735,17 @@ abstract class TreeInfo {
unapply(dissectApplied(tree))
}
+ /** Does list of trees start with a definition of
+ * a class of module with given name (ignoring imports)
+ */
+ def firstDefinesClassOrObject(trees: List[Tree], name: Name): Boolean = trees match {
+ case Import(_, _) :: xs => firstDefinesClassOrObject(xs, name)
+ case Annotated(_, tree1) :: _ => firstDefinesClassOrObject(List(tree1), name)
+ case ModuleDef(_, `name`, _) :: _ => true
+ case ClassDef(_, `name`, _, _) :: _ => true
+ case _ => false
+ }
+
/** Locates the synthetic Apply node corresponding to an extractor's call to
* unapply (unwrapping nested Applies) and returns the fun part of that Apply.
*/
@@ -750,8 +761,7 @@ abstract class TreeInfo {
}
/** Is this file the body of a compilation unit which should not
- * have Predef imported? This is the case iff the first import in the
- * unit explicitly refers to Predef.
+ * have Predef imported?
*/
def noPredefImportForUnit(body: Tree) = {
// Top-level definition whose leading imports include Predef.
@@ -760,7 +770,13 @@ abstract class TreeInfo {
case Import(expr, _) => isReferenceToPredef(expr)
case _ => false
}
- isLeadingPredefImport(body)
+ // Compilation unit is class or object 'name' in package 'scala'
+ def isUnitInScala(tree: Tree, name: Name) = tree match {
+ case PackageDef(Ident(nme.scala_), defs) => firstDefinesClassOrObject(defs, name)
+ case _ => false
+ }
+
+ isUnitInScala(body, nme.Predef) || isLeadingPredefImport(body)
}
def isAbsTypeDef(tree: Tree) = tree match {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 74b2208278..cf405ade03 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -82,6 +82,7 @@ trait Types
with tpe.GlbLubs
with tpe.TypeMaps
with tpe.TypeConstraints
+ with tpe.FindMembers
with util.Collections { self: SymbolTable =>
import definitions._
@@ -243,18 +244,6 @@ trait Types
}
}
- /** Same as a call to narrow unless existentials are visible
- * after widening the type. In that case, narrow from the widened
- * type instead of the proxy. This gives buried existentials a
- * chance to make peace with the other types. See SI-5330.
- */
- private def narrowForFindMember(tp: Type): Type = {
- val w = tp.widen
- // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type.
- if ((tp ne w) && containsExistential(w)) w.narrow
- else tp.narrow
- }
-
/** The base class for all types */
abstract class Type extends TypeApiImpl with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
@@ -899,7 +888,7 @@ trait Types
-1
}
- /** If this is a poly- or methodtype, a copy with cloned type / value parameters
+ /** If this is a ExistentialType, PolyType or MethodType, a copy with cloned type / value parameters
* owned by `owner`. Identity for all other types.
*/
def cloneInfo(owner: Symbol) = this
@@ -989,64 +978,7 @@ trait Types
*
*/
def findMembers(excludedFlags: Long, requiredFlags: Long): Scope = {
- def findMembersInternal: Scope = {
- var members: Scope = null
- if (Statistics.canEnable) Statistics.incCounter(findMembersCount)
- val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMembersNanos) else null
-
- //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
- var required = requiredFlags
- var excluded = excludedFlags | DEFERRED
- var retryForDeferred = true
- var self: Type = null
- while (retryForDeferred) {
- retryForDeferred = false
- val bcs0 = baseClasses
- var bcs = bcs0
- while (!bcs.isEmpty) {
- val decls = bcs.head.info.decls
- var entry = decls.elems
- while (entry ne null) {
- val sym = entry.sym
- val flags = sym.flags
- if ((flags & required) == required) {
- val excl = flags & excluded
- if (excl == 0L &&
- (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
- (bcs eq bcs0) ||
- (flags & PrivateLocal) != PrivateLocal ||
- (bcs0.head.hasTransOwner(bcs.head)))) {
- if (members eq null) members = newFindMemberScope
- var others: ScopeEntry = members.lookupEntry(sym.name)
- var symtpe: Type = null
- while ((others ne null) && {
- val other = others.sym
- (other ne sym) &&
- ((other.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (symtpe eq null) symtpe = self.memberType(sym)
- !(self.memberType(other) matches symtpe)
- })}) {
- others = members lookupNextEntry others
- }
- if (others eq null) members enter sym
- } else if (excl == DEFERRED) {
- retryForDeferred = (excludedFlags & DEFERRED) == 0
- }
- }
- entry = entry.next
- } // while (entry ne null)
- // excluded = excluded | LOCAL
- bcs = bcs.tail
- } // while (!bcs.isEmpty)
- required |= DEFERRED
- excluded &= ~(DEFERRED.toLong)
- } // while (retryForDeferred)
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- if (members eq null) EmptyScope else members
- }
-
+ def findMembersInternal = new FindMembers(this, excludedFlags, requiredFlags).apply()
if (this.isGround) findMembersInternal
else suspendingTypeVars(typeVarsInType(this))(findMembersInternal)
}
@@ -1055,110 +987,13 @@ trait Types
* Find member(s) in this type. If several members matching criteria are found, they are
* returned in an OverloadedSymbol
*
- * @param name The member's name, where nme.ANYNAME means `unspecified`
+ * @param name The member's name
* @param excludedFlags Returned members do not have these flags
* @param requiredFlags Returned members do have these flags
* @param stableOnly If set, return only members that are types or stable values
*/
- //TODO: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = {
- def findMemberInternal: Symbol = {
- var member: Symbol = NoSymbol
- var members: List[Symbol] = null
- var lastM: ::[Symbol] = null
- if (Statistics.canEnable) Statistics.incCounter(findMemberCount)
- val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMemberNanos) else null
-
- //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
- var membertpe: Type = null
- var required = requiredFlags
- var excluded = excludedFlags | DEFERRED
- var continue = true
- var self: Type = null
-
- while (continue) {
- continue = false
- val bcs0 = baseClasses
- var bcs = bcs0
- // omit PRIVATE LOCALS unless selector class is contained in class owning the def.
- def admitPrivateLocal(owner: Symbol): Boolean = {
- val selectorClass = this match {
- case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class.
- case _ => bcs0.head
- }
- selectorClass.hasTransOwner(owner)
- }
- while (!bcs.isEmpty) {
- val decls = bcs.head.info.decls
- var entry = decls.lookupEntry(name)
- while (entry ne null) {
- val sym = entry.sym
- val flags = sym.flags
- if ((flags & required) == required) {
- val excl = flags & excluded
- if (excl == 0L &&
- (
- (bcs eq bcs0) ||
- (flags & PrivateLocal) != PrivateLocal ||
- admitPrivateLocal(bcs.head))) {
- if (name.isTypeName || (stableOnly && sym.isStable && !sym.hasVolatileType)) {
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- return sym
- } else if (member eq NoSymbol) {
- member = sym
- } else if (members eq null) {
- if ((member ne sym) &&
- ((member.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (membertpe eq null) membertpe = self.memberType(member)
- !(membertpe matches self.memberType(sym))
- })) {
- lastM = new ::(sym, null)
- members = member :: lastM
- }
- } else {
- var others: List[Symbol] = members
- var symtpe: Type = null
- while ((others ne null) && {
- val other = others.head
- (other ne sym) &&
- ((other.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (symtpe eq null) symtpe = self.memberType(sym)
- !(self.memberType(other) matches symtpe)
- })}) {
- others = others.tail
- }
- if (others eq null) {
- val lastM1 = new ::(sym, null)
- lastM.tl = lastM1
- lastM = lastM1
- }
- }
- } else if (excl == DEFERRED) {
- continue = true
- }
- }
- entry = decls lookupNextEntry entry
- } // while (entry ne null)
- // excluded = excluded | LOCAL
- bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail
- } // while (!bcs.isEmpty)
- required |= DEFERRED
- excluded &= ~(DEFERRED.toLong)
- } // while (continue)
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- if (members eq null) {
- if (member == NoSymbol) if (Statistics.canEnable) Statistics.incCounter(noMemberCount)
- member
- } else {
- if (Statistics.canEnable) Statistics.incCounter(multMemberCount)
- lastM.tl = Nil
- baseClasses.head.newOverloaded(this, members)
- }
- }
+ def findMemberInternal = new FindMember(this, name, excludedFlags, requiredFlags, stableOnly).apply()
if (this.isGround) findMemberInternal
else suspendingTypeVars(typeVarsInType(this))(findMemberInternal)
@@ -2683,8 +2518,57 @@ trait Types
override def baseTypeSeq = underlying.baseTypeSeq map maybeRewrap
override def isHigherKinded = false
- override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
+ /** [SI-6169, SI-8197 -- companion to SI-1786]
+ *
+ * Approximation to improve the bounds of a Java-defined existential type,
+ * based on the bounds of the type parameters of the quantified type
+ * In Scala syntax, given a java-defined class C[T <: String], the existential type C[_]
+ * is improved to C[_ <: String] before skolemization, which captures (get it?) what Java does:
+ * enter the type paramers' bounds into the context when checking subtyping/type equality of existential types
+ *
+ * (Also tried doing this once during class file parsing or when creating the existential type,
+ * but that causes cyclic errors because it happens too early.)
+ *
+ * TODO: figure out how to do this earlier without running into cycles, so this can subsume the fix for SI-1786
+ */
+ private def sharpenQuantifierBounds(): Unit = {
+ /* Check that we're looking at rawToExistential's handiwork
+ * (`existentialAbstraction(eparams, typeRef(apply(pre), sym, eparams map (_.tpe)))`).
+ * We can't do this sharpening there because we'll run into cycles.
+ */
+ def rawToExistentialCreatedMe = (quantified corresponds underlying.typeArgs){ (q, a) => q.tpe =:= a }
+
+ if (underlying.typeSymbol.isJavaDefined && rawToExistentialCreatedMe) {
+ val tpars = underlying.typeSymbol.initialize.typeParams // TODO: is initialize needed?
+ debuglog(s"sharpen bounds: $this | ${underlying.typeArgs.map(_.typeSymbol)} <-- ${tpars.map(_.info)}")
+
+ foreach2(quantified, tpars) { (quant, tparam) =>
+ // TODO: check `tparam.info.substSym(tpars, quantified) <:< quant.info` instead (for some weird reason not working for test/t6169/ExistF)
+ // for now, crude approximation for the common case
+ if (quant.info.bounds.isEmptyBounds && !tparam.info.bounds.isEmptyBounds) {
+ // avoid creating cycles [pos/t2940] that consist of an existential quantifier's
+ // bounded by an existential type that unhygienically has that quantifier as its own quantifier
+ // (TODO: clone latter existential with fresh quantifiers -- not covering this case for now)
+ if ((existentialsInType(tparam.info) intersect quantified).isEmpty)
+ quant setInfo tparam.info.substSym(tpars, quantified)
+ }
+ }
+ }
+
+ _sharpenQuantifierBounds = false
+ }
+ private[this] var _sharpenQuantifierBounds = true
+
+ override def skolemizeExistential(owner: Symbol, origin: AnyRef) = {
+ // do this here because it's quite close to what Java does:
+ // when checking subtyping/type equality, enter constraints
+ // derived from the existentially quantified type into the typing environment
+ // (aka \Gamma, which tracks types for variables and constraints/kinds for types)
+ // as a nice bonus, delaying this until we need it avoids cyclic errors
+ if (_sharpenQuantifierBounds) sharpenQuantifierBounds
+
deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying)
+ }
private def wildcardArgsString(qset: Set[Symbol], args: List[Type]): List[String] = args map {
case TypeRef(_, sym, _) if (qset contains sym) =>
@@ -2905,6 +2789,8 @@ trait Types
override def params: List[Symbol] = zippedArgs map (_._1)
override def typeArgs: List[Type] = zippedArgs map (_._2)
+
+ override def safeToString: String = super.safeToString + typeArgs.map(_.safeToString).mkString("[", ", ", "]")
}
trait UntouchableTypeVar extends TypeVar {
@@ -3025,15 +2911,19 @@ trait Types
def addLoBound(tp: Type, isNumericBound: Boolean = false) {
assert(tp != this, tp) // implies there is a cycle somewhere (?)
//println("addLoBound: "+(safeToString, debugString(tp))) //DEBUG
- undoLog record this
- constr.addLoBound(tp, isNumericBound)
+ if (!sharesConstraints(tp)) {
+ undoLog record this
+ constr.addLoBound(tp, isNumericBound)
+ }
}
def addHiBound(tp: Type, isNumericBound: Boolean = false) {
// assert(tp != this)
//println("addHiBound: "+(safeToString, debugString(tp))) //DEBUG
- undoLog record this
- constr.addHiBound(tp, isNumericBound)
+ if (!sharesConstraints(tp)) {
+ undoLog record this
+ constr.addHiBound(tp, isNumericBound)
+ }
}
// </region>
@@ -3045,6 +2935,16 @@ trait Types
case ConstantTrue => true
case tv: TypeVar => tv.suspended
}
+
+ /** `AppliedTypeVar`s share the same `TypeConstraint` with the `HKTypeVar` that it was spawned from.
+ * A type inference session can also have more than one ATV.
+ * If we don't detect that, we end up with "cyclic constraint" when we try to instantiate type parameters
+ * after solving in, pos/t8237
+ */
+ protected final def sharesConstraints(other: Type): Boolean = other match {
+ case other: TypeVar => constr == other.constr // SI-8237 avoid cycles. Details in pos/t8237.scala
+ case _ => false
+ }
private[Types] def suspended_=(b: Boolean): Unit = _suspended = if (b) ConstantTrue else ConstantFalse
// SI-7785 Link the suspended attribute of a TypeVar created in, say, a TypeMap (e.g. AsSeenFrom) to its originator
private[Types] def linkSuspended(origin: TypeVar): Unit = _suspended = origin
diff --git a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala
new file mode 100644
index 0000000000..de54f3768e
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala
@@ -0,0 +1,288 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2014 LAMP/EPFL
+ * @author Jason Zaugg
+ */
+package scala.reflect.internal
+package tpe
+
+import Flags._
+import util.Statistics
+import TypesStats._
+
+trait FindMembers {
+ this: SymbolTable =>
+
+ /** Implementatation of `Type#{findMember, findMembers}` */
+ private[internal] abstract class FindMemberBase[T](tpe: Type, name: Name, excludedFlags: Long, requiredFlags: Long) {
+ protected val initBaseClasses: List[Symbol] = tpe.baseClasses
+
+ // The first base class, or the symbol of the ThisType
+ // e.g in:
+ // trait T { self: C => }
+ //
+ // The selector class of `T.this.type` is `T`, and *not* the first base class, `C`.
+ private[this] var _selectorClass: Symbol = null
+ private def selectorClass: Symbol = {
+ if (_selectorClass eq null) {
+ _selectorClass = tpe match {
+ case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class.
+ case _ => initBaseClasses.head
+ }
+ }
+ _selectorClass
+ }
+
+ // Cache for the narrowed type of `tp` (in `tp.findMember`).
+ // This is needed to avoid mismatched existential types are reported in SI-5330.
+ private[this] var _self: Type = null
+ protected def self: Type = {
+ // TODO: use narrow only for modules? (correct? efficiency gain?) (<-- Note: this comment predates SI-5330)
+ if (_self eq null) _self = narrowForFindMember(tpe)
+ _self
+ }
+
+ // Main entry point
+ def apply(): T = {
+ if (Statistics.canEnable) Statistics.incCounter(findMemberCount)
+ val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMemberNanos) else null
+ try searchConcreteThenDeferred
+ finally if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
+ }
+
+ protected def result: T
+
+ // SLS 5.1.3 First, a concrete definition always overrides an abstract definition
+ private def searchConcreteThenDeferred: T = {
+ val deferredSeen = walkBaseClasses(requiredFlags, excludedFlags | DEFERRED)
+ if (deferredSeen) // OPT: the `if` avoids a second pass if the first pass didn't spot any candidates.
+ walkBaseClasses(requiredFlags | DEFERRED, excludedFlags & ~(DEFERRED.toLong))
+ result
+ }
+
+ /*
+ * Walk up through the decls of each base class.
+ *
+ * Called in two passes: first excluding deferred, then mandating it.
+ *
+ * @return if a potential deferred member was seen on the first pass that calls for a second pass,
+ and `excluded & DEFERRED != 0L`
+ */
+ private def walkBaseClasses(required: Long, excluded: Long): Boolean = {
+ var bcs = initBaseClasses
+
+ // Have we seen a candidate deferred member?
+ var deferredSeen = false
+
+ // All direct parents of refinement classes in the base class sequence
+ // from the current `walkBaseClasses`
+ var refinementParents: List[Symbol] = Nil
+
+ // Has the current `walkBaseClasses` encountered a non-refinement class?
+ var seenFirstNonRefinementClass = false
+
+ val findAll = name == nme.ANYname
+
+ while (!bcs.isEmpty) {
+ val currentBaseClass = bcs.head
+ val decls = currentBaseClass.info.decls
+ var entry = if (findAll) decls.elems else decls.lookupEntry(name)
+ while (entry ne null) {
+ val sym = entry.sym
+ val flags = sym.flags
+ val meetsRequirements = (flags & required) == required
+ if (meetsRequirements) {
+ val excl: Long = flags & excluded
+ val isExcluded: Boolean = excl != 0L
+ if (!isExcluded && isPotentialMember(sym, flags, currentBaseClass, seenFirstNonRefinementClass, refinementParents)) {
+ if (shortCircuit(sym)) return false
+ else addMemberIfNew(sym)
+ } else if (excl == DEFERRED) {
+ deferredSeen = true
+ }
+ }
+ entry = if (findAll) entry.next else decls lookupNextEntry entry
+ }
+
+ // SLS 5.2 The private modifier can be used with any definition or declaration in a template.
+ // They are not inherited by subclasses [...]
+ if (currentBaseClass.isRefinementClass)
+ // SLS 3.2.7 A compound type T1 with . . . with Tn {R } represents objects with members as given in
+ // the component types T1, ..., Tn and the refinement {R }
+ //
+ // => private members should be included from T1, ... Tn. (SI-7475)
+ refinementParents :::= currentBaseClass.parentSymbols
+ else if (currentBaseClass.isClass)
+ seenFirstNonRefinementClass = true // only inherit privates of refinement parents after this point
+
+ bcs = bcs.tail
+ }
+ deferredSeen
+ }
+
+ /* Should this symbol be returned immediately as the sole result? */
+ protected def shortCircuit(sym: Symbol): Boolean
+
+ /* Add this member to the final result, unless an already-found member matches it. */
+ protected def addMemberIfNew(sym: Symbol): Unit
+
+ // Is `sym` a potentially member of `baseClass`?
+ //
+ // Q. When does a potential member fail to be a an actual member?
+ // A. if it is subsumed by an member in a subclass.
+ private def isPotentialMember(sym: Symbol, flags: Long, owner: Symbol,
+ seenFirstNonRefinementClass: Boolean, refinementParents: List[Symbol]): Boolean = {
+ // conservatively (performance wise) doing this with flags masks rather than `sym.isPrivate`
+ // to avoid multiple calls to `Symbol#flags`.
+ val isPrivate = (flags & PRIVATE) == PRIVATE
+ val isPrivateLocal = (flags & PrivateLocal) == PrivateLocal
+
+ // TODO Is the special handling of `private[this]` vs `private` backed up by the spec?
+ def admitPrivate(sym: Symbol): Boolean =
+ (selectorClass == owner) || (
+ !isPrivateLocal // private[this] only a member from within the selector class. (Optimization only? Does the spec back this up?)
+ && (
+ !seenFirstNonRefinementClass
+ || refinementParents.contains(owner)
+ )
+ )
+
+ (!isPrivate || admitPrivate(sym)) && (sym.name != nme.CONSTRUCTOR || owner == initBaseClasses.head)
+ }
+
+ // True unless the already-found member of type `memberType` matches the candidate symbol `other`.
+ protected def isNewMember(member: Symbol, other: Symbol): Boolean =
+ ( (other ne member)
+ && ( (member.owner eq other.owner) // same owner, therefore overload
+ || (member.flags & PRIVATE) != 0 // (unqualified) private members never participate in overriding
+ || (other.flags & PRIVATE) != 0 // ... as overrider or overridee.
+ || !(memberTypeLow(member) matches memberTypeHi(other)) // do the member types match? If so, its an override. Otherwise it's an overload.
+ )
+ )
+
+ // Cache for the member type of a candidate member when comparing against multiple, already-found existing members
+ //
+ // TODO this cache is probably unnecessary, `tp.memberType(sym: MethodSymbol)` is already cached internally.
+ private[this] var _memberTypeHiCache: Type = null
+ private[this] var _memberTypeHiCacheSym: Symbol = null
+
+ protected def memberTypeHi(sym: Symbol): Type = {
+ if (_memberTypeHiCacheSym ne sym) {
+ _memberTypeHiCache = self.memberType(sym)
+ _memberTypeHiCacheSym = sym
+ }
+ _memberTypeHiCache
+ }
+
+ // member type of the LHS of `matches` call. This is an extension point to enable a cache in
+ // FindMember.
+ protected def memberTypeLow(sym: Symbol): Type = self.memberType(sym)
+
+ /** Same as a call to narrow unless existentials are visible
+ * after widening the type. In that case, narrow from the widened
+ * type instead of the proxy. This gives buried existentials a
+ * chance to make peace with the other types. See SI-5330.
+ */
+ private def narrowForFindMember(tp: Type): Type = {
+ val w = tp.widen
+ // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type.
+ if ((tp ne w) && containsExistential(w)) w.narrow
+ else tp.narrow
+ }
+ }
+
+ private[reflect] final class FindMembers(tpe: Type, excludedFlags: Long, requiredFlags: Long)
+ extends FindMemberBase[Scope](tpe, nme.ANYname, excludedFlags, requiredFlags) {
+ private[this] var _membersScope: Scope = null
+ private def membersScope: Scope = {
+ if (_membersScope eq null) _membersScope = newFindMemberScope
+ _membersScope
+ }
+
+ protected def shortCircuit(sym: Symbol): Boolean = false
+ protected def result: Scope = membersScope
+
+ protected def addMemberIfNew(sym: Symbol): Unit = {
+ val members = membersScope
+ var others = members.lookupEntry(sym.name)
+ var isNew = true
+ while ((others ne null) && isNew) {
+ val member = others.sym
+ if (!isNewMember(member, sym))
+ isNew = false
+ others = members lookupNextEntry others // next existing member with the same name.
+ }
+ if (isNew) members.enter(sym)
+ }
+ }
+
+ private[reflect] final class FindMember(tpe: Type, name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean)
+ extends FindMemberBase[Symbol](tpe, name, excludedFlags, requiredFlags) {
+ // Gathering the results into a hand rolled ListBuffer
+ // TODO Try just using a ListBuffer to see if this low-level-ness is worth it.
+ private[this] var member0: Symbol = NoSymbol
+ private[this] var members: List[Symbol] = null
+ private[this] var lastM: ::[Symbol] = null
+
+ private def clearAndAddResult(sym: Symbol): Unit = {
+ member0 = sym
+ members = null
+ lastM = null
+ }
+
+ protected def shortCircuit(sym: Symbol): Boolean = (name.isTypeName || (stableOnly && sym.isStable && !sym.hasVolatileType)) && {
+ clearAndAddResult(sym)
+ true
+ }
+
+ protected def addMemberIfNew(sym: Symbol): Unit =
+ if (member0 eq NoSymbol) {
+ member0 = sym // The first found member
+ } else if (members eq null) {
+ // We've found exactly one member so far...
+ if (isNewMember(member0, sym)) {
+ // ... make that two.
+ lastM = new ::(sym, null)
+ members = member0 :: lastM
+ }
+ } else {
+ // Already found 2 or more members
+ var ms: List[Symbol] = members
+
+ var isNew = true
+ while ((ms ne null) && isNew) {
+ val member = ms.head
+ if (!isNewMember(member, sym))
+ isNew = false
+ ms = ms.tail
+ }
+ if (isNew) {
+ val lastM1 = new ::(sym, null)
+ lastM.tl = lastM1
+ lastM = lastM1
+ }
+ }
+
+ // Cache for the member type of the first member we find.
+ private[this] var _member0Tpe: Type = null
+ private[this] def member0Tpe: Type = {
+ assert(member0 != null)
+ if (_member0Tpe eq null) _member0Tpe = self.memberType(member0)
+ _member0Tpe
+ }
+
+ override protected def memberTypeLow(sym: Symbol): Type =
+ if (sym eq member0) member0Tpe else super.memberTypeLow(sym)
+
+ // Assemble the result from the hand-rolled ListBuffer
+ protected def result: Symbol = if (members eq null) {
+ if (member0 == NoSymbol) {
+ if (Statistics.canEnable) Statistics.incCounter(noMemberCount)
+ NoSymbol
+ } else member0
+ } else {
+ if (Statistics.canEnable) Statistics.incCounter(multMemberCount)
+ lastM.tl = Nil
+ initBaseClasses.head.newOverloaded(tpe, members)
+ }
+ }
+}
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
index e2159d30f5..564cbb1ce3 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
@@ -257,6 +257,12 @@ private[internal] trait TypeConstraints {
// println("solving "+tvars+"/"+tparams+"/"+(tparams map (_.info)))
foreach3(tvars, tparams, variances)(solveOne)
- tvars forall (tv => tv.instWithinBounds || util.andFalse(log(s"Inferred type for ${tv.originString} does not conform to bounds: ${tv.constr}")))
+
+ def logBounds(tv: TypeVar) = log {
+ val what = if (!tv.instValid) "is invalid" else s"does not conform to bounds: ${tv.constr}"
+ s"Inferred type for ${tv.originString} (${tv.inst}) $what"
+ }
+
+ tvars forall (tv => tv.instWithinBounds || util.andFalse(logBounds(tv)))
}
}
diff --git a/src/reflect/scala/reflect/internal/transform/PostErasure.scala b/src/reflect/scala/reflect/internal/transform/PostErasure.scala
new file mode 100644
index 0000000000..f0c7d0f050
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/transform/PostErasure.scala
@@ -0,0 +1,19 @@
+package scala.reflect
+package internal
+package transform
+
+trait PostErasure {
+ val global: SymbolTable
+ import global._
+ import definitions._
+
+ object elimErasedValueType extends TypeMap {
+ def apply(tp: Type) = tp match {
+ case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp)))
+ case ErasedValueType(_, underlying) => underlying
+ case _ => mapOver(tp)
+ }
+ }
+
+ def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp)
+}
diff --git a/src/reflect/scala/reflect/internal/transform/Transforms.scala b/src/reflect/scala/reflect/internal/transform/Transforms.scala
index fa185db22f..296ccde443 100644
--- a/src/reflect/scala/reflect/internal/transform/Transforms.scala
+++ b/src/reflect/scala/reflect/internal/transform/Transforms.scala
@@ -26,17 +26,20 @@ trait Transforms { self: SymbolTable =>
private val refChecksLazy = new Lazy(new { val global: Transforms.this.type = self } with RefChecks)
private val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry)
private val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure)
+ private val postErasureLazy = new Lazy(new { val global: Transforms.this.type = self } with PostErasure)
def refChecks = refChecksLazy.force
def uncurry = uncurryLazy.force
def erasure = erasureLazy.force
+ def postErasure = postErasureLazy.force
def transformedType(sym: Symbol) =
- erasure.transformInfo(sym,
- uncurry.transformInfo(sym,
- refChecks.transformInfo(sym, sym.info)))
+ postErasure.transformInfo(sym,
+ erasure.transformInfo(sym,
+ uncurry.transformInfo(sym,
+ refChecks.transformInfo(sym, sym.info))))
def transformedType(tpe: Type) =
- erasure.scalaErasure(uncurry.uncurry(tpe))
+ postErasure.elimErasedValueType(erasure.scalaErasure(uncurry.uncurry(tpe)))
}
diff --git a/src/reflect/scala/reflect/macros/Evals.scala b/src/reflect/scala/reflect/macros/Evals.scala
index 222ae43d79..68e07dd319 100644
--- a/src/reflect/scala/reflect/macros/Evals.scala
+++ b/src/reflect/scala/reflect/macros/Evals.scala
@@ -17,13 +17,13 @@ trait Evals {
* permitted by the shape of the arguments.
*
* Known issues: because of [[https://issues.scala-lang.org/browse/SI-5748 https://issues.scala-lang.org/browse/SI-5748]]
- * trees being evaluated first need to undergo `resetAllAttrs`. Resetting symbols and types
+ * trees being evaluated first need to undergo `untypecheck`. Resetting symbols and types
* mutates the tree in place, therefore the conventional approach is to `duplicate` the tree first.
*
* {{{
* scala> def impl(c: Context)(x: c.Expr[String]) = {
- * | val x1 = c.Expr[String](c.resetAllAttrs(x.tree.duplicate))
- * | println(s"compile-time value is: \${c.eval(x1)}")
+ * | val x1 = c.Expr[String](c.untypecheck(x.tree.duplicate))
+ * | println(s"compile-time value is: ${c.eval(x1)}")
* | x
* | }
* impl: (c: Context)(x: c.Expr[String])c.Expr[String]
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index 87de442921..6c077de1d2 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -68,12 +68,6 @@ trait Typers {
*/
def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree
- /** Recursively resets symbols and types in a given tree.
- * WARNING: Don't use this API, go for [[untypecheck]] instead.
- */
- @deprecated("Use `c.untypecheck` instead", "2.11.0")
- def resetAllAttrs(tree: Tree): Tree
-
/** Recursively resets locally defined symbols and types in a given tree.
* WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index d84e6aa737..bc5c8b2840 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -122,7 +122,7 @@ abstract class Universe extends scala.reflect.api.Universe {
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.
+ * fact is remembered so that `untypecheck` will snap back.
*
* \@PP: Attempting to elaborate on the above, I find: If defineType
* is called on a TypeTree whose type field is null or NoType,
@@ -130,7 +130,8 @@ abstract class Universe extends scala.reflect.api.Universe {
* ResetAttrsTraverser, which nulls out the type field of TypeTrees
* for which wasEmpty is true, leaving the others alone.
*
- * resetAllAttrs is used in situations where some speculative
+ * `untypecheck` (or `resetAttrs` in compiler parlance) is used
+ * in situations where some speculative
* typing of a tree takes place, fails, and the tree needs to be
* returned to its former state to try again. So according to me:
* using `defineType` instead of `setType` is how you communicate
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 68c67bb1f8..bc95b839b7 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -16,7 +16,7 @@ import java.io.IOException
import scala.reflect.internal.{ MissingRequirementError, JavaAccFlags, JMethodOrConstructor }
import internal.pickling.ByteCodecs
import internal.pickling.UnPickler
-import scala.collection.mutable.{ HashMap, ListBuffer }
+import scala.collection.mutable.{ HashMap, ListBuffer, ArrayBuffer }
import internal.Flags._
import ReflectionUtils._
import scala.language.existentials
@@ -118,15 +118,16 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
private def abort(msg: String) = throw new ScalaReflectionException(msg)
- private def ErrorInnerClass(sym: Symbol) = abort(s"$sym is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
- private def ErrorInnerModule(sym: Symbol) = abort(s"$sym is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
- private def ErrorStaticClass(sym: Symbol) = abort(s"$sym is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
- private def ErrorStaticModule(sym: Symbol) = abort(s"$sym is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
- private def ErrorNotMember(sym: Symbol, owner: Symbol) = abort(s"expected a member of $owner, you provided ${sym.kindString} ${sym.fullName}")
- private def ErrorNotField(sym: Symbol) = abort(s"expected a field or an accessor method symbol, you provided $sym")
- private def ErrorNotConstructor(sym: Symbol, owner: Symbol) = abort(s"expected a constructor of $owner, you provided $sym")
- private def ErrorFree(member: Symbol, freeType: Symbol) = abort(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a weak type ${freeType.name}")
- private def ErrorNonExistentField(sym: Symbol) = abort(
+ private def ErrorInnerClass(sym: Symbol) = abort(s"$sym is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
+ private def ErrorInnerModule(sym: Symbol) = abort(s"$sym is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
+ private def ErrorStaticClass(sym: Symbol) = abort(s"$sym is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
+ private def ErrorStaticModule(sym: Symbol) = abort(s"$sym is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
+ private def ErrorNotMember(sym: Symbol, owner: Symbol) = abort(s"expected a member of $owner, you provided ${sym.kindString} ${sym.fullName}")
+ private def ErrorNotField(sym: Symbol) = abort(s"expected a field or an accessor method symbol, you provided $sym")
+ private def ErrorNotConstructor(sym: Symbol, owner: Symbol) = abort(s"expected a constructor of $owner, you provided $sym")
+ private def ErrorArrayConstructor(sym: Symbol, owner: Symbol) = abort(s"Cannot instantiate arrays with mirrors. Consider using `scala.reflect.ClassTag(<class of element>).newArray(<length>)` instead")
+ private def ErrorFree(member: Symbol, freeType: Symbol) = abort(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a weak type ${freeType.name}")
+ private def ErrorNonExistentField(sym: Symbol) = abort(
sm"""Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method
|note that private parameters of class constructors don't get mapped onto fields and/or accessors,
|unless they are used outside of their declaring constructors.""")
@@ -221,6 +222,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
private def checkConstructorOf(sym: Symbol, owner: ClassSymbol) {
if (!sym.isClassConstructor) ErrorNotConstructor(sym, owner)
+ if (owner == ArrayClass) ErrorArrayConstructor(sym, owner)
ensuringNotFree(sym) {
if (!owner.info.decls.toList.contains(sym)) ErrorNotConstructor(sym, owner)
}
@@ -247,7 +249,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
}
def reflectMethod(method: MethodSymbol): MethodMirror = {
checkMemberOf(method, symbol)
- mkJavaMethodMirror(instance, method)
+ mkMethodMirror(instance, method)
}
def reflectClass(cls: ClassSymbol): ClassMirror = {
if (cls.isStatic) ErrorStaticClass(cls)
@@ -262,16 +264,35 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
override def toString = s"instance mirror for $instance"
}
- private class JavaFieldMirror(val receiver: Any, val symbol: TermSymbol)
+ // caches value class metadata, so that we minimize the work that needs to be done during Mirror.apply
+ private class DerivedValueClassMetadata(info: Type) {
+ val symbol = info.typeSymbol
+ val isDerivedValueClass = symbol.isDerivedValueClass
+ lazy val boxer = runtimeClass(symbol.toType).getDeclaredConstructors().head
+ lazy val unboxer = {
+ val fields @ (field :: _) = symbol.toType.declarations.collect{ case ts: TermSymbol if ts.isParamAccessor && ts.isMethod => ts }.toList
+ assert(fields.length == 1, s"$symbol: $fields")
+ runtimeClass(symbol.asClass).getDeclaredMethod(field.name.toString)
+ }
+ }
+
+ private class JavaFieldMirror(val receiver: Any, val symbol: TermSymbol, metadata: DerivedValueClassMetadata)
extends FieldMirror {
+ def this(receiver: Any, symbol: TermSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.info))
+ def bind(newReceiver: Any) = new JavaFieldMirror(newReceiver, symbol, metadata)
+ import metadata._
+
lazy val jfield = ensureAccessible(fieldToJava(symbol))
- def get = jfield get receiver
+ def get = {
+ val value = jfield get receiver
+ if (isDerivedValueClass) boxer.newInstance(value) else value
+ }
def set(value: Any) = {
// it appears useful to be able to set values of vals, therefore I'm disabling this check
// if (!symbol.isMutable) ErrorSetImmutableField(symbol)
- jfield.set(receiver, value)
+ jfield.set(receiver, if (isDerivedValueClass) unboxer.invoke(value) else value)
}
- def bind(newReceiver: Any) = new JavaFieldMirror(newReceiver, symbol)
+
override def toString = s"field mirror for ${symbol.fullName} (bound to $receiver)"
}
@@ -312,13 +333,17 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
bytecodelessMethodOwners(meth.owner) && !bytecodefulObjectMethods(meth)
}
+ private def isByNameParam(p: Type) = isByNameParamType(p)
+ private def isValueClassParam(p: Type) = p.typeSymbol.isDerivedValueClass
+
// unlike other mirrors, method mirrors are created by a factory
// that's because we want to have decent performance
// therefore we move special cases into separate subclasses
// rather than have them on a hot path them in a unified implementation of the `apply` method
- private def mkJavaMethodMirror[T: ClassTag](receiver: T, symbol: MethodSymbol): JavaMethodMirror = {
- if (isBytecodelessMethod(symbol)) new JavaBytecodelessMethodMirror(receiver, symbol)
- else if (symbol.paramss.flatten exists (p => isByNameParamType(p.info))) new JavaByNameMethodMirror(receiver, symbol)
+ private def mkMethodMirror[T: ClassTag](receiver: T, symbol: MethodSymbol): MethodMirror = {
+ def existsParam(pred: Type => Boolean) = symbol.paramss.flatten.map(_.info).exists(pred)
+ if (isBytecodelessMethod(symbol)) new BytecodelessMethodMirror(receiver, symbol)
+ else if (existsParam(isByNameParam) || existsParam(isValueClassParam)) new JavaTransformingMethodMirror(receiver, symbol)
else {
symbol.paramss.flatten.length match {
case 0 => new JavaVanillaMethodMirror0(receiver, symbol)
@@ -330,68 +355,123 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
}
}
}
- private abstract class JavaMethodMirror(val symbol: MethodSymbol) extends MethodMirror {
+
+ private abstract class JavaMethodMirror(val symbol: MethodSymbol, protected val ret: DerivedValueClassMetadata) extends MethodMirror {
lazy val jmeth = ensureAccessible(methodToJava(symbol))
- def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
+ lazy val jconstr = ensureAccessible(constructorToJava(symbol))
- def jinvoke(jmeth: jMethod, receiver: Any, args: Seq[Any]): Any = {
- val result = jinvokeraw(jmeth, receiver, args)
- if (jmeth.getReturnType == java.lang.Void.TYPE) ()
+ def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
+ else if (receiver == null) jconstr.newInstance(args.asInstanceOf[Seq[AnyRef]]: _*)
+ else jconstr.newInstance((receiver +: args).asInstanceOf[Seq[AnyRef]]: _*)
+ def jinvoke(args: Seq[Any]): Any = {
+ val result = jinvokeraw(args)
+ if (!symbol.isConstructor && jmeth.getReturnType == java.lang.Void.TYPE) ()
+ else if (!symbol.isConstructor && ret.isDerivedValueClass) ret.boxer.newInstance(result.asInstanceOf[AnyRef])
else result
}
- override def toString = s"method mirror for ${showMethodSig(symbol)} (bound to $receiver)"
- }
-
- private class JavaVanillaMethodMirror(val receiver: Any, symbol: MethodSymbol)
- extends JavaMethodMirror(symbol) {
- def bind(newReceiver: Any) = new JavaVanillaMethodMirror(newReceiver, symbol)
- def apply(args: Any*): Any = jinvoke(jmeth, receiver, args)
- }
-
- private class JavaVanillaMethodMirror0(receiver: Any, symbol: MethodSymbol)
- extends JavaVanillaMethodMirror(receiver, symbol) {
- override def bind(newReceiver: Any) = new JavaVanillaMethodMirror0(newReceiver, symbol)
- override def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver)
- }
-
- private class JavaVanillaMethodMirror1(receiver: Any, symbol: MethodSymbol)
- extends JavaVanillaMethodMirror(receiver, symbol) {
- override def bind(newReceiver: Any) = new JavaVanillaMethodMirror1(newReceiver, symbol)
- override def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef])
- }
-
- private class JavaVanillaMethodMirror2(receiver: Any, symbol: MethodSymbol)
- extends JavaVanillaMethodMirror(receiver, symbol) {
- override def bind(newReceiver: Any) = new JavaVanillaMethodMirror2(newReceiver, symbol)
- override def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef])
- }
-
- private class JavaVanillaMethodMirror3(receiver: Any, symbol: MethodSymbol)
- extends JavaVanillaMethodMirror(receiver, symbol) {
- override def bind(newReceiver: Any) = new JavaVanillaMethodMirror3(newReceiver, symbol)
- override def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef])
+ override def toString = {
+ val what = if (symbol.isConstructor) "constructor mirror" else "method mirror"
+ s"$what for ${showMethodSig(symbol)} (bound to $receiver)"
+ }
}
- private class JavaVanillaMethodMirror4(receiver: Any, symbol: MethodSymbol)
- extends JavaVanillaMethodMirror(receiver, symbol) {
- override def bind(newReceiver: Any) = new JavaVanillaMethodMirror4(newReceiver, symbol)
- override def jinvokeraw(jmeth: jMethod, receiver: Any, args: Seq[Any]) = jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef], args(3).asInstanceOf[AnyRef])
- }
+ private class JavaVanillaMethodMirror(val receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaMethodMirror(symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ def bind(newReceiver: Any) = new JavaVanillaMethodMirror(newReceiver, symbol, ret)
+ def apply(args: Any*): Any = jinvoke(args)
+ }
+
+ private class JavaVanillaMethodMirror0(receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaVanillaMethodMirror(receiver, symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ override def bind(newReceiver: Any) = new JavaVanillaMethodMirror0(newReceiver, symbol, ret)
+ override def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver)
+ else if (receiver == null) jconstr.newInstance()
+ else jconstr.newInstance(receiver.asInstanceOf[AnyRef])
+ }
+
+ private class JavaVanillaMethodMirror1(receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaVanillaMethodMirror(receiver, symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ override def bind(newReceiver: Any) = new JavaVanillaMethodMirror1(newReceiver, symbol, ret)
+ override def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef])
+ else if (receiver == null) jconstr.newInstance(args(0).asInstanceOf[AnyRef])
+ else jconstr.newInstance(receiver.asInstanceOf[AnyRef], args(0).asInstanceOf[AnyRef])
+ }
+
+ private class JavaVanillaMethodMirror2(receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaVanillaMethodMirror(receiver, symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ override def bind(newReceiver: Any) = new JavaVanillaMethodMirror2(newReceiver, symbol, ret)
+ override def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef])
+ else if (receiver == null) jconstr.newInstance(args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef])
+ else jconstr.newInstance(receiver.asInstanceOf[AnyRef], args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef])
+ }
+
+ private class JavaVanillaMethodMirror3(receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaVanillaMethodMirror(receiver, symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ override def bind(newReceiver: Any) = new JavaVanillaMethodMirror3(newReceiver, symbol, ret)
+ override def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef])
+ else if (receiver == null) jconstr.newInstance(args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef])
+ else jconstr.newInstance(receiver.asInstanceOf[AnyRef], args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef])
+ }
+
+ private class JavaVanillaMethodMirror4(receiver: Any, symbol: MethodSymbol, ret: DerivedValueClassMetadata)
+ extends JavaVanillaMethodMirror(receiver, symbol, ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new DerivedValueClassMetadata(symbol.returnType))
+ override def bind(newReceiver: Any) = new JavaVanillaMethodMirror4(newReceiver, symbol, ret)
+ override def jinvokeraw(args: Seq[Any]) =
+ if (!symbol.isConstructor) jmeth.invoke(receiver, args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef], args(3).asInstanceOf[AnyRef])
+ else if (receiver == null) jconstr.newInstance(args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef], args(3).asInstanceOf[AnyRef])
+ else jconstr.newInstance(receiver.asInstanceOf[AnyRef], args(0).asInstanceOf[AnyRef], args(1).asInstanceOf[AnyRef], args(2).asInstanceOf[AnyRef], args(3).asInstanceOf[AnyRef])
+ }
+
+ // caches MethodSymbol metadata, so that we minimize the work that needs to be done during Mirror.apply
+ // TODO: vararg is only supported in the last parameter list (SI-6182), so we don't need to worry about the rest for now
+ private class MethodMetadata(symbol: MethodSymbol) {
+ private val params = symbol.paramss.flatten.toArray
+ private val vcMetadata = params.map(p => new DerivedValueClassMetadata(p.info))
+ val isByName = params.map(p => isByNameParam(p.info))
+ def isDerivedValueClass(i: Int) = vcMetadata(i).isDerivedValueClass
+ def paramUnboxers(i: Int) = vcMetadata(i).unboxer
+ val paramCount = params.length
+ val ret = new DerivedValueClassMetadata(symbol.returnType)
+ }
+
+ private class JavaTransformingMethodMirror(val receiver: Any, symbol: MethodSymbol, metadata: MethodMetadata)
+ extends JavaMethodMirror(symbol, metadata.ret) {
+ def this(receiver: Any, symbol: MethodSymbol) = this(receiver, symbol, new MethodMetadata(symbol))
+ override def bind(newReceiver: Any) = new JavaTransformingMethodMirror(newReceiver, symbol, metadata)
+ import metadata._
- private class JavaByNameMethodMirror(val receiver: Any, symbol: MethodSymbol)
- extends JavaMethodMirror(symbol) {
- def bind(newReceiver: Any) = new JavaByNameMethodMirror(newReceiver, symbol)
def apply(args: Any*): Any = {
- val transformed = map2(args.toList, symbol.paramss.flatten)((arg, param) => if (isByNameParamType(param.info)) () => arg else arg)
- jinvoke(jmeth, receiver, transformed)
+ val args1 = new Array[Any](args.length)
+ var i = 0
+ while (i < args1.length) {
+ val arg = args(i)
+ if (i >= paramCount) args1(i) = arg // don't transform varargs
+ else if (isByName(i)) args1(i) = () => arg // don't transform by-name value class params
+ else if (isDerivedValueClass(i)) args1(i) = paramUnboxers(i).invoke(arg)
+ i += 1
+ }
+ jinvoke(args1)
}
}
- private class JavaBytecodelessMethodMirror[T: ClassTag](val receiver: T, symbol: MethodSymbol)
- extends JavaMethodMirror(symbol) {
- def bind(newReceiver: Any) = new JavaBytecodelessMethodMirror(newReceiver.asInstanceOf[T], symbol)
- def apply(args: Any*): Any = {
+ private class BytecodelessMethodMirror[T: ClassTag](val receiver: T, val symbol: MethodSymbol)
+ extends MethodMirror {
+ def bind(newReceiver: Any) = new BytecodelessMethodMirror(newReceiver.asInstanceOf[T], symbol)
+ override def toString = s"bytecodeless method mirror for ${showMethodSig(symbol)} (bound to $receiver)"
+
+ def apply(args: Any*): Any = {
// checking type conformance is too much of a hassle, so we don't do it here
// actually it's not even necessary, because we manually dispatch arguments below
val params = symbol.paramss.flatten
@@ -414,7 +494,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
def invokePrimitiveMethod = {
val jmeths = classOf[BoxesRunTime].getDeclaredMethods.filter(_.getName == nme.primitiveMethodName(symbol.name).toString)
assert(jmeths.length == 1, jmeths.toList)
- jinvoke(jmeths.head, null, objReceiver +: objArgs)
+ val jmeth = jmeths.head
+ val result = jmeth.invoke(null, (objReceiver +: objArgs).asInstanceOf[Seq[AnyRef]]: _*)
+ if (jmeth.getReturnType == java.lang.Void.TYPE) ()
+ else result
}
symbol match {
@@ -445,23 +528,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
}
}
- private class JavaConstructorMirror(val outer: AnyRef, val symbol: MethodSymbol)
- extends MethodMirror {
- def bind(newReceiver: Any) = new JavaConstructorMirror(newReceiver.asInstanceOf[AnyRef], symbol)
- override val receiver = outer
- lazy val jconstr = ensureAccessible(constructorToJava(symbol))
- def apply(args: Any*): Any = {
- if (symbol.owner == ArrayClass)
- abort("Cannot instantiate arrays with mirrors. Consider using `scala.reflect.ClassTag(<class of element>).newArray(<length>)` instead")
-
- val effectiveArgs =
- if (outer == null) args.asInstanceOf[Seq[AnyRef]]
- else outer +: args.asInstanceOf[Seq[AnyRef]]
- jconstr.newInstance(effectiveArgs: _*)
- }
- override def toString = s"constructor mirror for ${showMethodSig(symbol)} (bound to $outer)"
- }
-
private abstract class JavaTemplateMirror
extends TemplateMirror {
def outer: AnyRef
@@ -474,7 +540,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
def isStatic = false
def reflectConstructor(constructor: MethodSymbol) = {
checkConstructorOf(constructor, symbol)
- new JavaConstructorMirror(outer, constructor)
+ mkMethodMirror(outer, constructor)
}
override def toString = s"class mirror for ${symbol.fullName} (bound to $outer)"
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
index cfd66744ff..f6556a442d 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
@@ -12,6 +12,8 @@ class JavaUniverse extends internal.SymbolTable with JavaUniverseForce with Refl
override def inform(msg: String): Unit = log(msg)
def picklerPhase = internal.SomePhase
+ def erasurePhase = internal.SomePhase
+
lazy val settings = new Settings
private val isLogging = sys.props contains "scala.debug.reflect"
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index fb893cbff1..0fcf215580 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -27,27 +27,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.settings
this.treeInfo
- // inaccessible: this.scala$reflect$runtime$Gil$$gil
- // inaccessible: this.uniqueLock
- // inaccessible: this._skolemizationLevel
- // inaccessible: this._undoLog
- // inaccessible: this._intersectionWitness
- // inaccessible: this._subsametypeRecursions
- // inaccessible: this._pendingSubTypes
- // inaccessible: this._basetypeRecursions
- // inaccessible: this._pendingBaseTypes
- // inaccessible: this._lubResults
- // inaccessible: this._glbResults
- // inaccessible: this._indent
- // inaccessible: this._toStringRecursions
- // inaccessible: this._toStringSubjects
- // inaccessible: this.atomicIds
- // inaccessible: this.atomicExistentialIds
- // inaccessible: this._recursionTable
- // inaccessible: this.mirrors
this.rootMirror
this.treeBuild
- // inaccessible: this.SimpleNameOrdering
this.traceSymbols
this.perRunCaches
this.FreshNameExtractor
@@ -60,7 +41,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.SubpatternsAttachment
this.noPrint
this.typeDebug
- // inaccessible: this.maxFree
this.Range
// inaccessible: this.posAssigner
this.ConsoleWriter
@@ -116,7 +96,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.pendingSuperCall
this.emptyValDef
this.EmptyTreeTypeSubstituter
- // inaccessible: this.duplicator
this.UnmappableAnnotArg
this.LiteralAnnotArg
this.ArrayAnnotArg
@@ -127,7 +106,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.UnmappableAnnotation
this.ErroneousAnnotation
this.ThrownException
- // inaccessible: this.compactify
this.tpnme
this.fulltpnme
this.binarynme
@@ -147,7 +125,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.ProperTypeKind
this.TypeConKind
this.inferKind
- // inaccessible: this.substTypeMapCache
this.UnmappableTree
this.ErrorType
this.WildcardType
@@ -184,9 +161,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.unwrapToStableClass
this.unwrapWrapperTypes
this.RecoverableCyclicReference
- // inaccessible: this._undoLog
- // inaccessible: this.numericLoBound
- // inaccessible: this.numericHiBound
this.TypeConstraint
this.normalizeAliases
this.dropSingletonType
@@ -198,19 +172,16 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.typeVarToOriginMap
this.ErroneousCollector
this.adaptToNewRunMap
- // inaccessible: this.commonOwnerMapObj
this.SubTypePair
this.SymbolKind
this.NoSymbol
this.CyclicReference
- // inaccessible: this.TypeHistory
this.SymbolOps
this.TermName
this.TypeName
this.Liftable
this.Unliftable
this.BooleanFlag
- // inaccessible: this.CachedNames
this.WeakTypeTag
this.TypeTag
this.Expr
@@ -427,14 +398,12 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.languageFeatureModule
definitions.metaAnnotations
definitions.AnnotationDefaultAttr
- // inaccessible: definitions.erasurePhase
definitions.isPhantomClass
definitions.syntheticCoreClasses
definitions.syntheticCoreMethods
definitions.hijackedCoreClasses
definitions.symbolsNotPresentInBytecode
definitions.isPossibleSyntheticParent
- // inaccessible: definitions.boxedValueClassesSet
definitions.abbrvTag
definitions.numericWeight
definitions.boxedModule
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index 813c0e1386..d642b25127 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -12,7 +12,7 @@ import scala.reflect.internal.util.AbstractFileClassLoader
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
*/
-private[scala] object ReflectionUtils {
+object ReflectionUtils {
// Unwraps some chained exceptions which arise during reflective calls.
def unwrapThrowable(x: Throwable): Throwable = x match {
case _: InvocationTargetException | // thrown by reflectively invoked method or constructor
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 8fba1e538e..d261fc5be9 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -18,7 +18,7 @@ import scala.reflect.internal.util.{ BatchSourceFile, SourceFile }
import scala.tools.util.PathResolver
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.typechecker.{ TypeStrings, StructuredTypeStrings }
-import scala.tools.nsc.util.{ ScalaClassLoader, stringFromWriter, StackTraceOps }
+import scala.tools.nsc.util.{ ScalaClassLoader, stringFromReader, stringFromWriter, StackTraceOps }
import scala.tools.nsc.util.Exceptional.unwrap
import javax.script.{AbstractScriptEngine, Bindings, ScriptContext, ScriptEngine, ScriptEngineFactory, ScriptException, CompiledScript, Compilable}
@@ -534,8 +534,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
var code = ""
var bound = false
- @throws[ScriptException]
- def compile(script: String): CompiledScript = {
+ def compiled(script: String): CompiledScript = {
if (!bound) {
quietBind("engine" -> this.asInstanceOf[ScriptEngine])
bound = true
@@ -562,18 +561,6 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
}
- @throws[ScriptException]
- def compile(reader: java.io.Reader): CompiledScript = {
- val writer = new java.io.StringWriter()
- var c = reader.read()
- while(c != -1) {
- writer.write(c)
- c = reader.read()
- }
- reader.close()
- compile(writer.toString())
- }
-
private class WrappedRequest(val req: Request) extends CompiledScript {
var recorded = false
@@ -1014,10 +1001,16 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
@throws[ScriptException]
- def eval(script: String, context: ScriptContext): Object = compile(script).eval(context)
+ def compile(script: String): CompiledScript = eval("new javax.script.CompiledScript { def eval(context: javax.script.ScriptContext): Object = { " + script + " }.asInstanceOf[Object]; def getEngine: javax.script.ScriptEngine = engine }").asInstanceOf[CompiledScript]
+
+ @throws[ScriptException]
+ def compile(reader: java.io.Reader): CompiledScript = compile(stringFromReader(reader))
+
+ @throws[ScriptException]
+ def eval(script: String, context: ScriptContext): Object = compiled(script).eval(context)
@throws[ScriptException]
- def eval(reader: java.io.Reader, context: ScriptContext): Object = compile(reader).eval(context)
+ def eval(reader: java.io.Reader, context: ScriptContext): Object = eval(stringFromReader(reader), context)
override def finalize = close
diff --git a/test/disabled/run/t7843-jsr223-service.scala b/test/disabled/run/t7843-jsr223-service.scala
deleted file mode 100644
index e2ea850698..0000000000
--- a/test/disabled/run/t7843-jsr223-service.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-/*DISABLED:
- For Paul, it steals focus when it runs.
-
- For me, it fails with some platform specific extra output:
-
- -ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider apple.applescript.AppleScriptEngin
- n: Object = 10
- 12345678910
-*/
-import javax.script._
-import scala.tools.nsc.interpreter.IMain
-
-object Test extends App {
- val engine = new ScriptEngineManager getEngineByName "scala"
- engine.asInstanceOf[IMain].settings.usejavacp.value = true
- engine put ("n", 10)
- engine eval "1 to n.asInstanceOf[Int] foreach print"
-}
diff --git a/test/files/neg/forgot-interpolator.check b/test/files/neg/forgot-interpolator.check
index 157cbb4802..8988458982 100644
--- a/test/files/neg/forgot-interpolator.check
+++ b/test/files/neg/forgot-interpolator.check
@@ -10,9 +10,6 @@ forgot-interpolator.scala:30: warning: `$beppo` looks like an interpolated ident
forgot-interpolator.scala:34: warning: `$aleppo` looks like an interpolated identifier! Did you forget the interpolator?
def f = "$aleppo is a pepper and a city." // warn 4
^
-forgot-interpolator.scala:42: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator?
- def f = "$bar is private, shall we warn just in case?" // warn 5
- ^
forgot-interpolator.scala:47: warning: `$hippo` looks like an interpolated identifier! Did you forget the interpolator?
def h = "$hippo takes an implicit" // warn 6
^
@@ -26,5 +23,5 @@ forgot-interpolator.scala:90: warning: `$calico` looks like an interpolated iden
def f4 = "I also salute $calico" // warn 9
^
error: No warnings can be incurred under -Xfatal-warnings.
-9 warnings found
+8 warnings found
one error found
diff --git a/test/files/neg/forgot-interpolator.scala b/test/files/neg/forgot-interpolator.scala
index 34a7c7aef4..a53054d890 100644
--- a/test/files/neg/forgot-interpolator.scala
+++ b/test/files/neg/forgot-interpolator.scala
@@ -39,7 +39,7 @@ package test {
if (bar > 8) ??? // use it to avoid extra warning
}
class Baz extends Bar {
- def f = "$bar is private, shall we warn just in case?" // warn 5
+ def f = "$bar is private, shall we warn just in case?" // no longer a warning, private members aren't inherited!
}
class G {
def g = "$greppo takes an arg" // no warn
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index 880ddc4327..20ddd55f1f 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -88,7 +88,7 @@ names-defaults-neg.scala:76: error: no type parameters for method test4: (x: T[T
--- because ---
argument expression's type is not compatible with formal parameter type;
found : List[Int]
- required: ?T
+ required: ?T[?T[List[?T[X forSome { type X }]]]]
Error occurred in an application involving default arguments.
test4()
^
diff --git a/test/files/neg/t0764b.check b/test/files/neg/t0764b.check
new file mode 100644
index 0000000000..d74a9efbfe
--- /dev/null
+++ b/test/files/neg/t0764b.check
@@ -0,0 +1,63 @@
+t0764b.scala:27: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.NodeAlias[A]]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f1 = new Main1(v.prepend) // fail
+ ^
+t0764b.scala:28: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.NodeAlias[A]]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:29: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.Node{type T = A}]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:34: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f1 = new Main2(v.prepend) // fail
+ ^
+t0764b.scala:35: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.NodeAlias[A]}
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:36: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:52: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.NodeAlias[p2.t0764.NodeAlias[A]]
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:53: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.NodeAlias[p2.t0764.Node{type T = A}]
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:58: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f1 = new Main2(v.prepend) // fail
+ ^
+t0764b.scala:59: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.NodeAlias[A]}
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:60: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ ^
+11 errors found
diff --git a/test/files/neg/t0764b.scala b/test/files/neg/t0764b.scala
new file mode 100644
index 0000000000..4ad5ecdc03
--- /dev/null
+++ b/test/files/neg/t0764b.scala
@@ -0,0 +1,64 @@
+/** Note that this should compile! It's a neg test to track the
+behavior. If you have broken this test by making it compile, that
+means you have fixed it and it should be moved to pos.
+**/
+
+// In all cases when calling "prepend" the receiver 'v'
+// has static type NodeAlias[A] or (equivalently) Node { type T = A }.
+// Since prepend explicitly returns the singleton type of the receiver,
+// the return type of prepend in all cases is "v.type", and so the call
+// to "new Main" can be parameterized with any of the following, in order
+// of decreasing specificity with a tie for second place:
+//
+// new Main[v.type](v.prepend)
+// new Main[NodeAlias[A]](v.prepend)
+// new Main[Node { type T = A }](v.prepend)
+// new Main(v.prepend)
+
+package p1 {
+ object t0764 {
+ type NodeAlias[A] = Node { type T = A }
+ trait Node { outer =>
+ type T <: Node
+ def prepend: Node { type T = outer.type } = ???
+ }
+
+ class Main1[A <: Node](v: NodeAlias[A]) {
+ private[this] def f1 = new Main1(v.prepend) // fail
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main1[v.type](v.prepend) // ok
+ }
+
+ class Main2[A <: Node](v: Node { type T = A }) {
+ private[this] def f1 = new Main2(v.prepend) // fail
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main2[v.type](v.prepend) // ok
+ }
+ }
+}
+
+package p2 {
+ object t0764 {
+ type NodeAlias[A] = Node { type T = A }
+ trait Node { outer =>
+ type T <: Node
+ def prepend: NodeAlias[outer.type] = ???
+ }
+
+ class Main1[A <: Node](v: NodeAlias[A]) {
+ private[this] def f1 = new Main1(v.prepend) // ok! <<========== WOT
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main1[v.type](v.prepend) // ok
+ }
+
+ class Main2[A <: Node](v: Node { type T = A }) {
+ private[this] def f1 = new Main2(v.prepend) // fail
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main2[v.type](v.prepend) // ok
+ }
+ }
+}
diff --git a/test/files/neg/t6260-named.check b/test/files/neg/t6260-named.check
new file mode 100644
index 0000000000..ed6ab5e76f
--- /dev/null
+++ b/test/files/neg/t6260-named.check
@@ -0,0 +1,13 @@
+t6260-named.scala:12: error: bridge generated for member method apply: (a: C[Any])C[Any] in object O
+which overrides method apply: (v1: T1)R in trait Function1
+clashes with definition of the member itself;
+both have erased type (v1: Object)Object
+ def apply(a: C[Any]) = a
+ ^
+t6260-named.scala:14: error: bridge generated for member method apply: (a: C[Any])C[Any] in class X
+which overrides method apply: (a: A)A in trait T
+clashes with definition of the member itself;
+both have erased type (a: Object)Object
+ class X extends T[C[Any]] { def apply(a: C[Any]) = a }
+ ^
+two errors found
diff --git a/test/files/neg/t6260-named.scala b/test/files/neg/t6260-named.scala
new file mode 100644
index 0000000000..7cd9ce8473
--- /dev/null
+++ b/test/files/neg/t6260-named.scala
@@ -0,0 +1,15 @@
+class C[A](private val a: Any) extends AnyVal
+trait T[A] {
+ def apply(a: A): A
+}
+
+object Test {
+ (x: C[Any]) => {println(s"f($x)"); x} // okay
+ new T[C[Any]] { def apply(a: C[Any]) = a } // okay
+
+ // we can't rename the specific apply method to avoid the clash
+ object O extends Function1[C[Any], C[Any]] {
+ def apply(a: C[Any]) = a
+ }
+ class X extends T[C[Any]] { def apply(a: C[Any]) = a }
+}
diff --git a/test/files/neg/t6260.check b/test/files/neg/t6260.check
deleted file mode 100644
index 60c4add143..0000000000
--- a/test/files/neg/t6260.check
+++ /dev/null
@@ -1,13 +0,0 @@
-t6260.scala:3: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in <$anon: Box[X] => Box[Y]>
-which overrides method apply: (v1: T1)R in trait Function1
-clashes with definition of the member itself;
-both have erased type (v1: Object)Object
- ((bx: Box[X]) => new Box(f(bx.x)))(this)
- ^
-t6260.scala:8: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in <$anon: Box[X] => Box[Y]>
-which overrides method apply: (v1: T1)R in trait Function1
-clashes with definition of the member itself;
-both have erased type (v1: Object)Object
- ((bx: Box[X]) => new Box(f(bx.x)))(self)
- ^
-two errors found
diff --git a/test/files/neg/t6260b.check b/test/files/neg/t6260b.check
deleted file mode 100644
index 3a7e8947aa..0000000000
--- a/test/files/neg/t6260b.check
+++ /dev/null
@@ -1,7 +0,0 @@
-t6260b.scala:3: error: bridge generated for member method apply: ()X in <$anon: () => X>
-which overrides method apply: ()R in trait Function0
-clashes with definition of the member itself;
-both have erased type ()Object
-class Y { def f = new X("") or new X("") }
- ^
-one error found
diff --git a/test/files/neg/t7475c.check b/test/files/neg/t7475c.check
new file mode 100644
index 0000000000..472808131a
--- /dev/null
+++ b/test/files/neg/t7475c.check
@@ -0,0 +1,7 @@
+t7475c.scala:6: error: value a is not a member of A.this.B
+ println(this.a) // wait, what?
+ ^
+t7475c.scala:7: error: value b is not a member of A.this.B
+ println(this.b) // wait, what?
+ ^
+two errors found
diff --git a/test/files/neg/t7475c.scala b/test/files/neg/t7475c.scala
new file mode 100644
index 0000000000..cd4a8762ca
--- /dev/null
+++ b/test/files/neg/t7475c.scala
@@ -0,0 +1,9 @@
+class A {
+ private val a: Int = 0
+ private[this] val b: Int = 0
+ class B extends A {
+ def foo(a: A) = a.a // okay
+ println(this.a) // wait, what?
+ println(this.b) // wait, what?
+ }
+}
diff --git a/test/files/neg/t7475d.check b/test/files/neg/t7475d.check
new file mode 100644
index 0000000000..6bd1da0d44
--- /dev/null
+++ b/test/files/neg/t7475d.check
@@ -0,0 +1,7 @@
+t7475d.scala:4: error: value priv is not a member of T.this.TT
+ (??? : TT).priv
+ ^
+t7475d.scala:10: error: value priv is not a member of U.this.UU
+ (??? : UU).priv
+ ^
+two errors found
diff --git a/test/files/neg/t7475e.check b/test/files/neg/t7475e.check
new file mode 100644
index 0000000000..48af2be51a
--- /dev/null
+++ b/test/files/neg/t7475e.check
@@ -0,0 +1,4 @@
+t7475e.scala:8: error: value priv is not a member of Base.this.TT
+ (??? : TT).priv
+ ^
+one error found
diff --git a/test/files/neg/t7475e.scala b/test/files/neg/t7475e.scala
new file mode 100644
index 0000000000..e5c4877d6e
--- /dev/null
+++ b/test/files/neg/t7475e.scala
@@ -0,0 +1,12 @@
+trait U {
+}
+
+trait Base {
+ private val priv = 0
+
+ type TT = U with T // should exclude `priv`
+ (??? : TT).priv
+}
+
+trait T extends Base {
+}
diff --git a/test/files/neg/t7475f.check b/test/files/neg/t7475f.check
new file mode 100644
index 0000000000..a07a4480e2
--- /dev/null
+++ b/test/files/neg/t7475f.check
@@ -0,0 +1,10 @@
+t7475f.scala:12: error: method c1 in class C cannot be accessed in C[T]
+ c1 // a member, but inaccessible.
+ ^
+t7475f.scala:13: error: not found: value c2
+ c2 // a member, but inaccessible.
+ ^
+t7475f.scala:26: error: value d2 is not a member of D[Any]
+ other.d2 // not a member
+ ^
+three errors found
diff --git a/test/files/neg/t7475f.scala b/test/files/neg/t7475f.scala
new file mode 100644
index 0000000000..6c5feadf19
--- /dev/null
+++ b/test/files/neg/t7475f.scala
@@ -0,0 +1,28 @@
+class C[T] extends D[T] {
+ private def c1 = 0
+ private[this] def c2 = 0
+}
+
+trait D[T] {
+ self: C[T] =>
+
+ private def d1 = 0
+ private[this] def d2 = 0
+
+ c1 // a member, but inaccessible.
+ c2 // a member, but inaccessible.
+
+ d1 // okay
+ d2 // okay
+
+
+ class C {
+ d1
+ d2
+ }
+
+ def x(other: D[Any]) {
+ other.d1
+ other.d2 // not a member
+ }
+}
diff --git a/test/files/neg/t7507.check b/test/files/neg/t7507.check
index d402869fd4..de30fc7057 100644
--- a/test/files/neg/t7507.check
+++ b/test/files/neg/t7507.check
@@ -1,4 +1,4 @@
-t7507.scala:6: error: value bippy in trait Cake cannot be accessed in Cake
+t7507.scala:6: error: not found: value bippy
locally(bippy)
^
one error found
diff --git a/test/files/neg/t8207.check b/test/files/neg/t8207.check
new file mode 100644
index 0000000000..59facd897a
--- /dev/null
+++ b/test/files/neg/t8207.check
@@ -0,0 +1,7 @@
+t8207.scala:1: error: '.' expected but '}' found.
+class C { import C.this.toString }
+ ^
+t8207.scala:3: error: '.' expected but '}' found.
+class D { import D.this.toString }
+ ^
+two errors found
diff --git a/test/files/neg/t8207.scala b/test/files/neg/t8207.scala
new file mode 100644
index 0000000000..738ce381f4
--- /dev/null
+++ b/test/files/neg/t8207.scala
@@ -0,0 +1,3 @@
+class C { import C.this.toString }
+
+class D { import D.this.toString }
diff --git a/test/files/neg/t8219-any-any-ref-equals.check b/test/files/neg/t8219-any-any-ref-equals.check
new file mode 100644
index 0000000000..95d2536fba
--- /dev/null
+++ b/test/files/neg/t8219-any-any-ref-equals.check
@@ -0,0 +1,10 @@
+t8219-any-any-ref-equals.scala:5: error: method ==: (x$1: Any)Boolean does not take type parameters.
+ "".==[Int]
+ ^
+t8219-any-any-ref-equals.scala:6: error: method ==: (x$1: Any)Boolean does not take type parameters.
+ ("": AnyRef).==[Int]
+ ^
+t8219-any-any-ref-equals.scala:7: error: method ==: (x$1: Any)Boolean does not take type parameters.
+ ("": Object).==[Int]
+ ^
+three errors found
diff --git a/test/files/neg/t8219-any-any-ref-equals.scala b/test/files/neg/t8219-any-any-ref-equals.scala
new file mode 100644
index 0000000000..f1b81fa734
--- /dev/null
+++ b/test/files/neg/t8219-any-any-ref-equals.scala
@@ -0,0 +1,8 @@
+object Test {
+ // The error message tells us that AnyRef#== and Any#== are overloaded.
+ // A real class couldn't define such an overload, why do we allow AnyRef
+ // to do so?
+ "".==[Int]
+ ("": AnyRef).==[Int]
+ ("": Object).==[Int]
+}
diff --git a/test/files/neg/t8237-default.check b/test/files/neg/t8237-default.check
new file mode 100644
index 0000000000..59fe21ed03
--- /dev/null
+++ b/test/files/neg/t8237-default.check
@@ -0,0 +1,13 @@
+t8237-default.scala:5: error: no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])Nothing exist so that it can be applied to arguments (List[Int])
+ --- because ---
+argument expression's type is not compatible with formal parameter type;
+ found : List[Int]
+ required: ?T[?T[List[?T[X forSome { type X }]]]]
+ test4(test4$default$1)
+ ^
+t8237-default.scala:5: error: type mismatch;
+ found : List[Int]
+ required: T[T[List[T[X forSome { type X }]]]]
+ test4(test4$default$1)
+ ^
+two errors found
diff --git a/test/files/neg/t8237-default.scala b/test/files/neg/t8237-default.scala
new file mode 100644
index 0000000000..f695aa523f
--- /dev/null
+++ b/test/files/neg/t8237-default.scala
@@ -0,0 +1,29 @@
+// This test case was extracte from `names-defaults-neg.scala`
+// It pinpoints an improvement an error message that results from
+// a type inference failure
+object Test extends App {
+ test4(test4$default$1)
+
+ def test4[T[P]](x: T[T[List[T[X forSome { type X }]]]]) = ???
+ def test4$default$1[T[P]]: List[Int] = ???
+}
+
+/*
+OLD:
+ no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])Nothing exist so that it can be applied to arguments (List[Int])
+ --- because ---
+argument expression's type is not compatible with formal parameter type;
+ found : List[Int]
+ required: ?T
+ test4(test4$default$1)
+ ^
+
+NEW:
+
+no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])Nothing exist so that it can be applied to arguments (List[Int])
+ --- because ---
+argument expression's type is not compatible with formal parameter type;
+ found : List[Int]
+ required: ?T[?T[List[?T[X forSome { type X }]]]
+ test4(test4$default$1)
+*/
diff --git a/test/files/pos/annotated-original/M_1.scala b/test/files/pos/annotated-original/M_1.scala
index e312f9abbf..84a01bcce5 100644
--- a/test/files/pos/annotated-original/M_1.scala
+++ b/test/files/pos/annotated-original/M_1.scala
@@ -2,6 +2,6 @@ import language.experimental.macros
import scala.reflect.macros.blackbox.Context
object M {
- def impl(c: Context)(a: c.Expr[Any]) = c.Expr[Any](c.resetLocalAttrs(a.tree))
+ def impl(c: Context)(a: c.Expr[Any]) = c.Expr[Any](c.untypecheck(a.tree))
def m(a: Any) = macro impl
}
diff --git a/test/files/pos/annotated-treecopy/Impls_Macros_1.scala b/test/files/pos/annotated-treecopy/Impls_Macros_1.scala
index b02864b994..fdf9c72c31 100644
--- a/test/files/pos/annotated-treecopy/Impls_Macros_1.scala
+++ b/test/files/pos/annotated-treecopy/Impls_Macros_1.scala
@@ -44,7 +44,7 @@ object Macros {
val typeOut = c.Expr[String](q"${ttag.tpe.toString}").splice
def apply(_arg: T): U = c.Expr[U](b1)(ttag.asInstanceOf[c.WeakTypeTag[U]]).splice
})
- val untyped = c.resetLocalAttrs(template.tree)
+ val untyped = c.untypecheck(template.tree)
c.Expr[T => U](untyped)
case _ => sys.error("Bad function type")
diff --git a/test/files/neg/delambdafy_t6260_method.check b/test/files/pos/delambdafy_t6260_method.check
index f5cd6947d1..f5cd6947d1 100644
--- a/test/files/neg/delambdafy_t6260_method.check
+++ b/test/files/pos/delambdafy_t6260_method.check
diff --git a/test/files/neg/delambdafy_t6260_method.flags b/test/files/pos/delambdafy_t6260_method.flags
index 48b438ddf8..48b438ddf8 100644
--- a/test/files/neg/delambdafy_t6260_method.flags
+++ b/test/files/pos/delambdafy_t6260_method.flags
diff --git a/test/files/neg/delambdafy_t6260_method.scala b/test/files/pos/delambdafy_t6260_method.scala
index 93b5448227..93b5448227 100644
--- a/test/files/neg/delambdafy_t6260_method.scala
+++ b/test/files/pos/delambdafy_t6260_method.scala
diff --git a/test/files/pos/t1786-counter.scala b/test/files/pos/t1786-counter.scala
new file mode 100644
index 0000000000..c1ad2c204f
--- /dev/null
+++ b/test/files/pos/t1786-counter.scala
@@ -0,0 +1,38 @@
+trait ShapeLevel
+
+object Fail {
+ abstract class ProductNodeShape[Level <: ShapeLevel, C, M <: C, U <: C, P <: C] extends Shape[Level, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _]
+ }
+
+ abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
+
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _] = ???
+ }
+
+ trait ShapeLevel
+}
+
+object Ok {
+ abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
+
+ abstract class ProductNodeShape[Level <: ShapeLevel, C, M <: C, U <: C, P <: C] extends Shape[Level, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _]
+ }
+
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _] = ???
+ }
+}
+
+// This is why we reverted the fix for SI-1786 -- see SI-6169 for a potential alternative that could be extended to cover this.
+// both objects type check on 2.10.3, but only Ok was accepted by 2.11 after the original fix to SI-1786.
+// Fail results in:
+/*
+t1786-counter.scala:10: error: class TupleShape needs to be abstract, since method copy in class ProductNodeShape of type (shapes: Seq[Fail.Shape[_, _, _, _]])Fail.Shape[Level, _, _, _] is not defined
+(Note that Seq[Fail.Shape[_, _, _, _]] does not match Seq[Fail.Shape[_ <: Fail.ShapeLevel, _, _, _]]: their type parameters differ)
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ ^
+one error found
+*/ \ No newline at end of file
diff --git a/test/files/pos/t261-ab.scala b/test/files/pos/t261-ab.scala
deleted file mode 100644
index df641e811a..0000000000
--- a/test/files/pos/t261-ab.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-trait A { val foo: String = "A" }
-trait B {
- private val foo: String = "B"
- def f = println(foo)
-}
-object Test extends App with B with A {
- println(foo) // prints "A", as expected
- f // prints "B", as expected
-}
diff --git a/test/files/pos/t261-ba.scala b/test/files/pos/t261-ba.scala
deleted file mode 100644
index 6c9c5b10b7..0000000000
--- a/test/files/pos/t261-ba.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-trait B {
- private val foo: String = "B"
- def f = println(foo)
-}
-trait A { val foo: String = "A" }
-object Test extends App with B with A {
- println(foo) // prints "A", as expected
- f // prints "B", as expected
-}
diff --git a/test/files/pos/t6169/Exist.java b/test/files/pos/t6169/Exist.java
new file mode 100644
index 0000000000..dfc6b36b33
--- /dev/null
+++ b/test/files/pos/t6169/Exist.java
@@ -0,0 +1,4 @@
+public class Exist<T extends String> {
+ // java helpfully re-interprets Exist<?> as Exist<? extends String>
+ public Exist<?> foo() { throw new RuntimeException(); }
+} \ No newline at end of file
diff --git a/test/files/pos/t6169/ExistF.java b/test/files/pos/t6169/ExistF.java
new file mode 100644
index 0000000000..70fabd74cf
--- /dev/null
+++ b/test/files/pos/t6169/ExistF.java
@@ -0,0 +1,4 @@
+public class ExistF<T extends ExistF<T>> {
+ // java helpfully re-interprets ExistF<?> as ExistF<?0 extends ExistF<?0>>
+ public ExistF<?> foo() { throw new RuntimeException(); }
+} \ No newline at end of file
diff --git a/test/files/pos/t6169/ExistIndir.java b/test/files/pos/t6169/ExistIndir.java
new file mode 100644
index 0000000000..e66d1698c4
--- /dev/null
+++ b/test/files/pos/t6169/ExistIndir.java
@@ -0,0 +1,4 @@
+public class ExistIndir<T extends String, U extends T> {
+ // java helpfully re-interprets ExistIndir<?> as ExistIndir<? extends String>
+ public ExistIndir<?, ?> foo() { throw new RuntimeException(); }
+}
diff --git a/test/files/pos/t6169/OP.java b/test/files/pos/t6169/OP.java
new file mode 100644
index 0000000000..15e4c5640f
--- /dev/null
+++ b/test/files/pos/t6169/OP.java
@@ -0,0 +1 @@
+public abstract class OP<T> { }
diff --git a/test/files/pos/t6169/Skin.java b/test/files/pos/t6169/Skin.java
new file mode 100644
index 0000000000..780de1ee09
--- /dev/null
+++ b/test/files/pos/t6169/Skin.java
@@ -0,0 +1 @@
+public interface Skin<C extends Skinnable> { }
diff --git a/test/files/pos/t6169/Skinnable.java b/test/files/pos/t6169/Skinnable.java
new file mode 100644
index 0000000000..f91eaa30d8
--- /dev/null
+++ b/test/files/pos/t6169/Skinnable.java
@@ -0,0 +1,3 @@
+public interface Skinnable {
+ OP<Skin<?>> skinProperty();
+}
diff --git a/test/files/pos/t6169/skinnable.scala b/test/files/pos/t6169/skinnable.scala
new file mode 100644
index 0000000000..3ba2734526
--- /dev/null
+++ b/test/files/pos/t6169/skinnable.scala
@@ -0,0 +1,14 @@
+object ObjectProperty {
+ implicit def jfxObjectProperty2sfx[T](p: OP[T]) = new ObjectProperty[T](p)
+}
+
+class ObjectProperty[T](val delegate: OP[T])
+
+trait TestWildcardBoundInference {
+ def delegate: Skinnable
+ def skin: ObjectProperty[Skin[_ /* inferred: <: Skinnable */]] = ObjectProperty.jfxObjectProperty2sfx(delegate.skinProperty)
+ skin: ObjectProperty[Skin[_ <: Skinnable]]
+
+ def skinCheckInference = delegate.skinProperty
+ skinCheckInference: ObjectProperty[Skin[_ <: Skinnable]]
+} \ No newline at end of file
diff --git a/test/files/pos/t6169/t6169.scala b/test/files/pos/t6169/t6169.scala
new file mode 100644
index 0000000000..37f42619ca
--- /dev/null
+++ b/test/files/pos/t6169/t6169.scala
@@ -0,0 +1,7 @@
+class Test {
+ class MyExist extends ExistF[MyExist]
+ // SI-8197, SI-6169: java infers the bounds of existentials, so we have to as well now that SI-1786 is fixed...
+ def stringy: Exist[_ <: String] = (new Exist[String]).foo
+ def fbounded: (ExistF[t] forSome {type t <: ExistF[t] }) = (new MyExist).foo
+ def indir: ExistIndir[_ <: String, _ <: String] = (new ExistIndir[String, String]).foo
+} \ No newline at end of file
diff --git a/test/files/neg/t6260.flags b/test/files/pos/t6260.flags
index 2349d8294d..2349d8294d 100644
--- a/test/files/neg/t6260.flags
+++ b/test/files/pos/t6260.flags
diff --git a/test/files/neg/t6260.scala b/test/files/pos/t6260.scala
index 93b5448227..93b5448227 100644
--- a/test/files/neg/t6260.scala
+++ b/test/files/pos/t6260.scala
diff --git a/test/files/neg/t6260b.scala b/test/files/pos/t6260b.scala
index 73e2e58f73..73e2e58f73 100644
--- a/test/files/neg/t6260b.scala
+++ b/test/files/pos/t6260b.scala
diff --git a/test/files/pos/t6948.scala b/test/files/pos/t6948.scala
new file mode 100644
index 0000000000..12a1d7eaf2
--- /dev/null
+++ b/test/files/pos/t6948.scala
@@ -0,0 +1,10 @@
+object t6948 {
+ val rand = new scala.util.Random()
+ def a1 = rand.shuffle(0 to 5)
+ // Tis not to be
+ // def a2 = rand.shuffle(0 until 5)
+ def a3 = rand.shuffle(Vector(1, 2, 3))
+ def a4 = rand.shuffle(scala.collection.Seq(1, 2, 3))
+ def a5 = rand.shuffle(scala.collection.immutable.Seq(1, 2, 3))
+ def a6 = rand.shuffle(scala.collection.mutable.Seq(1, 2, 3))
+}
diff --git a/test/files/pos/t7377/Macro_1.scala b/test/files/pos/t7377/Macro_1.scala
index 9f51248095..b38687c8b3 100644
--- a/test/files/pos/t7377/Macro_1.scala
+++ b/test/files/pos/t7377/Macro_1.scala
@@ -2,6 +2,6 @@ import language.experimental._
import scala.reflect.macros.blackbox.Context
object M {
- def noopImpl[A](c: Context)(expr: c.Expr[A]): c.Expr[A] = c.Expr(c.typecheck(c.resetLocalAttrs(expr.tree)))
+ def noopImpl[A](c: Context)(expr: c.Expr[A]): c.Expr[A] = c.Expr(c.typecheck(c.untypecheck(expr.tree)))
def noop[A](expr: A): A = macro noopImpl[A]
}
diff --git a/test/files/pos/t7475a.scala b/test/files/pos/t7475a.scala
new file mode 100644
index 0000000000..810ce9a05c
--- /dev/null
+++ b/test/files/pos/t7475a.scala
@@ -0,0 +1,11 @@
+trait AbstractPublic {
+ def queue: Any
+}
+trait ConcretePrivate {
+ private val queue: Any = ()
+}
+
+abstract class Mix
+ extends ConcretePrivate with AbstractPublic {
+ final def queue: Any = ()
+}
diff --git a/test/files/pos/t7475b.scala b/test/files/pos/t7475b.scala
new file mode 100644
index 0000000000..a34743b8be
--- /dev/null
+++ b/test/files/pos/t7475b.scala
@@ -0,0 +1,8 @@
+trait U {
+}
+
+trait T {
+ type TT = Any with T with U
+ private val priv = 0
+ (??? : TT).priv
+}
diff --git a/test/files/pos/t7475d.scala b/test/files/pos/t7475d.scala
new file mode 100644
index 0000000000..497c2bf443
--- /dev/null
+++ b/test/files/pos/t7475d.scala
@@ -0,0 +1,11 @@
+trait T {
+ type TT = T with Any
+ private val priv = 0
+ (??? : TT).priv
+}
+
+trait U {
+ type UU = Any with U
+ private val priv = 0
+ (??? : UU).priv
+}
diff --git a/test/files/pos/t7475e.scala b/test/files/pos/t7475e.scala
new file mode 100644
index 0000000000..fbc965c4ca
--- /dev/null
+++ b/test/files/pos/t7475e.scala
@@ -0,0 +1,13 @@
+trait U {
+ private val priv = 0
+ type TT = U with T // should allow `priv`
+ (??? : TT).priv
+}
+
+trait Base {
+
+}
+
+trait T extends Base {
+
+}
diff --git a/test/files/pos/t7516/A_1.scala b/test/files/pos/t7516/A_1.scala
index 3bba19966d..3bd477dcda 100644
--- a/test/files/pos/t7516/A_1.scala
+++ b/test/files/pos/t7516/A_1.scala
@@ -3,7 +3,7 @@ import scala.reflect._,macros._, scala.language.experimental.macros
object A {
def impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] = {
val r = c.universe.reify { List(t.splice) }
- c.Expr[List[T]]( c.resetLocalAttrs(r.tree) )
+ c.Expr[List[T]]( c.untypecheck(r.tree) )
}
def demo[T](t: T): List[T] = macro impl[T]
}
diff --git a/test/files/pos/t8064/Macro_1.scala b/test/files/pos/t8064/Macro_1.scala
index dd42950b34..9f1e6955b4 100644
--- a/test/files/pos/t8064/Macro_1.scala
+++ b/test/files/pos/t8064/Macro_1.scala
@@ -5,6 +5,6 @@ object Macro {
def apply(a: Any): Any = macro impl
def impl(c: Context)(a: c.Tree): c.Tree = {
- c.resetLocalAttrs(a)
+ c.untypecheck(a)
}
}
diff --git a/test/files/pos/t8207.scala b/test/files/pos/t8207.scala
new file mode 100644
index 0000000000..680b40f379
--- /dev/null
+++ b/test/files/pos/t8207.scala
@@ -0,0 +1,6 @@
+class C { me =>
+ import me.{toString => ts}
+ locally(this: me.type)
+ trait T
+ type X = me.T
+}
diff --git a/test/files/pos/t8209a.check b/test/files/pos/t8209a.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t8209a.check
diff --git a/test/files/pos/t8209a/Macros_1.scala b/test/files/pos/t8209a/Macros_1.scala
new file mode 100644
index 0000000000..17014b4744
--- /dev/null
+++ b/test/files/pos/t8209a/Macros_1.scala
@@ -0,0 +1,17 @@
+import scala.language.experimental.macros
+import scala.language.implicitConversions
+import scala.reflect.macros.blackbox.Context
+
+class A
+object A { implicit def a2b(a: A): B = ??? }
+class B
+class C extends A
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ q"new C"
+ }
+
+ def foo: A = macro impl
+} \ No newline at end of file
diff --git a/test/files/pos/t8209a/Test_2.scala b/test/files/pos/t8209a/Test_2.scala
new file mode 100644
index 0000000000..e19d572f55
--- /dev/null
+++ b/test/files/pos/t8209a/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val a: A = Macros.foo
+ val b: B = Macros.foo
+} \ No newline at end of file
diff --git a/test/files/pos/t8209b.check b/test/files/pos/t8209b.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t8209b.check
diff --git a/test/files/pos/t8209b/Macros_1.scala b/test/files/pos/t8209b/Macros_1.scala
new file mode 100644
index 0000000000..705f7d630c
--- /dev/null
+++ b/test/files/pos/t8209b/Macros_1.scala
@@ -0,0 +1,17 @@
+import scala.language.experimental.macros
+import scala.language.implicitConversions
+import scala.reflect.macros.whitebox.Context
+
+class A
+object A { implicit def a2b(a: A): B = ??? }
+class B
+class C extends A
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ q"new C"
+ }
+
+ def foo: A = macro impl
+} \ No newline at end of file
diff --git a/test/files/pos/t8209b/Test_2.scala b/test/files/pos/t8209b/Test_2.scala
new file mode 100644
index 0000000000..e19d572f55
--- /dev/null
+++ b/test/files/pos/t8209b/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val a: A = Macros.foo
+ val b: B = Macros.foo
+} \ No newline at end of file
diff --git a/test/files/pos/t8219.scala b/test/files/pos/t8219.scala
new file mode 100644
index 0000000000..e1653b6238
--- /dev/null
+++ b/test/files/pos/t8219.scala
@@ -0,0 +1,15 @@
+trait Equalizer[T]
+trait Gen[A]
+
+class Broken {
+ implicit def const[T](x: T): Gen[T] = ???
+ implicit def convertToEqualizer[T](left: T): Equalizer[T] = ???
+
+ def in(a: Any) = ()
+ in {
+ import scala.None // any import will do..
+ "" == "" // this no longer triggers the bug, as Object#== now overrides Any#==
+ }
+
+ // We can still trigger the bug with a structural type, see pending/neg/t8219.scala
+}
diff --git a/test/files/pos/t8219b.scala b/test/files/pos/t8219b.scala
new file mode 100644
index 0000000000..d55d3139e1
--- /dev/null
+++ b/test/files/pos/t8219b.scala
@@ -0,0 +1,49 @@
+trait Equalizer[T]
+trait Gen[A]
+
+class Broken {
+ implicit def const[T](x: T): Gen[T] = ???
+ implicit def convertToEqualizer[T](left: T): Equalizer[T] = ???
+
+ def in(a: Any) = ()
+ in {
+ import scala.None // any import will do..
+ "" == "" // no longer a problem, see pos/t8129.scala
+ }
+
+ // We used to fall into the errant code path above when `Any#==` and `AnyRef#==`
+ // were overloaded.
+ //
+ // Real classes couldn't get away with that overloading; it would result in
+ // a compiler error because the variants would collapse into an overriding
+ // relationship after erasure.
+ //
+ //
+ // But, a structural type can! This triggers the same error, and served as
+ // a backstop for this test if we change the signatures of `AnyRef#==` to
+ // override `Any#==`.
+ type T = {
+ def a(a: AnyRef): Boolean
+ def a(a: Any): Boolean
+ }
+
+ def t: T = ???
+
+ in {
+ import scala.None // any import will do..
+ t.a("")
+ }
+
+ // Or, we can get here with ambiguous implicits from the formal parameter
+ // type of the less specific overload to that of the more specific.
+ object T {
+ def foo(a: Any) = true
+ def foo(a: String) = true
+ }
+ in {
+ import scala.None
+ implicit def any2str1(a: Any) = ""
+ implicit def any2str2(a: Any) = ""
+ T.foo("")
+ }
+}
diff --git a/test/files/pos/t8237.scala b/test/files/pos/t8237.scala
new file mode 100644
index 0000000000..005089079e
--- /dev/null
+++ b/test/files/pos/t8237.scala
@@ -0,0 +1,29 @@
+import scala.language.higherKinds
+
+object TestExplicit {
+ trait TC[A]
+ def fTt[A,E[X] <: List[X]](a: A)(implicit tt: TC[E[A]]) = a
+ implicit def tc[T]: TC[T] = ???
+
+ // Typechecking results in SOE in TypeVar.isGround
+ fTt(1)(tc)
+ // fun = TestExplicit.this.fTt[Int, E](1)
+ // args = TestExplicit.this.tc[E[Int]]
+ // argTpes.head.instantiateTypeParams = TC[?E#1[Int]]
+ // formals.head.instantiateTypeParams = TC[?E#2[Int]]
+ // (where ?E#1 and ?E#2 as distinct AppliedTypeVars that resulted
+ // from separate applications of type args to the same HKTypeVar, ?E)
+ //
+ // As we check if the argument conforms to the formal, we would have
+ // AppliedTypeVars sharing the same TypeConstraints on the LHS and RHS,
+ // which leads to a cyclic constraint.
+}
+
+object TestImplicit {
+ trait TC[A]
+ def fTt[A,E[X] <: List[X]](a: A)(implicit tt: TC[E[A]]) = a
+ implicit def tc[T]: TC[T] = ???
+
+ // Oddly enough, this one works.
+ fTt(1)
+}
diff --git a/test/files/pos/t8237b.scala b/test/files/pos/t8237b.scala
new file mode 100644
index 0000000000..52bb310e8b
--- /dev/null
+++ b/test/files/pos/t8237b.scala
@@ -0,0 +1,10 @@
+import scala.language.higherKinds
+import scala.reflect.runtime.universe._
+object Test {
+
+ def fTt[A,E[X]<:List[X]](a: A)(implicit tt: TypeTag[E[A]]) = a
+
+ trait TC[A]
+ implicit def TCListInt[A]: TC[A] = ???
+ fTt(1)
+}
diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check
index 1f868097ca..4bf68b3d4e 100644
--- a/test/files/presentation/callcc-interpreter.check
+++ b/test/files/presentation/callcc-interpreter.check
@@ -3,7 +3,7 @@ reload: CallccInterpreter.scala
askTypeCompletion at CallccInterpreter.scala(51,34)
================================================================================
[response] askTypeCompletion at (51,34)
-retrieved 59 members
+retrieved 57 members
abstract trait Term extends AnyRef
abstract trait Value extends AnyRef
case class Add extends callccInterpreter.Term with Product with Serializable
@@ -38,10 +38,8 @@ def toString(): String
def unitM[A](a: A): callccInterpreter.M[A]
def →[B](y: B): (callccInterpreter.type, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/completion-implicit-chained.check b/test/files/presentation/completion-implicit-chained.check
index f9d77f7a53..c583b7877c 100644
--- a/test/files/presentation/completion-implicit-chained.check
+++ b/test/files/presentation/completion-implicit-chained.check
@@ -3,7 +3,7 @@ reload: Completions.scala
askTypeCompletion at Completions.scala(11,16)
================================================================================
[response] askTypeCompletion at (11,16)
-retrieved 24 members
+retrieved 22 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def equals(x$1: Any): Boolean
@@ -11,10 +11,8 @@ def hashCode(): Int
def map(x: Int => Int)(implicit a: DummyImplicit): test.O.type
def toString(): String
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/ide-bug-1000349.check b/test/files/presentation/ide-bug-1000349.check
index c59fa6843f..79bfde5343 100644
--- a/test/files/presentation/ide-bug-1000349.check
+++ b/test/files/presentation/ide-bug-1000349.check
@@ -3,7 +3,7 @@ reload: CompletionOnEmptyArgMethod.scala
askTypeCompletion at CompletionOnEmptyArgMethod.scala(2,17)
================================================================================
[response] askTypeCompletion at (2,17)
-retrieved 32 members
+retrieved 30 members
def +(other: String): String
def ->[B](y: B): (Foo, B)
def ensuring(cond: Boolean): Foo
@@ -17,10 +17,8 @@ def hashCode(): Int
def toString(): String
def →[B](y: B): (Foo, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/ide-bug-1000475.check b/test/files/presentation/ide-bug-1000475.check
index f5b4253e1a..4fb7f18285 100644
--- a/test/files/presentation/ide-bug-1000475.check
+++ b/test/files/presentation/ide-bug-1000475.check
@@ -3,7 +3,7 @@ reload: Foo.scala
askTypeCompletion at Foo.scala(3,7)
================================================================================
[response] askTypeCompletion at (3,7)
-retrieved 31 members
+retrieved 29 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def +(other: String): String
@@ -18,10 +18,8 @@ def hashCode(): Int
def toString(): String
def →[B](y: B): (Object, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -37,7 +35,7 @@ final def wait(x$1: Long,x$2: Int): Unit
askTypeCompletion at Foo.scala(6,10)
================================================================================
[response] askTypeCompletion at (6,10)
-retrieved 31 members
+retrieved 29 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def +(other: String): String
@@ -52,10 +50,8 @@ def hashCode(): Int
def toString(): String
def →[B](y: B): (Object, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -71,7 +67,7 @@ final def wait(x$1: Long,x$2: Int): Unit
askTypeCompletion at Foo.scala(7,7)
================================================================================
[response] askTypeCompletion at (7,7)
-retrieved 31 members
+retrieved 29 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def +(other: String): String
@@ -86,10 +82,8 @@ def hashCode(): Int
def toString(): String
def →[B](y: B): (Object, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check
index dff89b155b..d8c7a369f7 100644
--- a/test/files/presentation/ide-bug-1000531.check
+++ b/test/files/presentation/ide-bug-1000531.check
@@ -3,7 +3,7 @@ reload: CrashOnLoad.scala
askTypeCompletion at CrashOnLoad.scala(6,12)
================================================================================
[response] askTypeCompletion at (6,12)
-retrieved 120 members
+retrieved 117 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
[inaccessible] protected[this] def reversed: List[B]
@@ -107,10 +107,8 @@ def zipWithIndex: Iterator[(B, Int)]
def zip[B](that: Iterator[B]): Iterator[(B, B)]
def →[B](y: B): (java.util.Iterator[B], B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/implicit-member.check b/test/files/presentation/implicit-member.check
index 5ad52b4dd3..3bd3d8af41 100644
--- a/test/files/presentation/implicit-member.check
+++ b/test/files/presentation/implicit-member.check
@@ -3,7 +3,7 @@ reload: ImplicitMember.scala
askTypeCompletion at ImplicitMember.scala(7,7)
================================================================================
[response] askTypeCompletion at (7,7)
-retrieved 34 members
+retrieved 32 members
def +(other: String): String
def ->[B](y: B): (Implicit.type, B)
def ensuring(cond: Boolean): Implicit.type
@@ -17,10 +17,8 @@ def toString(): String
def →[B](y: B): (Implicit.type, B)
final class AppliedImplicit[A] extends AnyRef
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check
index 20f17aa7d0..220bdf33b2 100644
--- a/test/files/presentation/ping-pong.check
+++ b/test/files/presentation/ping-pong.check
@@ -3,7 +3,7 @@ reload: PingPong.scala
askTypeCompletion at PingPong.scala(10,23)
================================================================================
[response] askTypeCompletion at (10,23)
-retrieved 35 members
+retrieved 32 members
[inaccessible] private[this] val ping: Ping
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
@@ -19,10 +19,8 @@ def hashCode(): Int
def poke(): Unit
def →[B](y: B): (Pong, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -40,7 +38,7 @@ private[this] val name: String
askTypeCompletion at PingPong.scala(19,20)
================================================================================
[response] askTypeCompletion at (19,20)
-retrieved 35 members
+retrieved 33 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def +(other: String): String
@@ -57,10 +55,8 @@ def name: String
def poke: Unit
def →[B](y: B): (Ping, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/scope-completion-3.check b/test/files/presentation/scope-completion-3.check
index df3007ab4e..b70a7d5c6b 100644
--- a/test/files/presentation/scope-completion-3.check
+++ b/test/files/presentation/scope-completion-3.check
@@ -3,19 +3,7 @@ reload: Completions.scala
askScopeCompletion at Completions.scala(75,2)
================================================================================
[response] askScopeCompletion at (75,2)
-retrieved 49 members
-[inaccessible] private class Cb2 extends AnyRef
-[inaccessible] private class Ct2 extends AnyRef
-[inaccessible] private def fb2: Int
-[inaccessible] private def ft2: Int
-[inaccessible] private object Ob2
-[inaccessible] private object Ot2
-[inaccessible] private type tb2 = Completion1.this.tb2
-[inaccessible] private type tt2 = Completion1.this.tt2
-[inaccessible] private[this] val vb2: Int
-[inaccessible] private[this] val vt2: Int
-[inaccessible] private[this] var rb2: Int
-[inaccessible] private[this] var rt2: Int
+retrieved 37 members
abstract class Base1 extends AnyRef
abstract trait Trait1 extends AnyRef
class Cb1 extends AnyRef
@@ -58,19 +46,7 @@ type tt1 = Completion1.this.tt1
askScopeCompletion at Completions.scala(104,2)
================================================================================
[response] askScopeCompletion at (104,2)
-retrieved 49 members
-[inaccessible] private class Cb2 extends AnyRef
-[inaccessible] private class Ct2 extends AnyRef
-[inaccessible] private def fb2: Int
-[inaccessible] private def ft2: Int
-[inaccessible] private object Ob2
-[inaccessible] private object Ot2
-[inaccessible] private type tb2 = test.Completion2.tb2
-[inaccessible] private type tt2 = test.Completion2.tt2
-[inaccessible] private[this] val vb2: Int
-[inaccessible] private[this] val vt2: Int
-[inaccessible] private[this] var rb2: Int
-[inaccessible] private[this] var rt2: Int
+retrieved 37 members
abstract class Base1 extends AnyRef
abstract trait Trait1 extends AnyRef
class Cb1 extends AnyRef
diff --git a/test/files/presentation/scope-completion-import.check b/test/files/presentation/scope-completion-import.check
index 220ffc399b..50197e5822 100644
--- a/test/files/presentation/scope-completion-import.check
+++ b/test/files/presentation/scope-completion-import.check
@@ -3,10 +3,8 @@ reload: Completions.scala
askScopeCompletion at Completions.scala(23,4)
================================================================================
[response] askScopeCompletion at (23,4)
-retrieved 18 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 16 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -27,10 +25,8 @@ val o: test.O.type
askScopeCompletion at Completions.scala(27,4)
================================================================================
[response] askScopeCompletion at (27,4)
-retrieved 17 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 15 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -126,10 +122,8 @@ val c: test.C
askScopeCompletion at Completions.scala(49,4)
================================================================================
[response] askScopeCompletion at (49,4)
-retrieved 18 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 16 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -150,10 +144,8 @@ private[this] var rOOO: Int
askScopeCompletion at Completions.scala(59,4)
================================================================================
[response] askScopeCompletion at (59,4)
-retrieved 19 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 17 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
diff --git a/test/files/presentation/t5708.check b/test/files/presentation/t5708.check
index 04806b5867..4b33893e98 100644
--- a/test/files/presentation/t5708.check
+++ b/test/files/presentation/t5708.check
@@ -3,7 +3,7 @@ reload: Completions.scala
askTypeCompletion at Completions.scala(17,9)
================================================================================
[response] askTypeCompletion at (17,9)
-retrieved 39 members
+retrieved 37 members
[inaccessible] private def privateM: String
[inaccessible] private[this] val privateV: String
[inaccessible] private[this] val protectedV: String
@@ -22,10 +22,8 @@ def hashCode(): Int
def toString(): String
def →[B](y: B): (test.Compat.type, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check
index 217da34b9c..b77887f8f7 100644
--- a/test/files/presentation/visibility.check
+++ b/test/files/presentation/visibility.check
@@ -3,7 +3,7 @@ reload: Completions.scala
askTypeCompletion at Completions.scala(14,12)
================================================================================
[response] askTypeCompletion at (14,12)
-retrieved 37 members
+retrieved 35 members
[inaccessible] private[this] def secretPrivateThis(): Unit
def +(other: String): String
def ->[B](y: B): (accessibility.Foo, B)
@@ -19,10 +19,8 @@ def someTests(other: accessibility.Foo): Unit
def toString(): String
def →[B](y: B): (accessibility.Foo, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -43,7 +41,7 @@ protected[package lang] def finalize(): Unit
askTypeCompletion at Completions.scala(16,11)
================================================================================
[response] askTypeCompletion at (16,11)
-retrieved 37 members
+retrieved 35 members
def +(other: String): String
def ->[B](y: B): (accessibility.Foo, B)
def ensuring(cond: Boolean): accessibility.Foo
@@ -58,10 +56,8 @@ def someTests(other: accessibility.Foo): Unit
def toString(): String
def →[B](y: B): (accessibility.Foo, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -83,8 +79,7 @@ protected[package lang] def finalize(): Unit
askTypeCompletion at Completions.scala(22,11)
================================================================================
[response] askTypeCompletion at (22,11)
-retrieved 37 members
-[inaccessible] private def secretPrivate(): Unit
+retrieved 34 members
def +(other: String): String
def ->[B](y: B): (accessibility.AccessibilityChecks, B)
def ensuring(cond: Boolean): accessibility.AccessibilityChecks
@@ -100,10 +95,8 @@ def someTests: Unit
def toString(): String
def →[B](y: B): (accessibility.AccessibilityChecks, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -123,7 +116,7 @@ protected[package lang] def finalize(): Unit
askTypeCompletion at Completions.scala(28,10)
================================================================================
[response] askTypeCompletion at (28,10)
-retrieved 37 members
+retrieved 35 members
[inaccessible] private def secretPrivate(): Unit
[inaccessible] private[this] def secretPrivateThis(): Unit
[inaccessible] protected def secretProtected(): Unit
@@ -143,10 +136,8 @@ def someTests(other: accessibility.Foo): Unit
def toString(): String
def →[B](y: B): (accessibility.Foo, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
@@ -163,7 +154,7 @@ protected[package accessibility] def secretProtectedInPackage(): Unit
askTypeCompletion at Completions.scala(37,8)
================================================================================
[response] askTypeCompletion at (37,8)
-retrieved 37 members
+retrieved 35 members
[inaccessible] private def secretPrivate(): Unit
[inaccessible] private[this] def secretPrivateThis(): Unit
[inaccessible] protected def secretProtected(): Unit
@@ -184,10 +175,8 @@ def someTests(other: accessibility.Foo): Unit
def toString(): String
def →[B](y: B): (accessibility.Foo, B)
final def !=(x$1: Any): Boolean
-final def !=(x$1: AnyRef): Boolean
final def ##(): Int
final def ==(x$1: Any): Boolean
-final def ==(x$1: AnyRef): Boolean
final def asInstanceOf[T0]: T0
final def eq(x$1: AnyRef): Boolean
final def isInstanceOf[T0]: Boolean
diff --git a/test/files/run/inferred-type-constructors.check b/test/files/run/inferred-type-constructors.check
new file mode 100644
index 0000000000..5992ef02ad
--- /dev/null
+++ b/test/files/run/inferred-type-constructors.check
@@ -0,0 +1,56 @@
+warning: there were 2 feature warning(s); re-run with -feature for details
+ p.Iterable[Int]
+ p.Set[Int]
+ p.Seq[Int]
+ p.m.Set[Int]
+ p.m.Seq[Int]
+ private[m] p.m.ASet[Int]
+ p.i.Seq[Int]
+ private[i] p.i.ASet[Int]
+ private[i] p.i.ASeq[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Set[Int]
+ p.Iterable[Int]
+ p.Set[Int]
+ p.Iterable[Int]
+ p.Set[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Seq[Int]
+ p.Iterable[Int]
+ p.Seq[Int]
+ p.Iterable[Int]
+ p.Seq[Int]
+ p.Iterable[Int]
+ p.m.Set[Int]
+ p.Iterable[Int]
+ p.Set[Int]
+ p.Iterable[Int]
+ p.Iterable[Int]
+ p.Seq[Int]
+ p.Iterable[Int]
+ p.Seq[Int]
+ p.Iterable[Int]
+ private[p] p.ASet[Int]
+ private[p] p.AIterable[Int]
+ p.Iterable[Int]
+ p.i.Seq[Int]
+ private[p] p.AIterable[Int]
+ List[Nothing]
+ scala.collection.immutable.Vector[Nothing]
+ scala.collection.immutable.Iterable[(Int, Int)]
+ scala.collection.immutable.Set[Int]
+ Seq[Int]
+ Array[Int]
+ scala.collection.AbstractSet[Int]
+ Comparable[java.lang.String]
+ scala.collection.immutable.LinearSeq[Int]
+ Iterable[Int]
diff --git a/test/files/run/inferred-type-constructors.scala b/test/files/run/inferred-type-constructors.scala
new file mode 100644
index 0000000000..79a8653f68
--- /dev/null
+++ b/test/files/run/inferred-type-constructors.scala
@@ -0,0 +1,125 @@
+package p {
+ trait TCon[+CC[X]] {
+ def fPublic: CC[Int] = ???
+ private[p] def fPackagePrivate: CC[Int] = ???
+ protected[p] def fPackageProtected: CC[Int] = ???
+ }
+ trait Iterable[+A] extends TCon[Iterable]
+ trait Set[A] extends Iterable[A] with TCon[Set]
+ trait Seq[+A] extends Iterable[A] with TCon[Seq]
+
+ private[p] abstract class AIterable[+A] extends Iterable[A]
+ private[p] abstract class ASeq[+A] extends AIterable[A] with Seq[A]
+ private[p] abstract class ASet[A] extends AIterable[A] with Set[A]
+
+ package m {
+ private[m] abstract class ASeq[A] extends p.ASeq[A] with Seq[A]
+ private[m] abstract class ASet[A] extends p.ASet[A] with Set[A]
+ trait Set[A] extends p.Set[A] with TCon[Set]
+ trait Seq[A] extends p.Seq[A] with TCon[Seq]
+ trait BitSet extends ASet[Int]
+ trait IntSeq extends ASeq[Int]
+ }
+
+ package i {
+ private[i] abstract class ASeq[+A] extends p.ASeq[A] with Seq[A]
+ private[i] abstract class ASet[A] extends p.ASet[A] with Set[A]
+ trait Set[A] extends p.Set[A] with TCon[Set]
+ trait Seq[+A] extends p.Seq[A] with TCon[Seq]
+ trait BitSet extends ASet[Int]
+ trait IntSeq extends ASeq[Int]
+ }
+}
+
+object Test {
+ import scala.reflect.runtime.universe._
+ // Complicated by the absence of usable type constructor type tags.
+ def extract[A, CC[X]](xs: CC[A]): CC[A] = xs
+ def whatis[T: TypeTag](x: T): Unit = {
+ val tpe = typeOf[T]
+ val access = tpe.typeSymbol.asInstanceOf[scala.reflect.internal.HasFlags].accessString.replaceAllLiterally("package ", "")
+ println(f"$access%15s $tpe")
+ }
+
+ trait IntIterable extends p.Iterable[Int]
+ trait IntSet extends p.Set[Int]
+ trait IntSeq extends p.Seq[Int]
+
+ trait MutableIntSet extends p.m.Set[Int]
+ trait MutableIntSeq extends p.m.Seq[Int]
+
+ trait ImmutableIntSet extends p.i.Set[Int]
+ trait ImmutableIntSeq extends p.i.Seq[Int]
+
+ def f1: IntIterable = null
+ def f2: IntSet = null
+ def f3: IntSeq = null
+
+ def g1: MutableIntSet = null
+ def g2: MutableIntSeq = null
+ def g3: p.m.BitSet = null
+
+ def h1: ImmutableIntSeq = null
+ def h2: p.i.BitSet = null
+ def h3: p.i.IntSeq = null
+
+ def main(args: Array[String]): Unit = {
+ whatis(extract(f1))
+ whatis(extract(f2))
+ whatis(extract(f3))
+ whatis(extract(g1))
+ whatis(extract(g2))
+ whatis(extract(g3))
+ whatis(extract(h1))
+ whatis(extract(h2))
+ whatis(extract(h3))
+
+ whatis(extract(if (true) f1 else f2))
+ whatis(extract(if (true) f1 else f3))
+ whatis(extract(if (true) f1 else g1))
+ whatis(extract(if (true) f1 else g2))
+ whatis(extract(if (true) f1 else g3))
+ whatis(extract(if (true) f1 else h1))
+ whatis(extract(if (true) f1 else h2))
+ whatis(extract(if (true) f1 else h3))
+ whatis(extract(if (true) f2 else f3))
+ whatis(extract(if (true) f2 else g1))
+ whatis(extract(if (true) f2 else g2))
+ whatis(extract(if (true) f2 else g3))
+ whatis(extract(if (true) f2 else h1))
+ whatis(extract(if (true) f2 else h2))
+ whatis(extract(if (true) f2 else h3))
+ whatis(extract(if (true) f3 else g1))
+ whatis(extract(if (true) f3 else g2))
+ whatis(extract(if (true) f3 else g3))
+ whatis(extract(if (true) f3 else h1))
+ whatis(extract(if (true) f3 else h2))
+ whatis(extract(if (true) f3 else h3))
+ whatis(extract(if (true) g1 else g2))
+ whatis(extract(if (true) g1 else g3))
+ whatis(extract(if (true) g1 else h1))
+ whatis(extract(if (true) g1 else h2))
+ whatis(extract(if (true) g1 else h3))
+ whatis(extract(if (true) g2 else g3))
+ whatis(extract(if (true) g2 else h1))
+ whatis(extract(if (true) g2 else h2))
+ whatis(extract(if (true) g2 else h3))
+ whatis(extract(if (true) g3 else h1))
+ whatis(extract(if (true) g3 else h2))
+ whatis(extract(if (true) g3 else h3))
+ whatis(extract(if (true) h1 else h2))
+ whatis(extract(if (true) h1 else h3))
+ whatis(extract(if (true) h2 else h3))
+
+ whatis(extract(Nil))
+ whatis(extract(Vector()))
+ whatis(extract(Map[Int,Int]()))
+ whatis(extract(Set[Int]()))
+ whatis(extract(Seq[Int]()))
+ whatis(extract(Array[Int]()))
+ whatis(extract(scala.collection.immutable.BitSet(1)))
+ whatis(extract("abc"))
+ whatis(extract(if (true) Stream(1) else List(1)))
+ whatis(extract(if (true) Seq(1) else Set(1)))
+ }
+}
diff --git a/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
index 624479480d..f038d8714f 100644
--- a/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
@@ -3,7 +3,7 @@ import scala.reflect.macros.blackbox.Context
object Impls {
def foo(c: Context)(x: c.Expr[Int]) = {
import c.universe._
- val x1 = c.Expr[Int](c.resetAllAttrs(x.tree))
+ val x1 = c.Expr[Int](c.untypecheck(x.tree))
c.Expr[Int](Literal(Constant(c.eval(x1))))
}
}
diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check
index 352aefaf25..b153ae0470 100644
--- a/test/files/run/reflection-magicsymbols-invoke.check
+++ b/test/files/run/reflection-magicsymbols-invoke.check
@@ -28,7 +28,7 @@ it's important to print the list of AnyVal's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor AnyVal: ()AnyVal
method getClass: ()Class[_ <: AnyVal]
-testing AnyVal.<init>: class java.lang.InstantiationException: null
+testing AnyVal.<init>: class scala.ScalaReflectionException: unsupported symbol constructor AnyVal when invoking bytecodeless method mirror for scala.AnyVal.<init>(): AnyVal (bound to null)
testing AnyVal.getClass: class scala.ScalaReflectionException: expected a member of class Integer, you provided method scala.AnyVal.getClass
============
AnyRef
@@ -36,12 +36,10 @@ it's important to print the list of AnyRef's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor Object: ()java.lang.Object
method !=: (x$1: Any)Boolean
-method !=: (x$1: AnyRef)Boolean
method ##: ()Int
method $asInstanceOf: [T0]()T0
method $isInstanceOf: [T0]()Boolean
method ==: (x$1: Any)Boolean
-method ==: (x$1: AnyRef)Boolean
method asInstanceOf: [T0]=> T0
method clone: ()java.lang.Object
method eq: (x$1: AnyRef)Boolean
@@ -82,14 +80,11 @@ Array
it's important to print the list of Array's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor Array: (_length: Int)Array[T]
-constructor Cloneable: ()java.lang.Cloneable
method !=: (x$1: Any)Boolean
-method !=: (x$1: AnyRef)Boolean
method ##: ()Int
method $asInstanceOf: [T0]()T0
method $isInstanceOf: [T0]()Boolean
method ==: (x$1: Any)Boolean
-method ==: (x$1: AnyRef)Boolean
method apply: (i: Int)T
method asInstanceOf: [T0]=> T0
method clone: ()Array[T]
diff --git a/test/files/run/reflection-sorted-members.check b/test/files/run/reflection-sorted-members.check
index c148e19e69..415e073149 100644
--- a/test/files/run/reflection-sorted-members.check
+++ b/test/files/run/reflection-sorted-members.check
@@ -1,4 +1,3 @@
value a
value b
value c
-value x
diff --git a/test/files/run/t261.check b/test/files/run/t261.check
new file mode 100644
index 0000000000..35d242ba79
--- /dev/null
+++ b/test/files/run/t261.check
@@ -0,0 +1,2 @@
+A
+B
diff --git a/test/files/run/t261.scala b/test/files/run/t261.scala
new file mode 100644
index 0000000000..d8ddb28c00
--- /dev/null
+++ b/test/files/run/t261.scala
@@ -0,0 +1,11 @@
+trait A { val foo: String = "A" }
+trait B {
+ private val foo: String = "B"
+ def f = println(foo)
+}
+object Test extends A with B {
+ def main(args: Array[String]) = {
+ println(foo)
+ f
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6260-delambdafy.check b/test/files/run/t6260-delambdafy.check
new file mode 100644
index 0000000000..b2a7bed988
--- /dev/null
+++ b/test/files/run/t6260-delambdafy.check
@@ -0,0 +1,4 @@
+f(C@2e)
+
+Test$lambda$1$$apply
+apply
diff --git a/test/files/run/t6260-delambdafy.flags b/test/files/run/t6260-delambdafy.flags
new file mode 100644
index 0000000000..48b438ddf8
--- /dev/null
+++ b/test/files/run/t6260-delambdafy.flags
@@ -0,0 +1 @@
+-Ydelambdafy:method
diff --git a/test/files/run/t6260-delambdafy.scala b/test/files/run/t6260-delambdafy.scala
new file mode 100644
index 0000000000..056b1edd4e
--- /dev/null
+++ b/test/files/run/t6260-delambdafy.scala
@@ -0,0 +1,12 @@
+class C[A](private val a: Any) extends AnyVal
+
+object Test {
+ val f = (x: C[Any]) => {println(s"f($x)"); x}
+ def main(args: Array[String]) {
+ f(new C("."))
+ val methods = f.getClass.getDeclaredMethods.map(_.getName).sorted
+ println("")
+ println(methods.mkString("\n"))
+ }
+}
+
diff --git a/test/files/run/t6260c.check b/test/files/run/t6260c.check
new file mode 100644
index 0000000000..1a57f2d741
--- /dev/null
+++ b/test/files/run/t6260c.check
@@ -0,0 +1,5 @@
+f(C@2e)
+
+Test$$anonfun$$apply
+apply
+g(C@2e)
diff --git a/test/files/run/t6260c.scala b/test/files/run/t6260c.scala
new file mode 100644
index 0000000000..845dc157b7
--- /dev/null
+++ b/test/files/run/t6260c.scala
@@ -0,0 +1,17 @@
+class C[A](private val a: Any) extends AnyVal
+
+object Test {
+ val f = (x: C[Any]) => {println(s"f($x)"); x}
+ trait T[A] {
+ def apply(a: A): A
+ }
+ val g = new T[C[Any]] { def apply(a: C[Any]) = { println(s"g($a)"); a } }
+ def main(args: Array[String]) {
+ f(new C("."))
+ val methods = f.getClass.getDeclaredMethods.map(_.getName).sorted
+ println("")
+ println(methods.mkString("\n"))
+ g.apply(new C("."))
+ }
+}
+
diff --git a/test/files/run/t6411a.check b/test/files/run/t6411a.check
new file mode 100644
index 0000000000..9226146195
--- /dev/null
+++ b/test/files/run/t6411a.check
@@ -0,0 +1,96 @@
+meth = method yg_1
+as seen by Scala reflection: def yg_1[T](y: Y[T]): T
+as seen by Java reflection: public java.lang.Object a$.yg_1(java.lang.Object)
+result = 1
+meth = method yg_1
+as seen by Scala reflection: def yg_1[T](y: Y[T]): T
+as seen by Java reflection: public java.lang.Object a$.yg_1(java.lang.Object)
+result = 1
+meth = method yi_2
+as seen by Scala reflection: def yi_2(y: Y[Int]): Int
+as seen by Java reflection: public int a$.yi_2(java.lang.Integer)
+result = 2
+meth = method yi_2
+as seen by Scala reflection: def yi_2(y: Y[Int]): Int
+as seen by Java reflection: public int a$.yi_2(java.lang.Integer)
+result = class java.lang.IllegalArgumentException: argument type mismatch
+meth = method ys_3
+as seen by Scala reflection: def ys_3(y: Y[String]): String
+as seen by Java reflection: public java.lang.String a$.ys_3(java.lang.String)
+result = class java.lang.IllegalArgumentException: argument type mismatch
+meth = method ys_3
+as seen by Scala reflection: def ys_3(y: Y[String]): String
+as seen by Java reflection: public java.lang.String a$.ys_3(java.lang.String)
+result = 3
+meth = method ya_4
+as seen by Scala reflection: def ya_4(ys: Array[Y[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.ya_4(Y[])
+result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
+meth = method ya_4
+as seen by Scala reflection: def ya_4(ys: Array[Y[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.ya_4(Y[])
+result = List(4)
+meth = method yl_5
+as seen by Scala reflection: def yl_5(ys: List[Y[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.yl_5(scala.collection.immutable.List)
+result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
+meth = method yl_5
+as seen by Scala reflection: def yl_5(ys: List[Y[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.yl_5(scala.collection.immutable.List)
+result = List(5)
+meth = method yni_7
+as seen by Scala reflection: def yni_7(y: => Y[Int]): Int
+as seen by Java reflection: public int a$.yni_7(scala.Function0)
+result = 7
+meth = method yns_8
+as seen by Scala reflection: def yns_8(y: => Y[String]): String
+as seen by Java reflection: public java.lang.String a$.yns_8(scala.Function0)
+result = 8
+meth = method zg_1
+as seen by Scala reflection: def zg_1[T](z: Z[T]): T
+as seen by Java reflection: public java.lang.Object a$.zg_1(Z)
+result = 1
+meth = method zg_1
+as seen by Scala reflection: def zg_1[T](z: Z[T]): T
+as seen by Java reflection: public java.lang.Object a$.zg_1(Z)
+result = 1
+meth = method zi_2
+as seen by Scala reflection: def zi_2(z: Z[Int]): Int
+as seen by Java reflection: public int a$.zi_2(Z)
+result = 2
+meth = method zi_2
+as seen by Scala reflection: def zi_2(z: Z[Int]): Int
+as seen by Java reflection: public int a$.zi_2(Z)
+result = class java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
+meth = method zs_3
+as seen by Scala reflection: def zs_3(z: Z[String]): String
+as seen by Java reflection: public java.lang.String a$.zs_3(Z)
+result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
+meth = method zs_3
+as seen by Scala reflection: def zs_3(z: Z[String]): String
+as seen by Java reflection: public java.lang.String a$.zs_3(Z)
+result = 3
+meth = method za_4
+as seen by Scala reflection: def za_4(zs: Array[Z[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.za_4(Z[])
+result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
+meth = method za_4
+as seen by Scala reflection: def za_4(zs: Array[Z[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.za_4(Z[])
+result = List(4)
+meth = method zl_5
+as seen by Scala reflection: def zl_5(zs: List[Z[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.zl_5(scala.collection.immutable.List)
+result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
+meth = method zl_5
+as seen by Scala reflection: def zl_5(zs: List[Z[String]]): List[String]
+as seen by Java reflection: public scala.collection.immutable.List a$.zl_5(scala.collection.immutable.List)
+result = List(5)
+meth = method zni_7
+as seen by Scala reflection: def zni_7(z: => Z[Int]): Int
+as seen by Java reflection: public int a$.zni_7(scala.Function0)
+result = 7
+meth = method zns_8
+as seen by Scala reflection: def zns_8(z: => Z[String]): String
+as seen by Java reflection: public java.lang.String a$.zns_8(scala.Function0)
+result = 8
diff --git a/test/files/run/t6411a.scala b/test/files/run/t6411a.scala
new file mode 100644
index 0000000000..3bfeac2890
--- /dev/null
+++ b/test/files/run/t6411a.scala
@@ -0,0 +1,81 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.language.reflectiveCalls
+
+class Y[T](val i: T) extends AnyVal {
+ override def toString = s"Y($i)"
+}
+class Z[T](val i: T) extends AnyRef {
+ override def toString = s"Z($i)"
+}
+
+object a {
+ def yg_1[T](y: Y[T]) = y.i
+ def yi_2(y: Y[Int]) = y.i
+ def ys_3(y: Y[String]) = y.i
+ def ya_4(ys: Array[Y[String]]) = ys.toList.map(_.i)
+ def yl_5(ys: List[Y[String]]) = ys.map(_.i)
+ def yv_6(ys: Y[String]*) = ys.toList.map(_.i)
+ def yni_7(y: => Y[Int]) = y.i
+ def yns_8(y: => Y[String]) = y.i
+
+ def zg_1[T](z: Z[T]) = z.i
+ def zi_2(z: Z[Int]) = z.i
+ def zs_3(z: Z[String]) = z.i
+ def za_4(zs: Array[Z[String]]) = zs.toList.map(_.i)
+ def zl_5(zs: List[Z[String]]) = zs.map(_.i)
+ def zv_6(zs: Z[String]*) = zs.toList.map(_.i)
+ def zni_7(z: => Z[Int]) = z.i
+ def zns_8(z: => Z[String]) = z.i
+}
+
+object Test extends App {
+ def test(methName: String, arg: Any) = {
+ val moduleA = cm.reflect(a)
+ val msym = moduleA.symbol.typeSignature.declaration(TermName(methName)).asMethod
+ println(s"meth = $msym")
+ val mmirror = moduleA.reflectMethod(msym)
+ val mresult =
+ try { mmirror(arg) }
+ catch {
+ case ex: Exception =>
+ val ex1 = scala.reflect.runtime.ReflectionUtils.unwrapThrowable(ex)
+ s"${ex1.getClass}: ${ex1.getMessage}"
+ }
+ println(s"as seen by Scala reflection: ${msym.asInstanceOf[scala.reflect.internal.Symbols#Symbol].defString}")
+ println(s"as seen by Java reflection: ${mmirror.asInstanceOf[{val jmeth: java.lang.reflect.Method}].jmeth}")
+ println(s"result = $mresult")
+ }
+
+ test("yg_1", new Y(1))
+ test("yg_1", new Y("1"))
+ test("yi_2", new Y(2))
+ test("yi_2", new Y("2"))
+ test("ys_3", new Y(3))
+ test("ys_3", new Y("3"))
+ test("ya_4", Array(new Y(4)))
+ test("ya_4", Array(new Y("4")))
+ test("yl_5", List(new Y(5)))
+ test("yl_5", List(new Y("5")))
+ // FIXME: disabled because of SI-7056
+ // test("yv_6", new Y(6))
+ // test("yv_6", new Y("6"))
+ test("yni_7", new Y(7))
+ test("yns_8", new Y("8"))
+
+ test("zg_1", new Z(1))
+ test("zg_1", new Z("1"))
+ test("zi_2", new Z(2))
+ test("zi_2", new Z("2"))
+ test("zs_3", new Z(3))
+ test("zs_3", new Z("3"))
+ test("za_4", Array(new Z(4)))
+ test("za_4", Array(new Z("4")))
+ test("zl_5", List(new Z(5)))
+ test("zl_5", List(new Z("5")))
+ // FIXME: disabled because of SI-7056
+ // test("zv_6", new Z(6))
+ // test("zv_6", new Z("6"))
+ test("zni_7", new Z(7))
+ test("zns_8", new Z("8"))
+} \ No newline at end of file
diff --git a/test/files/run/t6411b.check b/test/files/run/t6411b.check
new file mode 100644
index 0000000000..e20bed6d8d
--- /dev/null
+++ b/test/files/run/t6411b.check
@@ -0,0 +1 @@
+Bar(Foo(3))
diff --git a/test/files/run/t6411b.scala b/test/files/run/t6411b.scala
new file mode 100644
index 0000000000..af30108826
--- /dev/null
+++ b/test/files/run/t6411b.scala
@@ -0,0 +1,12 @@
+import scala.reflect.runtime.universe._
+
+case class Foo(n: Int) extends AnyVal
+case class Bar(foo: Foo)
+
+object Test extends App {
+ val mirror = runtimeMirror(getClass.getClassLoader)
+ val cm = mirror.reflectClass(typeOf[Bar].typeSymbol.asClass)
+ val ctor = typeOf[Bar].declaration(nme.CONSTRUCTOR).asMethod
+ val ctorm = cm.reflectConstructor(ctor)
+ println(ctorm(Foo(3)))
+} \ No newline at end of file
diff --git a/test/files/run/t7240/Macros_1.scala b/test/files/run/t7240/Macros_1.scala
index 019ddf7cd6..c6e976038d 100644
--- a/test/files/run/t7240/Macros_1.scala
+++ b/test/files/run/t7240/Macros_1.scala
@@ -41,7 +41,7 @@ object Bakery {
def constructor = Apply(Select(New(Ident(newTypeName("eval"))), nme.CONSTRUCTOR), List())
c.eval(c.Expr[Any](
- c.resetAllAttrs(Block(composeDSL(Literal(Constant(1))), constructor))))
+ c.untypecheck(Block(composeDSL(Literal(Constant(1))), constructor))))
c.Expr[Any](Literal(Constant(1)))
}
diff --git a/test/files/run/t7319.check b/test/files/run/t7319.check
index d03ee3a6cf..b7443aa0c4 100644
--- a/test/files/run/t7319.check
+++ b/test/files/run/t7319.check
@@ -21,7 +21,7 @@ scala> convert(Some[Int](0))
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Some[Int]
- required: ?F forSome { type _$1 <: ?F forSome { type _$2 } }
+ required: ?F[_$1] forSome { type _$1 <: ?F[_$2] forSome { type _$2 } }
convert(Some[Int](0))
^
<console>:12: error: type mismatch;
diff --git a/test/files/run/t7328.check b/test/files/run/t7328.check
new file mode 100644
index 0000000000..e386fe70d9
--- /dev/null
+++ b/test/files/run/t7328.check
@@ -0,0 +1,4 @@
+Foo
+Foo(3)
+Foo(3)
+Foo(5)
diff --git a/test/files/run/t7328.scala b/test/files/run/t7328.scala
new file mode 100644
index 0000000000..8816fa2347
--- /dev/null
+++ b/test/files/run/t7328.scala
@@ -0,0 +1,18 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+case class Foo(x: Int) extends AnyVal
+case class Bar(foo: Foo)
+
+object Test extends App {
+ val foo = typeOf[Bar].declaration(TermName("foo")).asMethod
+ println(foo.returnType) // Foo
+
+ val bar = Bar(Foo(3))
+ println(bar.foo) // Foo(3)
+
+ val im = cm.reflect(bar)
+ println(im.reflectField(foo).get) // incorrectly gives java.lang.Integer(3) not Foo(3)
+ im.reflectField(foo).set(Foo(5)) // java.lang.IllegalArgumentException: Can not set int field Bar.foo to Foo
+ println(im.reflectMethod(foo)()) // incorrectly gives java.lang.Integer(3) not Foo(3)
+} \ No newline at end of file
diff --git a/test/files/run/t7475b.check b/test/files/run/t7475b.check
new file mode 100644
index 0000000000..51993f072d
--- /dev/null
+++ b/test/files/run/t7475b.check
@@ -0,0 +1,2 @@
+2
+2
diff --git a/test/files/run/t7475b.scala b/test/files/run/t7475b.scala
new file mode 100644
index 0000000000..a205602b6d
--- /dev/null
+++ b/test/files/run/t7475b.scala
@@ -0,0 +1,11 @@
+trait A { private val x = 1 }
+trait B { val x = 2 }
+trait C1 extends B with A { println(x) }
+trait C2 extends A with B { println(x) }
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ new C1 { }
+ new C2 { }
+ }
+}
diff --git a/test/files/run/t7507.scala b/test/files/run/t7507.scala
index 6c1959ddac..a5eab6248f 100644
--- a/test/files/run/t7507.scala
+++ b/test/files/run/t7507.scala
@@ -4,6 +4,10 @@ trait Cake extends Slice
trait Slice { self: Cake => // must have self type that extends `Slice`
private[this] val bippy = () // must be private[this]
locally(bippy)
+ class C1 {
+ locally(bippy)
+ locally(self.bippy)
+ }
}
// Originally reported bug:
diff --git a/test/files/run/t7570a.check b/test/files/run/t7570a.check
new file mode 100644
index 0000000000..3cc58df837
--- /dev/null
+++ b/test/files/run/t7570a.check
@@ -0,0 +1 @@
+C
diff --git a/test/files/run/t7570a.scala b/test/files/run/t7570a.scala
new file mode 100644
index 0000000000..b8b4ddeaf2
--- /dev/null
+++ b/test/files/run/t7570a.scala
@@ -0,0 +1,11 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+import definitions._
+import Flag._
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val csym = tb.define(q"""class C { override def toString = "C" }""")
+ println(tb.eval(q"new $csym"))
+} \ No newline at end of file
diff --git a/test/files/run/t7570b.check b/test/files/run/t7570b.check
new file mode 100644
index 0000000000..0c28247025
--- /dev/null
+++ b/test/files/run/t7570b.check
@@ -0,0 +1 @@
+compilation failed: reflective toolbox has failed: cannot have free terms in a top-level definition
diff --git a/test/files/run/t7570b.scala b/test/files/run/t7570b.scala
new file mode 100644
index 0000000000..f1db193186
--- /dev/null
+++ b/test/files/run/t7570b.scala
@@ -0,0 +1,17 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import definitions._
+import Flag._
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val msg = build.newFreeTerm("msg", "C")
+ build.setTypeSignature(msg, typeOf[String])
+ try {
+ val csym = tb.define(q"""class C { override def toString = $msg }""")
+ println(tb.eval(q"new $csym"))
+ } catch {
+ case ToolBoxError(message, _) => println(s"compilation failed: $message")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t7570c.check b/test/files/run/t7570c.check
new file mode 100644
index 0000000000..61e659d9e0
--- /dev/null
+++ b/test/files/run/t7570c.check
@@ -0,0 +1,2 @@
+(class C,true,false,false)
+(object D,false,true,false)
diff --git a/test/files/run/t7570c.scala b/test/files/run/t7570c.scala
new file mode 100644
index 0000000000..a5bdbffe18
--- /dev/null
+++ b/test/files/run/t7570c.scala
@@ -0,0 +1,13 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import definitions._
+import Flag._
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val csym = tb.define(q"""class C { override def toString = "C" }""")
+ println((csym, csym.isClass, csym.isModule, csym.isModuleClass))
+ val dsym = tb.define(q"""object D { override def toString = "D" }""".asInstanceOf[ModuleDef])
+ println((dsym, dsym.isClass, dsym.isModule, dsym.isModuleClass))
+} \ No newline at end of file
diff --git a/test/disabled/run/t7843-jsr223-service.check b/test/files/run/t7843-jsr223-service.check
index a668df3567..a668df3567 100644
--- a/test/disabled/run/t7843-jsr223-service.check
+++ b/test/files/run/t7843-jsr223-service.check
diff --git a/test/files/run/t7843-jsr223-service.scala b/test/files/run/t7843-jsr223-service.scala
new file mode 100644
index 0000000000..31112212ea
--- /dev/null
+++ b/test/files/run/t7843-jsr223-service.scala
@@ -0,0 +1,8 @@
+import scala.tools.nsc.interpreter.IMain
+
+object Test extends App {
+ val engine = new IMain.Factory getScriptEngine()
+ engine.asInstanceOf[IMain].settings.usejavacp.value = true
+ engine put ("n", 10)
+ engine eval "1 to n.asInstanceOf[Int] foreach print"
+}
diff --git a/test/files/run/t7933.check b/test/files/run/t7933.check
new file mode 100644
index 0000000000..317e9677c3
--- /dev/null
+++ b/test/files/run/t7933.check
@@ -0,0 +1,2 @@
+hello
+hello
diff --git a/test/files/run/t7933.scala b/test/files/run/t7933.scala
new file mode 100644
index 0000000000..b06dffcd80
--- /dev/null
+++ b/test/files/run/t7933.scala
@@ -0,0 +1,11 @@
+import scala.tools.nsc.interpreter.IMain
+
+object Test extends App {
+ val engine = new IMain.Factory getScriptEngine()
+ engine.asInstanceOf[IMain].settings.usejavacp.value = true
+ val res2 = engine.asInstanceOf[javax.script.Compilable]
+ res2 compile "8" eval()
+ val res5 = res2 compile """println("hello") ; 8"""
+ res5 eval()
+ res5 eval()
+}
diff --git a/test/files/run/t8245.scala b/test/files/run/t8245.scala
new file mode 100644
index 0000000000..d44defbb9e
--- /dev/null
+++ b/test/files/run/t8245.scala
@@ -0,0 +1,14 @@
+object Test {
+ def foo(o: Option[Int]): Int = {
+ lazy val i: Int = {
+ def local: Int = {if ("".isEmpty) return 42; -42}
+ assert(local == 42)
+ o.getOrElse(return -1)
+ }
+ i + 1
+ }
+
+ def main(args: Array[String]) {
+ assert(foo(None) == -1)
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
index 582e915258..ca4c8609ac 100644
--- a/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
@@ -29,4 +29,8 @@ object PatternConstructionProps extends QuasiquoteProperties("pattern constructi
property("splice into casedef") = forAll { (pat: Tree, cond: Tree, body: Tree) =>
cq"$pat if $cond => $body" ≈ CaseDef(pat, cond, body)
}
-} \ No newline at end of file
+
+ property("splice into alternative") = forAll { (first: Tree, rest: List[Tree]) =>
+ pq"$first | ..$rest" ≈ Alternative(first :: rest)
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala
index c8e66c7ef5..ad3266bcec 100644
--- a/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/PatternDeconstructionProps.scala
@@ -36,4 +36,9 @@ object PatternDeconstructionProps extends QuasiquoteProperties("pattern deconstr
val cq"$pat0 if $cond0 => $body0" = cq"$pat if $cond => $body"
pat0 ≈ pat && cond0 ≈ cond && body0 ≈ body
}
+
+ property("extract alternative") = forAll { (first: Tree, rest: List[Tree]) =>
+ val pq"$first1 | ..$rest1" = pq"$first | ..$rest"
+ first1 ≈ first && rest1 ≈ rest
+ }
}
diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala
index 7bb8ca958b..0d6f43db06 100644
--- a/test/junit/scala/collection/SetMapConsistencyTest.scala
+++ b/test/junit/scala/collection/SetMapConsistencyTest.scala
@@ -478,7 +478,7 @@ class SetMapConsistencyTest {
}
@Test
- def si8213() {
+ def testSI8213() {
val am = new scala.collection.mutable.AnyRefMap[String, Int]
for (i <- 0 until 1024) am += i.toString -> i
am.getOrElseUpdate("1024", { am.clear; -1 })
@@ -488,4 +488,23 @@ class SetMapConsistencyTest {
lm.getOrElseUpdate(1024, { lm.clear; -1 })
assert(lm == scala.collection.mutable.LongMap(1024L -> -1))
}
+
+ // Mutating when an iterator is in the wild shouldn't produce random junk in the iterator
+ // Todo: test all sets/maps this way
+ @Test
+ def testSI8154() {
+ def f() = {
+ val xs = scala.collection.mutable.AnyRefMap[String, Int]("a" -> 1)
+ val it = xs.iterator
+ it.hasNext
+ xs.clear()
+
+ if (it.hasNext) Some(it.next)
+ else None
+ }
+ assert(f() match {
+ case Some((a,b)) if (a==null || b==null) => false
+ case _ => true
+ })
+ }
}
diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
index a3699a4eeb..b42e9a07cb 100644
--- a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
+++ b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
@@ -69,6 +69,7 @@ class SymbolTableForUnitTesting extends SymbolTable {
// Members declared in scala.reflect.internal.Required
def picklerPhase: scala.reflect.internal.Phase = SomePhase
+ def erasurePhase: scala.reflect.internal.Phase = SomePhase
// Members declared in scala.reflect.internal.SymbolTable
def currentRunId: Int = 1
diff --git a/test/files/pos/t1786.scala b/test/pending/pos/t1786.scala
index 32d6c06f6e..6299eb9eae 100644
--- a/test/files/pos/t1786.scala
+++ b/test/pending/pos/t1786.scala
@@ -1,3 +1,11 @@
+/** This a consequence of the current type checking algorithm, where bounds are checked only after variables are instantiated.
+ * I believe this will change once we go to contraint-based type inference.
+ * Alternatively, we can pursue a more extensive fix to SI-6169
+ *
+ * The below code shows a compiler flaw in that the wildcard "_" as value for a bounded type parameter either
+ * breaks the boundary - as it result in Any - or doesn't evaluate to the boundary (as I'd hoped it to be).
+*/
+
class SomeClass(val intValue:Int)
class MyClass[T <: SomeClass](val myValue:T)
class Flooz[A >: Null <: SomeClass, T >: Null <: A](var value: T)
diff --git a/test/files/pos/t5459.scala b/test/pending/pos/t5459.scala
index 971e6f896d..971e6f896d 100644
--- a/test/files/pos/t5459.scala
+++ b/test/pending/pos/t5459.scala
diff --git a/test/pending/run/idempotency-partial-functions.scala b/test/pending/run/idempotency-partial-functions.scala
index e673da5a29..b26c442599 100644
--- a/test/pending/run/idempotency-partial-functions.scala
+++ b/test/pending/run/idempotency-partial-functions.scala
@@ -22,7 +22,7 @@ object Test extends App {
val tb = cm.mkToolBox()
val tpartials = tb.typecheck(partials.tree)
println(tpartials)
- val rtpartials = tb.resetAllAttrs(tpartials)
+ val rtpartials = tb.untypecheck(tpartials)
println(tb.eval(rtpartials))
}
Test.main(null) \ No newline at end of file