summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala8
-rw-r--r--src/compiler/scala/reflect/reify/Taggers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala22
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala28
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala16
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala82
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala299
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala23
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala24
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala12
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala6
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala29
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala2
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala2
-rw-r--r--src/library/scala/collection/immutable/HashMap.scala51
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala22
-rw-r--r--src/library/scala/collection/immutable/Stream.scala2
-rw-r--r--src/library/scala/collection/mutable/ResizableArray.scala22
-rw-r--r--src/library/scala/math/Numeric.scala4
-rw-r--r--src/library/scala/ref/WeakReference.scala2
-rw-r--r--src/library/scala/sys/process/ProcessBuilder.scala2
-rw-r--r--src/library/scala/util/Sorting.scala4
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala4
-rw-r--r--src/reflect/scala/reflect/api/Liftables.scala30
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala40
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala14
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala1
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala3
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala5
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala12
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala3
40 files changed, 472 insertions, 408 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index 4a1122b913..85204d0f1b 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -13,7 +13,7 @@ trait Typers {
/**
* @see [[scala.tools.reflect.ToolBox.typeCheck]]
*/
- def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
val context = callsiteTyper.context
val wrapper1 = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _)
@@ -24,7 +24,7 @@ trait Typers {
// typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time
// I'd advise fixing the root cause: finding why the context is not set to report errors
// (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you)
- wrapper(callsiteTyper.silent(_.typed(tree, pt), reportAmbiguousErrors = false) match {
+ wrapper(callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false) match {
case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result
@@ -46,7 +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(tree)
+ def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(universe.duplicateAndKeepPositions(tree))
- def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree)
+ def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(universe.duplicateAndKeepPositions(tree))
}
diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala
index 0c7831b592..093c2bee22 100644
--- a/src/compiler/scala/reflect/reify/Taggers.scala
+++ b/src/compiler/scala/reflect/reify/Taggers.scala
@@ -65,13 +65,13 @@ abstract class Taggers {
case _ =>
translatingReificationErrors(materializer)
}
- try c.typeCheck(result)
+ try c.typecheck(result)
catch { case terr @ TypecheckException(pos, msg) => failTag(result, terr) }
}
def materializeExpr(universe: Tree, mirror: Tree, expr: Tree): Tree = {
val result = translatingReificationErrors(c.reifyTree(universe, mirror, expr))
- try c.typeCheck(result)
+ try c.typecheck(result)
catch { case terr @ TypecheckException(pos, msg) => failExpr(result, terr) }
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 91db1bb92a..61ea9230a7 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -671,6 +671,7 @@ self =>
def isRawBar = isIdent && in.name == raw.BAR
def isIdent = in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT
+ def isMacro = in.token == IDENTIFIER && in.name == nme.MACROkw
def isLiteralToken(token: Token) = token match {
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
@@ -1038,6 +1039,8 @@ self =>
def identForType(): TypeName = ident().toTypeName
def identForType(skipIt: Boolean): TypeName = ident(skipIt).toTypeName
+ def identOrMacro(): Name = if (isMacro) rawIdent() else ident()
+
def selector(t: Tree): Tree = {
val point = in.offset
//assert(t.pos.isDefined, t)
@@ -2551,7 +2554,7 @@ self =>
}
else {
val nameOffset = in.offset
- val name = ident()
+ val name = identOrMacro()
funDefRest(start, nameOffset, mods, name)
}
}
@@ -2584,7 +2587,7 @@ self =>
} else {
if (in.token == EQUALS) {
in.nextTokenAllow(nme.MACROkw)
- if (in.token == IDENTIFIER && in.name == nme.MACROkw) {
+ if (isMacro) {
in.nextToken()
newmods |= Flags.MACRO
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 65bb52159e..87bd498ea1 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -204,8 +204,12 @@ trait Scanners extends ScannersCommon {
val idx = name.start - kwOffset
if (idx >= 0 && idx < kwArray.length) {
token = kwArray(idx)
- if (token == IDENTIFIER && allowIdent != name && emitIdentifierDeprecationWarnings)
- deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated")
+ if (token == IDENTIFIER && allowIdent != name) {
+ if (name == nme.MACROkw)
+ syntaxError(name+" is now a reserved word; usage as an identifier is disallowed")
+ else if (emitIdentifierDeprecationWarnings)
+ deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated")
+ }
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index c546c21d48..933a2f70a1 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -340,7 +340,19 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
else (true, adaptToType(tree, expectedTpe))
}
+ def adaptAndPostErase(tree: Tree, pt: Type): (Boolean, Tree) = {
+ val (needsAdapt, adaptedTree) = adapt(tree, pt)
+ val trans = postErasure.newTransformer(unit)
+ val postErasedTree = trans.atOwner(currentOwner)(trans.transform(adaptedTree)) // SI-8017 elimnates ErasedValueTypes
+ (needsAdapt, postErasedTree)
+ }
+
enteringPhase(currentRun.posterasurePhase) {
+ // e.g, in:
+ // class C(val a: Int) extends AnyVal; (x: Int) => new C(x)
+ //
+ // This type is:
+ // (x: Int)ErasedValueType(class C, Int)
val liftedBodyDefTpe: MethodType = {
val liftedBodySymbol = {
val Apply(method, _) = originalFunction.body
@@ -349,8 +361,14 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
liftedBodySymbol.info.asInstanceOf[MethodType]
}
val (paramNeedsAdaptation, adaptedParams) = (bridgeSyms zip liftedBodyDefTpe.params map {case (bridgeSym, param) => adapt(Ident(bridgeSym) setType bridgeSym.tpe, param.tpe)}).unzip
- val body = Apply(gen.mkAttributedSelect(gen.mkAttributedThis(newClass), applyMethod.symbol), adaptedParams) setType applyMethod.symbol.tpe.resultType
- val (needsReturnAdaptation, adaptedBody) = adapt(typer.typed(body), ObjectTpe)
+ // SI-8017 Before, this code used `applyMethod.symbol.info.resultType`.
+ // But that symbol doesn't have a type history that goes back before `delambdafy`,
+ // so we just see a plain `Int`, rather than `ErasedValueType(C, Int)`.
+ // This triggered primitive boxing, rather than value class boxing.
+ val resTp = liftedBodyDefTpe.finalResultType
+ val body = Apply(gen.mkAttributedSelect(gen.mkAttributedThis(newClass), applyMethod.symbol), adaptedParams) setType resTp
+ val (needsReturnAdaptation, adaptedBody) = adaptAndPostErase(body, ObjectTpe)
+
val needsBridge = (paramNeedsAdaptation contains true) || needsReturnAdaptation
if (needsBridge) {
val methDef = DefDef(bridgeMethSym, List(bridgeParams), adaptedBody)
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index e31211d321..b4329965fc 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -100,23 +100,36 @@ abstract class Flatten extends InfoTransform {
/** Buffers for lifted out classes */
private val liftedDefs = perRunCaches.newMap[Symbol, ListBuffer[Tree]]()
- override def transform(tree: Tree): Tree = {
+ override def transform(tree: Tree): Tree = postTransform {
tree match {
case PackageDef(_, _) =>
liftedDefs(tree.symbol.moduleClass) = new ListBuffer
+ super.transform(tree)
case Template(_, _, _) if tree.symbol.isDefinedInPackage =>
liftedDefs(tree.symbol.owner) = new ListBuffer
+ super.transform(tree)
+ case ClassDef(_, _, _, _) if tree.symbol.isNestedClass =>
+ // SI-5508 Ordering important. In `object O { trait A { trait B } }`, we want `B` to appear after `A` in
+ // the sequence of lifted trees in the enclosing package. Why does this matter? Currently, mixin
+ // needs to transform `A` first to a chance to create accessors for private[this] trait fields
+ // *before* it transforms inner classes that refer to them. This also fixes SI-6231.
+ //
+ // Alternative solutions
+ // - create the private[this] accessors eagerly in Namer (but would this cover private[this] fields
+ // added later phases in compilation?)
+ // - move the accessor creation to the Mixin info transformer
+ val liftedBuffer = liftedDefs(tree.symbol.enclosingTopLevelClass.owner)
+ val index = liftedBuffer.length
+ liftedBuffer.insert(index, super.transform(tree))
+ EmptyTree
case _ =>
+ super.transform(tree)
}
- postTransform(super.transform(tree))
}
private def postTransform(tree: Tree): Tree = {
val sym = tree.symbol
val tree1 = tree match {
- case ClassDef(_, _, _, _) if sym.isNestedClass =>
- liftedDefs(sym.enclosingTopLevelClass.owner) += tree
- EmptyTree
case Select(qual, name) if sym.isStaticModule && !sym.isTopLevel =>
exitingFlatten {
atPos(tree.pos) {
@@ -134,7 +147,10 @@ abstract class Flatten extends InfoTransform {
/** Transform statements and add lifted definitions to them. */
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
val stats1 = super.transformStats(stats, exprOwner)
- if (currentOwner.isPackageClass) stats1 ::: liftedDefs(currentOwner).toList
+ if (currentOwner.isPackageClass) {
+ val lifted = liftedDefs(currentOwner).toList
+ stats1 ::: lifted
+ }
else stats1
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 6da971338f..89f9cb4b06 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -1207,21 +1207,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val iface = toInterface(sym.owner.tpe).typeSymbol
val ifaceGetter = sym getter iface
- def si6231Restriction() {
- // See SI-6231 comments in LamdaLift for ideas on how to lift the restriction.
- val msg = sm"""Implementation restriction: local ${iface.fullLocationString} is unable to automatically capture the
- |free variable ${sym} on behalf of ${currentClass}. You can manually assign it to a val inside the trait,
- |and refer to that val in ${currentClass}. For more details, see SI-6231."""
- reporter.error(tree.pos, msg)
- }
-
- if (ifaceGetter == NoSymbol) {
- if (sym.isParamAccessor) {
- si6231Restriction()
- EmptyTree
- }
- else abort("No getter for " + sym + " in " + iface)
- }
+ if (ifaceGetter == NoSymbol) abort("No getter for " + sym + " in " + iface)
else typedPos(tree.pos)((qual DOT ifaceGetter)())
case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 1723c69180..c505d9dc5f 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -923,7 +923,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Return the specialized overload of `m`, in the given environment. */
private def specializedOverload(owner: Symbol, sym: Symbol, env: TypeEnv, nameSymbol: Symbol = NoSymbol): Symbol = {
- val newFlags = (sym.flags | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR)
+ val newFlags = (sym.flags | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | LAZY)
// this method properly duplicates the symbol's info
val specname = specializedName(nameSymbol orElse sym, env)
( sym.cloneSymbol(owner, newFlags, newName = specname)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index a18068f2e0..0d46a96b81 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -260,7 +260,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
def isBlackbox(expandee: Tree): Boolean = isBlackbox(dissectApplied(expandee).core.symbol)
- def isBlackbox(macroDef: Symbol): Boolean = loadMacroImplBinding(macroDef).map(_.isBlackbox).getOrElse(false)
+ def isBlackbox(macroDef: Symbol): Boolean = {
+ val fastTrackBoxity = fastTrack.get(macroDef).map(_.isBlackbox)
+ val bindingBoxity = loadMacroImplBinding(macroDef).map(_.isBlackbox)
+ fastTrackBoxity orElse bindingBoxity getOrElse false
+ }
def computeMacroDefTypeFromMacroImplRef(macroDdef: DefDef, macroImplRef: Tree): Type = {
macroImplRef match {
@@ -345,7 +349,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
new {
val universe: self.global.type = self.global
val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer]
- val expandee = universe.analyzer.macroExpanderAttachment(expandeeTree).original orElse expandeeTree
+ val expandee = universe.analyzer.macroExpanderAttachment(expandeeTree).original orElse duplicateAndKeepPositions(expandeeTree)
val macroRole = universe.analyzer.macroExpanderAttachment(expandeeTree).role
} with UnaffiliatedMacroContext {
val prefix = Expr[Nothing](prefixTree)(TypeTag.Nothing)
@@ -403,8 +407,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
val wrappedArgs = mapWithIndex(args)((arg, j) => {
val fingerprint = implParams(min(j, implParams.length - 1))
fingerprint match {
- case LiftedTyped => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752
- case LiftedUntyped => arg
+ case LiftedTyped => context.Expr[Nothing](arg.duplicate)(TypeTag.Nothing) // TODO: SI-5752
+ case LiftedUntyped => arg.duplicate
case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " +
s"corresponding to arg $arg in $argss")
}
@@ -634,7 +638,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
if (isBlackbox(expandee)) {
- val expanded1 = atPos(enclosingMacroPosition.focus)(Typed(expanded0, TypeTree(innerPt)))
+ val expanded1 = atPos(enclosingMacroPosition.makeTransparent)(Typed(expanded0, TypeTree(innerPt)))
typecheck("blackbox typecheck", expanded1, outerPt)
} else {
val expanded1 = expanded0
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 39e259fdfd..86bb99e7fa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1132,7 +1132,7 @@ trait Namers extends MethodSynthesis {
}
}
- addDefaultGetters(meth, vparamss, tparams, overriddenSymbol(methResTp))
+ addDefaultGetters(meth, ddef, vparamss, tparams, overriddenSymbol(methResTp))
// fast track macros, i.e. macros defined inside the compiler, are hardcoded
// hence we make use of that and let them have whatever right-hand side they need
@@ -1174,7 +1174,12 @@ trait Namers extends MethodSynthesis {
* typechecked, the corresponding param would not yet have the "defaultparam"
* flag.
*/
- private def addDefaultGetters(meth: Symbol, vparamss: List[List[ValDef]], tparams: List[TypeDef], overriddenSymbol: => Symbol) {
+ private def addDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef], overriddenSymbol: => Symbol) {
+ val DefDef(_, _, rtparams0, rvparamss0, _, _) = resetLocalAttrs(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)
+ def rvparamss = rvparamss0.map(_.map(_.duplicate))
val methOwner = meth.owner
val isConstr = meth.isConstructor
val overridden = if (isConstr || !methOwner.isClass) NoSymbol else overriddenSymbol
@@ -1206,23 +1211,36 @@ trait Namers extends MethodSynthesis {
//
vparamss.foldLeft(Nil: List[List[ValDef]]) { (previous, vparams) =>
assert(!overrides || vparams.length == baseParamss.head.length, ""+ meth.fullName + ", "+ overridden.fullName)
+ val rvparams = rvparamss(previous.length)
var baseParams = if (overrides) baseParamss.head else Nil
- for (vparam <- vparams) {
+ map2(vparams, rvparams)((vparam, rvparam) => {
val sym = vparam.symbol
// true if the corresponding parameter of the base class has a default argument
val baseHasDefault = overrides && baseParams.head.hasDefault
if (sym.hasDefault) {
- // generate a default getter for that argument
+ // Create a "default getter", i.e. a DefDef that will calculate vparam.rhs
+ // for those who are going to call meth without providing an argument corresponding to vparam.
+ // After the getter is created, a corresponding synthetic symbol is created and entered into the parent namer.
+ //
+ // In the ideal world, this DefDef would be a simple one-liner that just returns vparam.rhs,
+ // but in scalac things are complicated in two different ways.
+ //
+ // 1) Because the underlying language is quite sophisticated, we must allow for those sophistications in our getter.
+ // Namely: a) our getter has to copy type parameters from the associated method (or the associated class
+ // if meth is a constructor), because vparam.rhs might refer to one of them, b) our getter has to copy
+ // preceding value parameter lists from the associated method, because again vparam.rhs might refer to one of them.
+ //
+ // 2) Because we have already assigned symbols to type and value parameters that we have to copy, we must jump through
+ // hoops in order to destroy them and allow subsequent naming create new symbols for our getter. Previously this
+ // was done in an overly brutal way akin to resetAllAttrs, but now we utilize a resetLocalAttrs-based approach.
+ // Still far from ideal, but at least enables things like run/macro-default-params that were previously impossible.
+
val oflag = if (baseHasDefault) OVERRIDE else 0
val name = nme.defaultGetterName(meth.name, posCounter)
- // Create trees for the defaultGetter. Uses tools from Unapplies.scala
- var deftParams = tparams map copyUntyped[TypeDef]
- val defvParamss = mmap(previous) { p =>
- // in the default getter, remove the default parameter
- val p1 = atPos(p.pos.focus) { ValDef(p.mods &~ DEFAULTPARAM, p.name, p.tpt.duplicate, EmptyTree) }
- UnTyper.traverse(p1)
- p1
+ var defTparams = rtparams
+ val defVparamss = mmap(rvparamss.take(previous.length)){ rvp =>
+ copyValDef(rvp)(mods = rvp.mods &~ DEFAULTPARAM, rhs = EmptyTree)
}
val parentNamer = if (isConstr) {
@@ -1244,7 +1262,8 @@ trait Namers extends MethodSynthesis {
return // fix #3649 (prevent crash in erroneous source code)
}
}
- deftParams = cdef.tparams map copyUntypedInvariant
+ val ClassDef(_, _, rtparams, _) = resetLocalAttrs(cdef.duplicate)
+ defTparams = rtparams.map(rt => copyTypeDef(rt)(mods = rt.mods &~ (COVARIANT | CONTRAVARIANT)))
nmr
}
else ownerNamer getOrElse {
@@ -1255,23 +1274,30 @@ trait Namers extends MethodSynthesis {
nmr
}
- // If the parameter type mentions any type parameter of the method, let the compiler infer the
- // return type of the default getter => allow "def foo[T](x: T = 1)" to compile.
- // This is better than always using Wildcard for inferring the result type, for example in
- // def f(i: Int, m: Int => Int = identity _) = m(i)
- // if we use Wildcard as expected, we get "Nothing => Nothing", and the default is not usable.
- val names = deftParams map { case TypeDef(_, name, _, _) => name }
- val subst = new TypeTreeSubstituter(names contains _)
-
- val defTpt = subst(copyUntyped(vparam.tpt match {
- // default getter for by-name params
- case AppliedTypeTree(_, List(arg)) if sym.hasFlag(BYNAMEPARAM) => arg
- case t => t
- }))
- val defRhs = copyUntyped(vparam.rhs)
+ val defTpt =
+ // don't mess with tpt's of case copy default getters, because assigning something other than TypeTree()
+ // will break the carefully orchestrated naming/typing logic that involves enterCopyMethod and caseClassCopyMeth
+ if (meth.isCaseCopy) TypeTree()
+ else {
+ // If the parameter type mentions any type parameter of the method, let the compiler infer the
+ // return type of the default getter => allow "def foo[T](x: T = 1)" to compile.
+ // This is better than always using Wildcard for inferring the result type, for example in
+ // def f(i: Int, m: Int => Int = identity _) = m(i)
+ // if we use Wildcard as expected, we get "Nothing => Nothing", and the default is not usable.
+ // TODO: this is a very brittle approach; I sincerely hope that Denys's research into hygiene
+ // will open the doors to a much better way of doing this kind of stuff
+ val tparamNames = defTparams map { case TypeDef(_, name, _, _) => name }
+ val eraseAllMentionsOfTparams = new TypeTreeSubstituter(tparamNames contains _)
+ eraseAllMentionsOfTparams(rvparam.tpt match {
+ // default getter for by-name params
+ case AppliedTypeTree(_, List(arg)) if sym.hasFlag(BYNAMEPARAM) => arg
+ case t => t
+ })
+ }
+ val defRhs = rvparam.rhs
val defaultTree = atPos(vparam.pos.focus) {
- DefDef(Modifiers(paramFlagsToDefaultGetter(meth.flags)) | oflag, name, deftParams, defvParamss, defTpt, defRhs)
+ DefDef(Modifiers(paramFlagsToDefaultGetter(meth.flags)) | oflag, name, defTparams, defVparamss, defTpt, defRhs)
}
if (!isConstr)
methOwner.resetFlag(INTERFACE) // there's a concrete member now
@@ -1286,7 +1312,7 @@ trait Namers extends MethodSynthesis {
}
posCounter += 1
if (overrides) baseParams = baseParams.tail
- }
+ })
if (overrides) baseParamss = baseParamss.tail
previous :+ vparams
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index ec916719dc..95f2620061 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -954,162 +954,166 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case Object_eq | Object_ne | Object_== | Object_!= | Any_== | Any_!= => true
case _ => false
}
- def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match {
- case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) =>
- // Make sure the 'eq' or 'ne' method is the one in AnyRef.
- def isReferenceOp = fn.symbol == Object_eq || fn.symbol == Object_ne
- def isNew(tree: Tree) = tree match {
- case Function(_, _)
- | Apply(Select(New(_), nme.CONSTRUCTOR), _) => true
- case _ => false
- }
- def underlyingClass(tp: Type): Symbol = {
- val sym = tp.widen.typeSymbol
- if (sym.isAbstractType) underlyingClass(sym.info.bounds.hi)
- else sym
- }
- val actual = underlyingClass(args.head.tpe)
- val receiver = underlyingClass(qual.tpe)
- def onTrees[T](f: List[Tree] => T) = f(List(qual, args.head))
- def onSyms[T](f: List[Symbol] => T) = f(List(receiver, actual))
-
- // @MAT normalize for consistency in error message, otherwise only part is normalized due to use of `typeSymbol`
- def typesString = normalizeAll(qual.tpe.widen)+" and "+normalizeAll(args.head.tpe.widen)
-
- /* Symbols which limit the warnings we can issue since they may be value types */
- val isMaybeValue = Set[Symbol](AnyClass, AnyRefClass, AnyValClass, ObjectClass, ComparableClass, JavaSerializableClass)
-
- // Whether def equals(other: Any) has known behavior: it is the default
- // inherited from java.lang.Object, or it is a synthetically generated
- // case equals. TODO - more cases are warnable if the target is a synthetic
- // equals.
- def isUsingWarnableEquals = {
- val m = receiver.info.member(nme.equals_)
- ((m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m))
- }
- def isMethodCaseEquals(m: Symbol) = m.isSynthetic && m.owner.isCase
- def isCaseEquals = isMethodCaseEquals(receiver.info.member(nme.equals_))
- // Whether this == or != is one of those defined in Any/AnyRef or an overload from elsewhere.
- def isUsingDefaultScalaOp = {
- val s = fn.symbol
- (s == Object_==) || (s == Object_!=) || (s == Any_==) || (s == Any_!=)
- }
- def haveSubclassRelationship = (actual isSubClass receiver) || (receiver isSubClass actual)
-
- // Whether the operands+operator represent a warnable combo (assuming anyrefs)
- // Looking for comparisons performed with ==/!= in combination with either an
- // equals method inherited from Object or a case class synthetic equals (for
- // which we know the logic.)
- def isWarnable = isReferenceOp || (isUsingDefaultScalaOp && isUsingWarnableEquals)
- def isEitherNullable = (NullTpe <:< receiver.info) || (NullTpe <:< actual.info)
- def isEitherValueClass = actual.isDerivedValueClass || receiver.isDerivedValueClass
- def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass
- def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass
- def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || isAnyNumber(s)
- def isScalaNumber(s: Symbol) = s isSubClass ScalaNumberClass
- def isJavaNumber(s: Symbol) = s isSubClass JavaNumberClass
- // includes java.lang.Number if appropriate [SI-5779]
- def isAnyNumber(s: Symbol) = isScalaNumber(s) || isJavaNumber(s)
- def isMaybeAnyValue(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || isMaybeValue(s)
- // used to short-circuit unrelatedTypes check if both sides are special
- def isSpecial(s: Symbol) = isMaybeAnyValue(s) || isAnyNumber(s)
- val nullCount = onSyms(_ filter (_ == NullClass) size)
- def isNonsenseValueClassCompare = (
- !haveSubclassRelationship
- && isUsingDefaultScalaOp
- && isEitherValueClass
- && !isCaseEquals
- )
+ /** Check the sensibility of using the given `equals` to compare `qual` and `other`. */
+ private def checkSensibleEquals(pos: Position, qual: Tree, name: Name, sym: Symbol, other: Tree) = {
+ def isReferenceOp = sym == Object_eq || sym == Object_ne
+ def isNew(tree: Tree) = tree match {
+ case Function(_, _) | Apply(Select(New(_), nme.CONSTRUCTOR), _) => true
+ case _ => false
+ }
+ def underlyingClass(tp: Type): Symbol = {
+ val sym = tp.widen.typeSymbol
+ if (sym.isAbstractType) underlyingClass(sym.info.bounds.hi)
+ else sym
+ }
+ val actual = underlyingClass(other.tpe)
+ val receiver = underlyingClass(qual.tpe)
+ def onTrees[T](f: List[Tree] => T) = f(List(qual, other))
+ def onSyms[T](f: List[Symbol] => T) = f(List(receiver, actual))
+
+ // @MAT normalize for consistency in error message, otherwise only part is normalized due to use of `typeSymbol`
+ def typesString = normalizeAll(qual.tpe.widen)+" and "+normalizeAll(other.tpe.widen)
+
+ /* Symbols which limit the warnings we can issue since they may be value types */
+ val isMaybeValue = Set[Symbol](AnyClass, AnyRefClass, AnyValClass, ObjectClass, ComparableClass, JavaSerializableClass)
+
+ // Whether def equals(other: Any) has known behavior: it is the default
+ // inherited from java.lang.Object, or it is a synthetically generated
+ // case equals. TODO - more cases are warnable if the target is a synthetic
+ // equals.
+ def isUsingWarnableEquals = {
+ val m = receiver.info.member(nme.equals_)
+ ((m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m))
+ }
+ def isMethodCaseEquals(m: Symbol) = m.isSynthetic && m.owner.isCase
+ def isCaseEquals = isMethodCaseEquals(receiver.info.member(nme.equals_))
+ // Whether this == or != is one of those defined in Any/AnyRef or an overload from elsewhere.
+ def isUsingDefaultScalaOp = sym == Object_== || sym == Object_!= || sym == Any_== || sym == Any_!=
+ def haveSubclassRelationship = (actual isSubClass receiver) || (receiver isSubClass actual)
+
+ // Whether the operands+operator represent a warnable combo (assuming anyrefs)
+ // Looking for comparisons performed with ==/!= in combination with either an
+ // equals method inherited from Object or a case class synthetic equals (for
+ // which we know the logic.)
+ def isWarnable = isReferenceOp || (isUsingDefaultScalaOp && isUsingWarnableEquals)
+ def isEitherNullable = (NullTpe <:< receiver.info) || (NullTpe <:< actual.info)
+ def isEitherValueClass = actual.isDerivedValueClass || receiver.isDerivedValueClass
+ def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass
+ def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass
+ def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || isAnyNumber(s)
+ def isScalaNumber(s: Symbol) = s isSubClass ScalaNumberClass
+ def isJavaNumber(s: Symbol) = s isSubClass JavaNumberClass
+ // includes java.lang.Number if appropriate [SI-5779]
+ def isAnyNumber(s: Symbol) = isScalaNumber(s) || isJavaNumber(s)
+ def isMaybeAnyValue(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || isMaybeValue(s)
+ // used to short-circuit unrelatedTypes check if both sides are special
+ def isSpecial(s: Symbol) = isMaybeAnyValue(s) || isAnyNumber(s)
+ val nullCount = onSyms(_ filter (_ == NullClass) size)
+ def isNonsenseValueClassCompare = (
+ !haveSubclassRelationship
+ && isUsingDefaultScalaOp
+ && isEitherValueClass
+ && !isCaseEquals
+ )
- def nonSensibleWarning(what: String, alwaysEqual: Boolean) = {
- val msg = alwaysEqual == (name == nme.EQ || name == nme.eq)
- unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield " + msg)
- }
- def nonSensible(pre: String, alwaysEqual: Boolean) =
- nonSensibleWarning(pre+"values of types "+typesString, alwaysEqual)
- def nonSensiblyEq() = nonSensible("", true)
- def nonSensiblyNeq() = nonSensible("", false)
- def nonSensiblyNew() = nonSensibleWarning("a fresh object", false)
-
- def unrelatedMsg = name match {
- case nme.EQ | nme.eq => "never compare equal"
- case _ => "always compare unequal"
- }
- def unrelatedTypes() = {
- val weaselWord = if (isEitherValueClass) "" else " most likely"
- unit.warning(pos, s"$typesString are unrelated: they will$weaselWord $unrelatedMsg")
- }
+ // Have we already determined that the comparison is non-sensible? I mean, non-sensical?
+ var isNonSensible = false
+
+ def nonSensibleWarning(what: String, alwaysEqual: Boolean) = {
+ val msg = alwaysEqual == (name == nme.EQ || name == nme.eq)
+ unit.warning(pos, s"comparing $what using `${name.decode}' will always yield $msg")
+ isNonSensible = true
+ }
+ def nonSensible(pre: String, alwaysEqual: Boolean) =
+ nonSensibleWarning(s"${pre}values of types $typesString", alwaysEqual)
+ def nonSensiblyEq() = nonSensible("", alwaysEqual = true)
+ def nonSensiblyNeq() = nonSensible("", alwaysEqual = false)
+ def nonSensiblyNew() = nonSensibleWarning("a fresh object", alwaysEqual = false)
+
+ def unrelatedMsg = name match {
+ case nme.EQ | nme.eq => "never compare equal"
+ case _ => "always compare unequal"
+ }
+ def unrelatedTypes() = if (!isNonSensible) {
+ val weaselWord = if (isEitherValueClass) "" else " most likely"
+ unit.warning(pos, s"$typesString are unrelated: they will$weaselWord $unrelatedMsg")
+ }
- if (nullCount == 2) // null == null
+ if (nullCount == 2) // null == null
+ nonSensiblyEq()
+ else if (nullCount == 1) {
+ if (onSyms(_ exists isPrimitiveValueClass)) // null == 5
+ nonSensiblyNeq()
+ else if (onTrees( _ exists isNew)) // null == new AnyRef
+ nonSensiblyNew()
+ }
+ else if (isBoolean(receiver)) {
+ if (!isBoolean(actual) && !isMaybeValue(actual)) // true == 5
+ nonSensiblyNeq()
+ }
+ else if (isUnit(receiver)) {
+ if (isUnit(actual)) // () == ()
nonSensiblyEq()
- else if (nullCount == 1) {
- if (onSyms(_ exists isPrimitiveValueClass)) // null == 5
- nonSensiblyNeq()
- else if (onTrees( _ exists isNew)) // null == new AnyRef
- nonSensiblyNew()
- }
- else if (isBoolean(receiver)) {
- if (!isBoolean(actual) && !isMaybeValue(actual)) // true == 5
+ else if (!isUnit(actual) && !isMaybeValue(actual)) // () == "abc"
+ nonSensiblyNeq()
+ }
+ else if (isNumeric(receiver)) {
+ if (!isNumeric(actual))
+ if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc"
nonSensiblyNeq()
- }
- else if (isUnit(receiver)) {
- if (isUnit(actual)) // () == ()
- nonSensiblyEq()
- else if (!isUnit(actual) && !isMaybeValue(actual)) // () == "abc"
+ }
+ else if (isWarnable && !isCaseEquals) {
+ if (isNew(qual)) // new X == y
+ nonSensiblyNew()
+ else if (isNew(other) && (receiver.isEffectivelyFinal || isReferenceOp)) // object X ; X == new Y
+ nonSensiblyNew()
+ else if (receiver.isEffectivelyFinal && !(receiver isSubClass actual) && !actual.isRefinementClass) { // object X, Y; X == Y
+ if (isEitherNullable)
+ nonSensible("non-null ", false)
+ else
nonSensiblyNeq()
}
- else if (isNumeric(receiver)) {
- if (!isNumeric(actual))
- if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc"
- nonSensiblyNeq()
+ }
+
+ // warn if one but not the other is a derived value class
+ // this is especially important to enable transitioning from
+ // regular to value classes without silent failures.
+ if (isNonsenseValueClassCompare)
+ unrelatedTypes()
+ // possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean
+ else if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) {
+ // better to have lubbed and lost
+ def warnIfLubless(): Unit = {
+ val common = global.lub(List(actual.tpe, receiver.tpe))
+ if (ObjectTpe <:< common)
+ unrelatedTypes()
}
- else if (isWarnable && !isCaseEquals) {
- if (isNew(qual)) // new X == y
- nonSensiblyNew()
- else if (isNew(args.head) && (receiver.isEffectivelyFinal || isReferenceOp)) // object X ; X == new Y
- nonSensiblyNew()
- else if (receiver.isEffectivelyFinal && !(receiver isSubClass actual) && !actual.isRefinementClass) { // object X, Y; X == Y
- if (isEitherNullable)
- nonSensible("non-null ", false)
- else
- nonSensiblyNeq()
+ // warn if actual has a case parent that is not same as receiver's;
+ // if actual is not a case, then warn if no common supertype, as below
+ if (isCaseEquals) {
+ def thisCase = receiver.info.member(nme.equals_).owner
+ actual.info.baseClasses.find(_.isCase) match {
+ case Some(p) if p != thisCase => nonSensible("case class ", false)
+ case None =>
+ // stronger message on (Some(1) == None)
+ //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq()
+ //else
+ // if a class, it must be super to thisCase (and receiver) since not <: thisCase
+ if (!actual.isTrait && !(receiver isSubClass actual)) nonSensiblyNeq()
+ else if (!haveSubclassRelationship) warnIfLubless()
+ case _ =>
}
}
-
- // warn if one but not the other is a derived value class
- // this is especially important to enable transitioning from
- // regular to value classes without silent failures.
- if (isNonsenseValueClassCompare)
- unrelatedTypes()
- // possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean
- else if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) {
- // better to have lubbed and lost
- def warnIfLubless(): Unit = {
- val common = global.lub(List(actual.tpe, receiver.tpe))
- if (ObjectTpe <:< common)
- unrelatedTypes()
- }
- // warn if actual has a case parent that is not same as receiver's;
- // if actual is not a case, then warn if no common supertype, as below
- if (isCaseEquals) {
- def thisCase = receiver.info.member(nme.equals_).owner
- actual.info.baseClasses.find(_.isCase) match {
- case Some(p) if p != thisCase => nonSensible("case class ", false)
- case None =>
- // stronger message on (Some(1) == None)
- //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq()
- //else
- // if a class, it must be super to thisCase (and receiver) since not <: thisCase
- if (!actual.isTrait && !(receiver isSubClass actual)) nonSensiblyNeq()
- else if (!haveSubclassRelationship) warnIfLubless()
- case _ =>
- }
- }
- // warn only if they have no common supertype below Object
- else if (!haveSubclassRelationship) {
- warnIfLubless()
- }
+ // warn only if they have no common supertype below Object
+ else if (!haveSubclassRelationship) {
+ warnIfLubless()
}
+ }
+ }
+ /** Sensibility check examines flavors of equals. */
+ def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match {
+ case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) =>
+ checkSensibleEquals(pos, qual, name, fn.symbol, args.head)
case _ =>
}
@@ -1526,7 +1530,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
transform(qual)
case Apply(fn, args) =>
- // sensicality should be subsumed by the unreachability/exhaustivity/irrefutability analyses in the pattern matcher
+ // sensicality should be subsumed by the unreachability/exhaustivity/irrefutability
+ // analyses in the pattern matcher
if (!inPattern) {
checkImplicitViewOptionApply(tree.pos, fn, args)
checkSensible(tree.pos, fn, args)
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 54c665fe56..14f47a00fd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -50,6 +50,10 @@ trait StdAttachments {
case _ => false
}
+ /** Returns the original tree of the macro expansion if the argument is a macro expansion or EmptyTree otherwise.
+ */
+ def macroExpandee(tree: Tree): Tree = tree.attachments.get[MacroExpansionAttachment].map(_.expandee).getOrElse(EmptyTree)
+
/** After macro expansion is completed, links the expandee and the expansion result by annotating them both with a `MacroExpansionAttachment`.
* The `expanded` parameter is of type `Any`, because macros can expand both into trees and into annotations.
*/
@@ -147,4 +151,18 @@ trait StdAttachments {
* because someone has put MacroImplRefAttachment on it.
*/
def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined
+
+ /** Since mkInvoke, the applyDynamic/selectDynamic/etc desugarer, is disconnected
+ * from typedNamedApply, the applyDynamicNamed argument rewriter, the latter
+ * doesn’t know whether it needs to apply the rewriting because the application
+ * has just been desugared or it needs to hold on because it’s already performed
+ * a desugaring on this tree. This has led to SI-8006.
+ *
+ * This attachment solves the problem by providing a means of communication
+ * between the two Dynamic desugarers, which solves the aforementioned issue.
+ */
+ case object DynamicRewriteAttachment
+ def markDynamicRewrite(tree: Tree): Tree = tree.updateAttachment(DynamicRewriteAttachment)
+ def unmarkDynamicRewrite(tree: Tree): Tree = tree.removeAttachment[DynamicRewriteAttachment.type]
+ def isDynamicRewrite(tree: Tree): Boolean = tree.attachments.get[DynamicRewriteAttachment.type].isDefined
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5e89440bc0..dbe85f4f5a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -56,16 +56,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
resetDocComments()
}
- object UnTyper extends Traverser {
- override def traverse(tree: Tree) = {
- if (tree.canHaveAttrs) {
- tree.clearType()
- if (tree.hasSymbolField) tree.symbol = NoSymbol
- }
- super.traverse(tree)
- }
- }
-
sealed abstract class SilentResult[+T] {
@inline final def fold[U](none: => U)(f: T => U): U = this match {
case SilentResultValue(value) => f(value)
@@ -3369,7 +3359,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
(args exists isNamedArg) || // uses a named argument
isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
// integrate this application into the block
- if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
+ if (dyna.isApplyDynamicNamed(fun) && isDynamicRewrite(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
else tryNamesDefaults
} else {
val tparams = context.extractUndetparams()
@@ -3927,7 +3917,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
gen.mkTuple(List(CODE.LIT(""), arg))
}
- val t = treeCopy.Apply(orig, fun, args map argToBinding)
+ val t = treeCopy.Apply(orig, unmarkDynamicRewrite(fun), args map argToBinding)
wrapErrors(t, _.typed(t, mode, pt))
}
@@ -3953,9 +3943,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
debuglog(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)")
val treeInfo.Applied(treeSelection, _, _) = tree
- def isDesugaredApply = treeSelection match {
- case Select(`qual`, nme.apply) => true
- case _ => false
+ def isDesugaredApply = {
+ val protoQual = macroExpandee(qual) orElse qual
+ treeSelection match {
+ case Select(`protoQual`, nme.apply) => true
+ case _ => false
+ }
}
acceptsApplyDynamicWithType(qual, name) map { tp =>
// If tp == NoType, pass only explicit type arguments to applyXXX. Not used at all
@@ -3989,7 +3982,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val nameStringLit = atPos(treeSelection.pos.withStart(treeSelection.pos.point).makeTransparent) {
Literal(Constant(name.decode))
}
- atPos(qual.pos)(Apply(fun, List(nameStringLit)))
+ markDynamicRewrite(atPos(qual.pos)(Apply(fun, List(nameStringLit))))
case _ =>
setError(tree)
}
@@ -4247,7 +4240,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
val ids = for (p <- params) yield Ident(p.name)
val selector1 = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) }
- val body = treeCopy.Match(tree, selector1, cases)
+ // SI-8120 If we don't duplicate the cases, the original Match node will share trees with ones that
+ // receive symbols owned by this function. However if, after a silent mode session, we discard
+ // this Function and try a different approach (e.g. applying a view to the reciever) we end up
+ // with orphaned symbols which blows up far down the pipeline (or can be detected with -Ycheck:typer).
+ val body = treeCopy.Match(tree, selector1, (cases map duplicateAndKeepPositions).asInstanceOf[List[CaseDef]])
typed1(atPos(tree.pos) { Function(params, body) }, mode, pt)
}
} else
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index ed96f66ab8..ffac29b4b8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -43,12 +43,6 @@ trait Unapplies extends ast.TreeDSL {
def unapply(tp: Type): Option[Symbol] = unapplyMember(tp).toOption
}
- def copyUntyped[T <: Tree](tree: T): T =
- returning[T](tree.duplicate)(UnTyper traverse _)
-
- def copyUntypedInvariant(td: TypeDef): TypeDef =
- copyTypeDef(copyUntyped(td))(mods = td.mods &~ (COVARIANT | CONTRAVARIANT))
-
private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
@@ -58,8 +52,15 @@ trait Unapplies extends ast.TreeDSL {
}
private def constrParamss(cdef: ClassDef): List[List[ValDef]] = {
- val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor cdef.impl.body
- mmap(vparamss)(copyUntyped[ValDef])
+ val ClassDef(_, _, _, Template(_, _, body)) = resetLocalAttrs(cdef.duplicate)
+ val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor body
+ vparamss
+ }
+
+ private def constrTparamsInvariant(cdef: ClassDef): List[TypeDef] = {
+ val ClassDef(_, _, tparams, _) = resetLocalAttrs(cdef.duplicate)
+ val tparamsInvariant = tparams.map(tparam => copyTypeDef(tparam)(mods = tparam.mods &~ (COVARIANT | CONTRAVARIANT)))
+ tparamsInvariant
}
/** The return value of an unapply method of a case class C[Ts]
@@ -125,7 +126,7 @@ trait Unapplies extends ast.TreeDSL {
/** The apply method corresponding to a case class
*/
def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef): DefDef = {
- val tparams = cdef.tparams map copyUntypedInvariant
+ val tparams = constrTparamsInvariant(cdef)
val cparamss = constrParamss(cdef)
def classtpe = classType(cdef, tparams)
atPos(cdef.pos.focus)(
@@ -141,7 +142,7 @@ trait Unapplies extends ast.TreeDSL {
/** The unapply method corresponding to a case class
*/
def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = {
- val tparams = cdef.tparams map copyUntypedInvariant
+ val tparams = constrTparamsInvariant(cdef)
val method = constrParamss(cdef) match {
case xs :: _ if xs.nonEmpty && isRepeatedParamType(xs.last.tpt) => nme.unapplySeq
case _ => nme.unapply
@@ -196,7 +197,7 @@ trait Unapplies extends ast.TreeDSL {
treeCopy.ValDef(vd, Modifiers(flags), vd.name, tpt, rhs)
}
- val tparams = cdef.tparams map copyUntypedInvariant
+ val tparams = constrTparamsInvariant(cdef)
val paramss = classParamss match {
case Nil => Nil
case ps :: pss =>
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index dd92e14602..bb0bbd79a3 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -24,10 +24,12 @@ trait FastTrack {
new { val c: c0.type = c0 } with MacroImplementations
private implicit def context2quasiquote(c0: MacroContext): QuasiquoteImpls { val c: c0.type } =
new { val c: c0.type = c0 } with QuasiquoteImpls
- private def make(sym: Symbol)(pf: PartialFunction[Applied, MacroContext => Tree]) =
- sym -> new FastTrackEntry(pf)
+ private def makeBlackbox(sym: Symbol)(pf: PartialFunction[Applied, MacroContext => Tree]) =
+ sym -> new FastTrackEntry(pf, isBlackbox = true)
+ private def makeWhitebox(sym: Symbol)(pf: PartialFunction[Applied, MacroContext => Tree]) =
+ sym -> new FastTrackEntry(pf, isBlackbox = false)
- final class FastTrackEntry(pf: PartialFunction[Applied, MacroContext => Tree]) extends (MacroArgs => Any) {
+ final class FastTrackEntry(pf: PartialFunction[Applied, MacroContext => Tree], val isBlackbox: Boolean) extends (MacroArgs => Any) {
def validate(tree: Tree) = pf isDefinedAt Applied(tree)
def apply(margs: MacroArgs): margs.c.Expr[Nothing] = {
val MacroArgs(c, _) = margs
@@ -42,14 +44,14 @@ trait FastTrack {
val runDefinitions = currentRun.runDefinitions
import runDefinitions._
Map[Symbol, FastTrackEntry](
- make( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) },
- make( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) },
- make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) },
- make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) },
- make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) },
- make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree },
- make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote },
- make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote }
+ makeBlackbox( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) },
+ makeBlackbox( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) },
+ makeBlackbox( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) },
+ makeBlackbox( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) },
+ makeBlackbox( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) },
+ makeBlackbox(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree },
+ makeWhitebox( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote },
+ makeWhitebox(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote }
)
}
}
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index be22003114..236b868842 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -21,6 +21,12 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*/
def frontEnd: FrontEnd
+ /** @see `Typers.typecheck`
+ */
+ @deprecated("Use `tb.typecheck` instead", "2.11.0")
+ def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree =
+ typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
+
/** Typechecks a tree using this ToolBox.
* This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings.
*
@@ -35,7 +41,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* `withImplicitViewsDisabled` recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false
* `withMacrosDisabled` recursively prohibits macro expansions and macro-based implicits, default value is false
*/
- def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree
+ def typecheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree
/** Infers an implicit value of the expected type `pt` in top-level context.
* Optional `pos` parameter provides a position that will be associated with the implicit search.
@@ -47,7 +53,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* If `silent` is false, `TypeError` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
- * Unlike in `typeCheck`, `silent` is true by default.
+ * Unlike in `typecheck`, `silent` is true by default.
*/
def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree
@@ -61,7 +67,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* If `silent` is false, `TypeError` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
- * Unlike in `typeCheck`, `silent` is true by default.
+ * Unlike in `typecheck`, `silent` is true by default.
*/
def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index e94b7725cd..af13b7d0ba 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -171,7 +171,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
unwrapped
}
- def typeCheck(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree =
+ def typecheck(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree =
transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, expr) => {
trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
@@ -348,7 +348,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
}
- def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi =>
+ def typecheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi =>
import compilerApi._
if (compiler.settings.verbose) println("importing "+tree+", expectedType = "+expectedType)
@@ -356,7 +356,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val cexpectedType: compiler.Type = importer.importType(expectedType)
if (compiler.settings.verbose) println("typing "+ctree+", expectedType = "+expectedType)
- val ttree: compiler.Tree = compiler.typeCheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
+ val ttree: compiler.Tree = compiler.typecheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
val uttree = exporter.importTree(ttree)
uttree
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 6d7aafe266..87ab52414c 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -32,8 +32,16 @@ trait Reifiers { self: Quasiquotes =>
var nameMap = collection.mutable.HashMap.empty[Name, Set[TermName]].withDefault { _ => Set() }
/** Wraps expressions into:
- * a sequence of nested withFreshTermName/withFreshTypeName calls which are required
- * to force regeneration of randomly generated names on every evaluation of quasiquote.
+ * a block which starts with a sequence of vals that correspond
+ * to fresh names that has to be created at evaluation of the quasiquote
+ * and ends with reified tree:
+ *
+ * {
+ * val name$1: universe.TermName = universe.build.freshTermName(prefix1)
+ * ...
+ * val name$N: universe.TermName = universe.build.freshTermName(prefixN)
+ * tree
+ * }
*
* Wraps patterns into:
* a call into anonymous class' unapply method required by unapply macro expansion:
@@ -50,15 +58,18 @@ trait Reifiers { self: Quasiquotes =>
*/
def wrap(tree: Tree) =
if (isReifyingExpressions) {
- nameMap.foldLeft(tree) {
- case (t, (origname, names)) =>
+ val freshdefs = nameMap.iterator.map {
+ case (origname, names) =>
assert(names.size == 1)
val FreshName(prefix) = origname
- val ctor = TermName("withFresh" + (if (origname.isTermName) "TermName" else "TypeName"))
- // q"$u.build.$ctor($prefix) { ${names.head} => $t }"
- Apply(Apply(Select(Select(u, nme.build), ctor), List(Literal(Constant(prefix)))),
- List(Function(List(ValDef(Modifiers(PARAM), names.head, TypeTree(), EmptyTree)), t)))
- }
+ val nameTypeName = if (origname.isTermName) tpnme.TermName else tpnme.TypeName
+ val freshName = if (origname.isTermName) nme.freshTermName else nme.freshTypeName
+ // q"val ${names.head}: $u.$nameTypeName = $u.build.$freshName($prefix)"
+ ValDef(NoMods, names.head, Select(u, nameTypeName),
+ Apply(Select(Select(u, nme.build), freshName), Literal(Constant(prefix)) :: Nil))
+ }.toList
+ // q"..$freshdefs; $tree"
+ SyntacticBlock(freshdefs :+ tree)
} else {
val freevars = holeMap.toList.map { case (name, _) => Ident(name) }
val isVarPattern = tree match { case Bind(name, Ident(nme.WILDCARD)) => true case _ => false }
diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
index 498bdc5943..6658b6feea 100644
--- a/src/library/scala/collection/convert/DecorateAsJava.scala
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -287,7 +287,7 @@ trait DecorateAsJava {
* will be visible via the Scala interface and vice versa.
*
* If the Scala `concurrent.Map` was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * explicit call of `asConcurrentMap(java.util.concurrent.ConcurrentMap)`
* then the original Java `ConcurrentMap` will be returned.
*
* @param m The Scala `concurrent.Map` to be converted.
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index b6ebf2ff06..9916fe9843 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -244,7 +244,7 @@ trait WrapAsJava {
* will be visible via the Scala interface and vice versa.
*
* If the Scala `concurrent.Map` was previously obtained from an implicit or
- * explicit call of `mapAsScalaConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * explicit call of `mapAsScalaConcurrentMap(java.util.concurrent.ConcurrentMap)`
* then the original Java ConcurrentMap will be returned.
*
* @param m The Scala `concurrent.Map` to be converted.
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala
index c3a6351336..fb0a34e64d 100644
--- a/src/library/scala/collection/immutable/HashMap.scala
+++ b/src/library/scala/collection/immutable/HashMap.scala
@@ -180,21 +180,6 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
override def get0(key: A, hash: Int, level: Int): Option[B] =
if (hash == this.hash && key == this.key) Some(value) else None
- // override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1)): HashMap[A, B1] =
- // if (hash == this.hash && key == this.key) new HashMap1(key, hash, value, kv)
- // else {
- // var thatindex = (hash >>> level) & 0x1f
- // var thisindex = (this.hash >>> level) & 0x1f
- // if (hash != this.hash) {
- // --new HashTrieMap[A,B1](level+5, this, new HashMap1(key, hash, value, kv))
- // val m = new HashTrieMap[A,B1](0,new Array[HashMap[A,B1]](0),0) // TODO: could save array alloc
- // m.updated0(this.key, this.hash, level, this.value, this.kv).updated0(key, hash, level, value, kv) TODO and it will
- // } else {
- // 32-bit hash collision (rare, but not impossible)
- // new HashMapCollision1(hash, ListMap.empty.updated(this.key,this.value).updated(key,value))
- // }
- // }
-
private[collection] override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[A, B1]): HashMap[A, B1] =
if (hash == this.hash && key == this.key ) {
if (merger eq null) {
@@ -283,24 +268,6 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
// assert(Integer.bitCount(bitmap) == elems.length)
// assert(elems.length > 1 || (elems.length == 1 && elems(0).isInstanceOf[HashTrieMap[_,_]]))
-/*
- def this (level: Int, m1: HashMap1[A,B], m2: HashMap1[A,B]) = {
- this(((m1.hash >>> level) & 0x1f) | ((m2.hash >>> level) & 0x1f), {
- val idx1 = (m1.hash >>> level) & 0x1f
- val idx2 = (m2.hash >>> level) & 0x1f
- assert(idx1 != idx2, m1.hash + "==" + m2.hash + " at level " + level) // TODO
- val elems = new Array[HashMap[A,B]](2)
- if (idx1 < idx2) {
- elems(0) = m1
- elems(1) = m2
- } else {
- elems(0) = m2
- elems(1) = m1
- }
- elems
- }, 2)
- }
-*/
override def size = size0
override def get0(key: A, hash: Int, level: Int): Option[B] = {
@@ -379,24 +346,6 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
final override def getElem(cc: AnyRef): (A, B) = cc.asInstanceOf[HashMap1[A, B]].ensurePair
}
-/*
-def time(block: =>Unit) = { val t0 = System.nanoTime; block; println("elapsed: " + (System.nanoTime - t0)/1000000.0) }
-var mOld = OldHashMap.empty[Int,Int]
-var mNew = HashMap.empty[Int,Int]
-time { for (i <- 0 until 100000) mOld = mOld.updated(i,i) }
-time { for (i <- 0 until 100000) mOld = mOld.updated(i,i) }
-time { for (i <- 0 until 100000) mOld = mOld.updated(i,i) }
-time { for (i <- 0 until 100000) mNew = mNew.updated(i,i) }
-time { for (i <- 0 until 100000) mNew = mNew.updated(i,i) }
-time { for (i <- 0 until 100000) mNew = mNew.updated(i,i) }
-time { mOld.iterator.foreach( p => ()) }
-time { mOld.iterator.foreach( p => ()) }
-time { mOld.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-*/
-
override def foreach[U](f: ((A, B)) => U): Unit = {
var i = 0
while (i < elems.length) {
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index 0546c54826..9eaceccd9f 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -282,28 +282,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override def iterator = new TrieIterator[A](elems.asInstanceOf[Array[Iterable[A]]]) {
final override def getElem(cc: AnyRef): A = cc.asInstanceOf[HashSet1[A]].key
}
-/*
-
-def time(block: =>Unit) = { val t0 = System.nanoTime; block; println("elapsed: " + (System.nanoTime - t0)/1000000.0) }
-var mOld = OldHashSet.empty[Int]
-var mNew = HashSet.empty[Int]
-time { for (i <- 0 until 100000) mOld = mOld + i }
-time { for (i <- 0 until 100000) mOld = mOld + i }
-time { for (i <- 0 until 100000) mOld = mOld + i }
-time { for (i <- 0 until 100000) mNew = mNew + i }
-time { for (i <- 0 until 100000) mNew = mNew + i }
-time { for (i <- 0 until 100000) mNew = mNew + i }
-time { mOld.iterator.foreach( p => ()) }
-time { mOld.iterator.foreach( p => ()) }
-time { mOld.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-time { mNew.iterator.foreach( p => ()) }
-
-*/
+
override def foreach[U](f: A => U): Unit = {
var i = 0
- while (i < elems.length) {
+ while (i < elems.length) {
elems(i).foreach(f)
i += 1
}
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 5e1de44749..a82e31f5da 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -955,7 +955,7 @@ self =>
* `Stream`.
* @example {{{
* val sov: Stream[Vector[Int]] = Vector(0) #:: Vector(0, 0) #:: sov.zip(sov.tail).map { n => n._1 ++ n._2 }
- * sov flatten take 10 mkString ", "
+ * sov.flatten take 10 mkString ", "
* // produces: "0, 0, 0, 0, 0, 0, 0, 0, 0, 0"
* }}}
*/
diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala
index 4a12f9588c..c3047522e2 100644
--- a/src/library/scala/collection/mutable/ResizableArray.scala
+++ b/src/library/scala/collection/mutable/ResizableArray.scala
@@ -89,16 +89,20 @@ trait ResizableArray[A] extends IndexedSeq[A]
}
}
- /** Ensure that the internal array has at `n` cells. */
+ /** Ensure that the internal array has at least `n` cells. */
protected def ensureSize(n: Int) {
- if (n > array.length) {
- var newsize = array.length * 2
- while (n > newsize)
- newsize = newsize * 2
-
- val newar: Array[AnyRef] = new Array(newsize)
- scala.compat.Platform.arraycopy(array, 0, newar, 0, size0)
- array = newar
+ // Use a Long to prevent overflows
+ val arrayLength: Long = array.length
+ if (n > arrayLength) {
+ var newSize: Long = arrayLength * 2
+ while (n > newSize)
+ newSize = newSize * 2
+ // Clamp newSize to Int.MaxValue
+ if (newSize > Int.MaxValue) newSize = Int.MaxValue
+
+ val newArray: Array[AnyRef] = new Array(newSize.toInt)
+ scala.compat.Platform.arraycopy(array, 0, newArray, 0, size0)
+ array = newArray
}
}
diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala
index e6644c0dfc..eafbf96993 100644
--- a/src/library/scala/math/Numeric.scala
+++ b/src/library/scala/math/Numeric.scala
@@ -127,6 +127,8 @@ object Numeric {
def toLong(x: Float): Long = x.toLong
def toFloat(x: Float): Float = x
def toDouble(x: Float): Double = x.toDouble
+ // logic in Numeric base trait mishandles abs(-0.0f)
+ override def abs(x: Float): Float = math.abs(x)
}
trait FloatIsFractional extends FloatIsConflicted with Fractional[Float] {
def div(x: Float, y: Float): Float = x / y
@@ -149,6 +151,8 @@ object Numeric {
def toLong(x: Double): Long = x.toLong
def toFloat(x: Double): Float = x.toFloat
def toDouble(x: Double): Double = x
+ // logic in Numeric base trait mishandles abs(-0.0)
+ override def abs(x: Double): Double = math.abs(x)
}
trait DoubleIsFractional extends DoubleIsConflicted with Fractional[Double] {
def div(x: Double, y: Double): Double = x / y
diff --git a/src/library/scala/ref/WeakReference.scala b/src/library/scala/ref/WeakReference.scala
index c8fb262a08..6ee40aed5c 100644
--- a/src/library/scala/ref/WeakReference.scala
+++ b/src/library/scala/ref/WeakReference.scala
@@ -10,7 +10,7 @@
package scala.ref
/**
- * A wrapper class for java.lag.ref.WeakReference
+ * A wrapper class for java.lang.ref.WeakReference
* The new functionality is (1) results are Option values, instead of using null.
* (2) There is an extractor that maps the weak reference itself into an option.
* @author Sean McDirmid
diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala
index feced71dae..88c0cf8e58 100644
--- a/src/library/scala/sys/process/ProcessBuilder.scala
+++ b/src/library/scala/sys/process/ProcessBuilder.scala
@@ -62,7 +62,7 @@ import ProcessBuilder._
* there's a few methods that create a new `ProcessBuilder` with a
* pre-configured input or output. They are `#<`, `#>` and `#>>`, and may take
* as input either another `ProcessBuilder` (like the pipe described above), or
- * something else such as a `java.io.File` or a `java.lang.InputStream`.
+ * something else such as a `java.io.File` or a `java.io.InputStream`.
* For example:
* {{{
* new URL("http://databinder.net/dispatch/About") #> "grep JSON" #>> new File("About_JSON") !
diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala
index 276e157f55..2e021ad9d9 100644
--- a/src/library/scala/util/Sorting.scala
+++ b/src/library/scala/util/Sorting.scala
@@ -141,14 +141,14 @@ object Sorting {
var done = false
while (!done) {
while (b <= c && x(b) <= v) {
- if (x(b) == v) {
+ if (x(b) equiv v) {
swap(a, b)
a += 1
}
b += 1
}
while (c >= b && x(c) >= v) {
- if (x(c) == v) {
+ if (x(c) equiv v) {
swap(c, d)
d -= 1
}
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 9baf3ec179..6971175f88 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -90,9 +90,9 @@ private[reflect] trait BuildUtils { self: Universe =>
def RefTree(qual: Tree, sym: Symbol): Tree
- def withFreshTermName[T](prefix: String)(f: TermName => T): T
+ def freshTermName(prefix: String): TermName
- def withFreshTypeName[T](prefix: String)(f: TypeName => T): T
+ def freshTypeName(prefix: String): TypeName
val ScalaDot: ScalaDotExtractor
diff --git a/src/reflect/scala/reflect/api/Liftables.scala b/src/reflect/scala/reflect/api/Liftables.scala
new file mode 100644
index 0000000000..6ac5557caa
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Liftables.scala
@@ -0,0 +1,30 @@
+package scala
+package reflect
+package api
+
+// TODO: needs a Scaladoc
+trait Liftables { self: Universe =>
+
+ // TODO: needs a Scaladoc
+ trait Liftable[T] {
+ def apply(value: T): Tree
+ }
+
+ // TODO: needs a Scaladoc
+ object Liftable extends StandardLiftableInstances {
+ def apply[T](f: T => Tree): Liftable[T] =
+ new Liftable[T] { def apply(value: T): Tree = f(value) }
+ }
+
+ // TODO: needs a Scaladoc
+ trait Unliftable[T] {
+ def unapply(tree: Tree): Option[T]
+ }
+
+ // TODO: needs a Scaladoc
+ object Unliftable extends StandardUnliftableInstances {
+ def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] {
+ def unapply(value: Tree): Option[T] = pf.lift(value)
+ }
+ }
+}
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index 6e2e2c3781..1e0854d171 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -68,7 +68,7 @@ import java.io.{ PrintWriter, StringWriter }
* scala> import scala.reflect.runtime.{currentMirror => cm}
* import scala.reflect.runtime.{currentMirror=>cm}
*
- * scala> showRaw(cm.mkToolBox().typeCheck(tree), printTypes = true)
+ * scala> showRaw(cm.mkToolBox().typecheck(tree), printTypes = true)
* res2: String = Block[1](List(
* ClassDef[2](Modifiers(FINAL), newTypeName("C"), List(), Template[3](
* List(Ident[4](newTypeName("AnyRef"))),
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index 57464459be..6756d5e114 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -4,14 +4,7 @@ package api
trait StandardLiftables { self: Universe =>
import build.{SyntacticTuple, ScalaDot}
- trait Liftable[T] {
- def apply(value: T): Tree
- }
-
- object Liftable {
- def apply[T](f: T => Tree): Liftable[T] =
- new Liftable[T] { def apply(value: T): Tree = f(value) }
-
+ trait StandardLiftableInstances {
private def lift[T: Liftable](value: T): Tree = implicitly[Liftable[T]].apply(value)
private def selectScala(names: Name*) = names.tail.foldLeft(ScalaDot(names.head)) { Select(_, _) }
private def callScala(names: Name*)(args: List[Tree]) = Apply(selectScala(names: _*), args)
@@ -122,15 +115,7 @@ trait StandardLiftables { self: Universe =>
}
}
- trait Unliftable[T] {
- def unapply(tree: Tree): Option[T]
- }
-
- object Unliftable {
- def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] {
- def unapply(value: Tree): Option[T] = pf.lift(value)
- }
-
+ trait StandardUnliftableInstances {
private def unliftPrimitive[Unboxed: ClassTag, Boxed: ClassTag] = Unliftable[Unboxed] {
case Literal(Constant(value))
if value.getClass == implicitly[ClassTag[Boxed]].runtimeClass
@@ -149,7 +134,7 @@ trait StandardLiftables { self: Universe =>
implicit def unliftString: Unliftable[String] = Unliftable { case Literal(Constant(s: String)) => s }
implicit def unliftScalaSymbol: Unliftable[scala.Symbol] = Unliftable {
- case Apply(ScalaDot(nme.Symbol), List(Literal(Constant(name: String)))) => scala.Symbol(name)
+ 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}
@@ -223,4 +208,23 @@ trait StandardLiftables { self: Universe =>
case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: UnliftT21(v21) :: UnliftT22(v22) :: Nil) => Tuple22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
}
}
+
+ // names used internally by implementations of standard liftables and unliftables
+ import scala.language.implicitConversions
+ private implicit def cachedNames(nme: self.nme.type): CachedNames.type = CachedNames
+ private object CachedNames {
+ val Array = TermName("Array")
+ val collection = TermName("collection")
+ val immutable = TermName("immutable")
+ val Left = TermName("Left")
+ val List = TermName("List")
+ val Map = TermName("Map")
+ val None = TermName("None")
+ val Right = TermName("Right")
+ val Set = TermName("Set")
+ val Some = TermName("Some")
+ val Symbol = TermName("Symbol")
+ val Vector = TermName("Vector")
+ val util = TermName("util")
+ }
}
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index 4ea6ddc7f8..aec5f19fa0 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -96,20 +96,6 @@ trait StandardNames {
* of non-private vals and vars are renamed using `LOCAL_SUFFIX_STRING`.
*/
val LOCAL_SUFFIX_STRING: String
-
- protected[reflect] val Array: NameType
- protected[reflect] val collection: NameType
- protected[reflect] val immutable: NameType
- protected[reflect] val Left: NameType
- protected[reflect] val List: NameType
- protected[reflect] val Map: NameType
- protected[reflect] val None: NameType
- protected[reflect] val Right: NameType
- protected[reflect] val Set: NameType
- protected[reflect] val Some: NameType
- protected[reflect] val Symbol: NameType
- protected[reflect] val util: NameType
- protected[reflect] val Vector: NameType
}
/** Defines standard type names that can be accessed via the [[tpnme]] member.
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index 534f69a23e..1da2c24306 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -78,6 +78,7 @@ abstract class Universe extends Symbols
with Mirrors
with Printers
with Importers
+ with Liftables
with Quasiquotes
{
/** Use `refiy` to produce the abstract syntax tree representing a given Scala expression.
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 13c2268227..0a81bfa2a5 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -134,9 +134,9 @@ trait BuildUtils { self: SymbolTable =>
def RefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym
- def withFreshTermName[T](prefix: String)(f: TermName => T): T = f(freshTermName(prefix))
+ def freshTermName(prefix: String): TermName = self.freshTermName(prefix)
- def withFreshTypeName[T](prefix: String)(f: TypeName => T): T = f(freshTypeName(prefix))
+ def freshTypeName(prefix: String): TypeName = self.freshTypeName(prefix)
protected implicit def fresh: FreshNameCreator = self.currentFreshNameCreator
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 3a630b6a16..9c5a593ca5 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -281,7 +281,6 @@ trait Mirrors extends api.Mirrors {
class RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol {
this setInfo NullaryMethodType(RootClass.tpe)
- RootClass.sourceModule = this
override def isRootPackage = true
}
@@ -296,6 +295,7 @@ trait Mirrors extends api.Mirrors {
override def isRoot = true
override def isEffectiveRoot = true
override def isNestedClass = false
+ override def sourceModule = RootPackage
}
// This is <root>, the actual root of everything except the package _root_.
@@ -316,6 +316,7 @@ trait Mirrors extends api.Mirrors {
class EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
override def isEffectiveRoot = true
override def isEmptyPackageClass = true
+ override def sourceModule = EmptyPackage
}
lazy val EmptyPackageClass = new EmptyPackageClass
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 5ad2b15e8c..ea6afa7349 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -124,15 +124,8 @@ trait StdNames {
final val AnyRef: NameType = "AnyRef"
final val Array: NameType = "Array"
final val List: NameType = "List"
- final val Left: NameType = "Left"
- final val Right: NameType = "Right"
- final val Vector: NameType = "Vector"
final val Seq: NameType = "Seq"
- final val Set: NameType = "Set"
- final val Some: NameType = "Some"
final val Symbol: NameType = "Symbol"
- final val Map: NameType = "Map"
- final val None: NameType = "None"
final val WeakTypeTag: NameType = "WeakTypeTag"
final val TypeTag : NameType = "TypeTag"
final val Expr: NameType = "Expr"
@@ -681,6 +674,8 @@ trait StdNames {
val find_ : NameType = "find"
val flatMap: NameType = "flatMap"
val foreach: NameType = "foreach"
+ val freshTermName: NameType = "freshTermName"
+ val freshTypeName: NameType = "freshTypeName"
val get: NameType = "get"
val hashCode_ : NameType = "hashCode"
val hash_ : NameType = "hash"
@@ -763,7 +758,6 @@ trait StdNames {
val typedProductIterator: NameType = "typedProductIterator"
val TypeName: NameType = "TypeName"
val typeTagToManifest: NameType = "typeTagToManifest"
- val util: NameType = "util"
val unapply: NameType = "unapply"
val unapplySeq: NameType = "unapplySeq"
val unbox: NameType = "unbox"
@@ -799,7 +793,7 @@ trait StdNames {
final val STAR : NameType = "*"
final val TILDE: NameType = "~"
- final val isUnary: Set[Name] = scala.collection.immutable.Set(MINUS, PLUS, TILDE, BANG)
+ final val isUnary: Set[Name] = Set(MINUS, PLUS, TILDE, BANG)
}
// value-conversion methods
@@ -852,8 +846,8 @@ trait StdNames {
val UNARY_! = encode("unary_!")
// Grouped here so Cleanup knows what tests to perform.
- val CommonOpNames = scala.collection.immutable.Set[Name](OR, XOR, AND, EQ, NE)
- val BooleanOpNames = scala.collection.immutable.Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
+ val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE)
+ val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
val add: NameType = "add"
val complement: NameType = "complement"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 0dfcf06874..e15b33e5d7 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -801,9 +801,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
isConstructor && !isPrimaryConstructor
/** Is this symbol a synthetic apply or unapply method in a companion object of a case class? */
+ // xeno-by: why this obscure use of the CASE flag? why not simply compare name with nme.apply and nme.unapply?
final def isCaseApplyOrUnapply =
isMethod && isCase && isSynthetic
+ /** Is this symbol a synthetic copy method in a case class? */
+ final def isCaseCopy =
+ isMethod && owner.isCase && isSynthetic && name == nme.copy
+
/** Is this symbol a trait which needs an implementation class? */
final def needsImplClass = (
isTrait
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index 29c1af110b..5a25801335 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -23,6 +23,12 @@ trait Typers {
*/
def openMacros: List[BlackboxContext]
+ /** @see `Typers.typecheck`
+ */
+ @deprecated("Use `c.typecheck` instead", "2.11.0")
+ def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree =
+ typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
+
/** Typechecks the provided tree against the expected type `pt` in the macro callsite context.
*
* If `silent` is false, `TypecheckException` will be thrown in case of a typecheck error.
@@ -36,7 +42,7 @@ trait Typers {
*
* @throws [[scala.reflect.macros.TypecheckException]]
*/
- def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
+ def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
/** Infers an implicit value of the expected type `pt` in the macro callsite context.
* Optional `pos` parameter provides a position that will be associated with the implicit search.
@@ -44,7 +50,7 @@ trait Typers {
* If `silent` is false, `TypecheckException` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
- * Unlike in `typeCheck`, `silent` is true by default.
+ * Unlike in `typecheck`, `silent` is true by default.
*
* @throws [[scala.reflect.macros.TypecheckException]]
*/
@@ -56,7 +62,7 @@ trait Typers {
* If `silent` is false, `TypecheckException` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
- * Unlike in `typeCheck`, `silent` is true by default.
+ * Unlike in `typecheck`, `silent` is true by default.
*
* @throws [[scala.reflect.macros.TypecheckException]]
*/
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 0f41506382..9c4a3a5fe1 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -204,9 +204,10 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
// inaccessible: this.TypeHistory
this.TermName
this.TypeName
- this.BooleanFlag
this.Liftable
this.Unliftable
+ this.BooleanFlag
+ // inaccessible: this.CachedNames
this.WeakTypeTag
this.TypeTag
this.Expr