summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala20
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala62
-rw-r--r--src/reflect/scala/reflect/internal/Constants.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala27
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala52
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Phase.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala30
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Reporting.scala9
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala4
-rw-r--r--src/reflect/scala/reflect/internal/SymbolPairs.scala28
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala178
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala229
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala4
-rw-r--r--src/reflect/scala/reflect/internal/tpe/GlbLubs.scala20
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala28
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala14
-rw-r--r--src/reflect/scala/reflect/internal/transform/RefChecks.scala14
-rw-r--r--src/reflect/scala/reflect/internal/transform/Transforms.scala5
-rw-r--r--src/reflect/scala/reflect/internal/transform/UnCurry.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala7
25 files changed, 394 insertions, 366 deletions
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index fa19103d0c..cfde164754 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -175,15 +175,6 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
case (Nil, defaults) => defaults contains category
case (metas, _) => metas exists (_ matches category)
}
-
- def mkFilter(categories: List[Symbol], defaultRetention: Boolean)(ann: AnnotationInfo) =
- (ann.metaAnnotations, ann.defaultTargets) match {
- case (Nil, Nil) => defaultRetention
- case (Nil, defaults) => categories exists defaults.contains
- case (metas, _) =>
- val metaSyms = metas collect { case ann if !ann.symbol.isInstanceOf[StubSymbol] => ann.symbol }
- categories exists (category => metaSyms exists (_ isNonBottomSubClass category))
- }
}
class CompleteAnnotationInfo(
@@ -305,10 +296,13 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
}
/** The default kind of members to which this annotation is attached.
- * For instance, for scala.deprecated defaultTargets =
- * List(getter, setter, beanGetter, beanSetter).
- */
- def defaultTargets = symbol.annotations map (_.symbol) filter isMetaAnnotation
+ * For instance, for scala.deprecated defaultTargets =
+ * List(getter, setter, beanGetter, beanSetter).
+ *
+ * NOTE: have to call symbol.initialize, since we won't get any annotations if the symbol hasn't yet been completed
+ */
+ def defaultTargets = symbol.initialize.annotations map (_.symbol) filter isMetaAnnotation
+
// Test whether the typeSymbol of atp conforms to the given class.
def matches(clazz: Symbol) = !symbol.isInstanceOf[StubSymbol] && (symbol isNonBottomSubClass clazz)
// All subtrees of all args are considered.
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 81281b5eb4..78f9721713 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -56,42 +56,44 @@ trait BaseTypeSeqs {
if(pending contains i) {
pending.clear()
throw CyclicInheritance
- } else
- elems(i) match {
- case rtp @ RefinedType(variants, decls) =>
- // can't assert decls.isEmpty; see t0764
- //if (!decls.isEmpty) abort("computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
- //Console.println("compute closure of "+this+" => glb("+variants+")")
- pending += i
- try {
- mergePrefixAndArgs(variants, Variance.Contravariant, lubDepth(variants)) match {
- case NoType => typeError("no common type instance of base types "+(variants mkString ", and ")+" exists.")
- case tp0 =>
- pending(i) = false
- elems(i) = tp0
- tp0
- }
- }
- catch {
- case CyclicInheritance =>
- typeError(
- "computing the common type instance of base types "+(variants mkString ", and ")+" leads to a cycle.")
+ } else {
+ def computeLazyType(rtp: RefinedType): Type = {
+ if (!isIntersectionTypeForLazyBaseType(rtp))
+ devWarning("unexpected RefinedType in base type seq, lazy BTS elements should be created via intersectionTypeForLazyBaseType: " + rtp)
+ val variants = rtp.parents
+ // can't assert decls.isEmpty; see t0764
+ //if (!decls.isEmpty) abort("computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
+ //Console.println("compute closure of "+this+" => glb("+variants+")")
+ pending += i
+ try {
+ mergePrefixAndArgs(variants, Variance.Contravariant, lubDepth(variants)) match {
+ case NoType => typeError("no common type instance of base types " + (variants mkString ", and ") + " exists.")
+ case tp0 =>
+ pending(i) = false
+ elems(i) = tp0
+ tp0
}
+ }
+ catch {
+ case CyclicInheritance =>
+ typeError(
+ "computing the common type instance of base types " + (variants mkString ", and ") + " leads to a cycle.")
+ }
+ }
+ elems(i) match {
+ case rtp@RefinedType(variants, decls) =>
+ computeLazyType(rtp)
+ case et @ ExistentialType(quantified, rtp: RefinedType) =>
+ existentialAbstraction(quantified, computeLazyType(rtp))
case tp =>
tp
}
+ }
def rawElem(i: Int) = elems(i)
- /** The type symbol of the type at i'th position in this sequence;
- * no evaluation needed.
- */
- def typeSymbol(i: Int): Symbol = {
- elems(i) match {
- case RefinedType(v :: vs, _) => v.typeSymbol
- case tp => tp.typeSymbol
- }
- }
+ /** The type symbol of the type at i'th position in this sequence */
+ def typeSymbol(i: Int): Symbol = elems(i).typeSymbol
/** Return all evaluated types in this sequence as a list */
def toList: List[Type] = elems.toList
@@ -215,7 +217,7 @@ trait BaseTypeSeqs {
}
i += 1
}
- buf += intersectionType(minTypes)
+ buf += intersectionTypeForLazyBaseType(minTypes) // TODO this reverses the order. Does this matter? Or should this be minTypes.reverse?
btsSize += 1
}
}
diff --git a/src/reflect/scala/reflect/internal/Constants.scala b/src/reflect/scala/reflect/internal/Constants.scala
index 85d0efdcba..7b47798ff7 100644
--- a/src/reflect/scala/reflect/internal/Constants.scala
+++ b/src/reflect/scala/reflect/internal/Constants.scala
@@ -7,7 +7,6 @@ package scala
package reflect
package internal
-import java.lang.Integer.toOctalString
import scala.annotation.switch
trait Constants extends api.Constants {
@@ -212,7 +211,7 @@ trait Constants extends api.Constants {
case '"' => "\\\""
case '\'' => "\\\'"
case '\\' => "\\\\"
- case _ => if (ch.isControl) "\\0" + toOctalString(ch.toInt) else String.valueOf(ch)
+ case _ => if (ch.isControl) "\\u%04X".format(ch.toInt) else String.valueOf(ch)
}
def escapedStringValue: String = {
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index fe6d88e7c7..d0539dfd42 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -362,7 +362,6 @@ trait Definitions extends api.StandardDefinitions {
// classes with special meanings
lazy val StringAddClass = requiredClass[scala.runtime.StringAdd]
lazy val ScalaNumberClass = requiredClass[scala.math.ScalaNumber]
- lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter]
lazy val DelayedInitClass = requiredClass[scala.DelayedInit]
def delayedInitMethod = getMemberMethod(DelayedInitClass, nme.delayedInit)
@@ -675,8 +674,10 @@ trait Definitions extends api.StandardDefinitions {
// Note that these call .dealiasWiden and not .normalize, the latter of which
// tends to change the course of events by forcing types.
def isFunctionType(tp: Type) = isFunctionTypeDirect(tp.dealiasWiden)
+
// the number of arguments expected by the function described by `tp` (a FunctionN or SAM type),
// or `-1` if `tp` does not represent a function type or SAM
+ // for use during typers (after fields, samOf will be confused by abstract accessors for trait fields)
def functionArityFromType(tp: Type) = {
val dealiased = tp.dealiasWiden
if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.length - 1
@@ -686,13 +687,14 @@ trait Definitions extends api.StandardDefinitions {
}
}
- // the result type of a function or corresponding SAM type
- def functionResultType(tp: Type): Type = {
+ // the argument types expected by the function described by `tp` (a FunctionN or SAM type),
+ // or `Nil` if `tp` does not represent a function type or SAM (or if it happens to be Function0...)
+ def functionOrSamArgTypes(tp: Type): List[Type] = {
val dealiased = tp.dealiasWiden
- if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.last
+ if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.init
else samOf(tp) match {
- case samSym if samSym.exists => tp.memberInfo(samSym).resultType.deconst
- case _ => NoType
+ case samSym if samSym.exists => tp.memberInfo(samSym).paramTypes
+ case _ => Nil
}
}
@@ -837,9 +839,9 @@ trait Definitions extends api.StandardDefinitions {
* The class defining the method is a supertype of `tp` that
* has a public no-arg primary constructor.
*/
- def samOf(tp: Type): Symbol = if (!doSam) NoSymbol else {
+ def samOf(tp: Type): Symbol = if (!doSam) NoSymbol else if (!isNonRefinementClassType(unwrapToClass(tp))) NoSymbol else {
// look at erased type because we (only) care about what ends up in bytecode
- // (e.g., an alias type or intersection type is fine as long as the intersection dominator compiles to an interface)
+ // (e.g., an alias type is fine as long as is compiles to a single-abstract-method)
val tpSym: Symbol = erasure.javaErasure(tp).typeSymbol
if (tpSym.exists && tpSym.isClass
@@ -864,7 +866,7 @@ trait Definitions extends api.StandardDefinitions {
// must filter out "universal" members (getClass is deferred for some reason)
val deferredMembers = (
tp.membersBasedOnFlags(excludedFlags = BridgeAndPrivateFlags, requiredFlags = METHOD).toList.filter(
- mem => mem.isDeferredNotJavaDefault && !isUniversalMember(mem)
+ mem => mem.isDeferred && !isUniversalMember(mem)
) // TODO: test
)
@@ -1049,11 +1051,7 @@ trait Definitions extends api.StandardDefinitions {
}
}
- /** Remove references to class Object (other than the head) in a list of parents */
- def removeLaterObjects(tps: List[Type]): List[Type] = tps match {
- case Nil => Nil
- case x :: xs => x :: xs.filterNot(_.typeSymbol == ObjectClass)
- }
+
/** Remove all but one reference to class Object from a list of parents. */
def removeRedundantObjects(tps: List[Type]): List[Type] = tps match {
case Nil => Nil
@@ -1470,6 +1468,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val StringAdd_+ = getMemberMethod(StringAddClass, nme.PLUS)
// The given symbol represents either String.+ or StringAdd.+
+ // TODO: this misses Predef.any2stringadd
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
lazy val StringContext_f = getMemberMethod(StringContextClass, nme.f)
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index e06decea6d..a146f9aea5 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -169,17 +169,23 @@ class Flags extends ModifierFlags {
final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED
+ final val SYNTHESIZE_IMPL_IN_SUBCLASS = 1L << 50 // used in fields phase to indicate this accessor should receive an implementation in a subclass
+
+ // flags used strictly internally in the Fields phase (info/tree transform):
+ final val NEEDS_TREES = 1L << 59 // this symbol needs a tree. (distinct from SYNTHESIZE_IMPL_IN_SUBCLASS)
+
// ------- shift definitions -------------------------------------------------------
//
// Flags from 1L to (1L << 50) are normal flags.
//
- // The flags DEFERRED (1L << 4) to MODULE (1L << 8) have a `late` counterpart. Late flags change
- // their counterpart from 0 to 1 after a specific phase (see below). The first late flag
- // (lateDEFERRED) is at (1L << 51), i.e., late flags are shifted by 47. The last one is (1L << 55).
+ // The "late" counterpart to flags DEFERRED (1L << 4) to MODULE (1L << 8)
+ // show up in `sym.flags` as their regular counterpart once the phase mask admits them (see below).
+ // The first late flag (lateDEFERRED) is at (1L << 51), i.e., late flags are shifted by 47. The last one is (1L << 55).
+ // Think of it as a poor man's flag history akin to the type history for a symbol's info.
//
- // The flags PROTECTED (1L) to PRIVATE (1L << 2) have a `not` counterpart. Negated flags change
- // their counterpart from 1 to 0 after a specific phase (see below). They are shifted by 56, i.e.,
- // the first negated flag (notPROTECTED) is at (1L << 56), the last at (1L << 58).
+ // The "not" counterpart to flags PROTECTED (1L) to PRIVATE (1L << 2)
+ // are negated flags that suppress their counterpart after a specific phase (see below).
+ // They are shifted by 56, i.e., the first negated flag (notPROTECTED) is at (1L << 56), the last at (1L << 58).
//
// Late and negative flags are only enabled after certain phases, implemented by the phaseNewFlags
// method of the SubComponent, so they implement a bit of a flag history.
@@ -211,20 +217,15 @@ class Flags extends ModifierFlags {
// erasure 15 [START] <latedeferred>
// mixin 20 [START] <latemodule> <notoverride>
//
- // lateMETHOD set in RefChecks#transformInfo.
- // lateFINAL set in Symbols#makeNotPrivate.
// notPRIVATE set in Symbols#makeNotPrivate, IExplicitOuter#transform, Inliners.
// notPROTECTED set in ExplicitOuter#transform.
- // lateDEFERRED set in AddInterfaces, Mixin, etc.
- // lateMODULE set in Mixin#transformInfo.
- // notOVERRIDE set in Mixin#preTransform.
- final val lateDEFERRED = (DEFERRED: Long) << LateShift
- final val lateFINAL = (FINAL: Long) << LateShift
- final val lateMETHOD = (METHOD: Long) << LateShift
- final val lateMODULE = (MODULE: Long) << LateShift
+// final val lateDEFERRED = (DEFERRED: Long) << LateShift // unused
+// final val lateFINAL = (FINAL: Long) << LateShift // only used for inliner -- could be subsumed by notPRIVATE?
+// final val lateMETHOD = (METHOD: Long) << LateShift // unused
+// final val lateMODULE = (MODULE: Long) << LateShift // unused
- final val notOVERRIDE = (OVERRIDE: Long) << AntiShift
+// final val notOVERRIDE = (OVERRIDE: Long) << AntiShift // unused
final val notPRIVATE = (PRIVATE: Long) << AntiShift
final val notPROTECTED = (PROTECTED: Long) << AntiShift
@@ -257,7 +258,8 @@ class Flags extends ModifierFlags {
/** These modifiers appear in TreePrinter output. */
final val PrintableFlags =
ExplicitFlags | BridgeFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO |
- ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | STATIC | SPECIALIZED | SYNCHRONIZED | ARTIFACT
+ ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | STATIC | SPECIALIZED | SYNCHRONIZED | ARTIFACT |
+ SYNTHESIZE_IMPL_IN_SUBCLASS | NEEDS_TREES
/** When a symbol for a field is created, only these flags survive
* from Modifiers. Others which may be applied at creation time are:
@@ -442,16 +444,16 @@ class Flags extends ModifierFlags {
case JAVA_DEFAULTMETHOD => "<defaultmethod>" // (1L << 47)
case JAVA_ENUM => "<enum>" // (1L << 48)
case JAVA_ANNOTATION => "<annotation>" // (1L << 49)
- case 0x4000000000000L => "" // (1L << 50)
- case `lateDEFERRED` => "<latedeferred>" // (1L << 51)
- case `lateFINAL` => "<latefinal>" // (1L << 52)
- case `lateMETHOD` => "<latemethod>" // (1L << 53)
- case 0x80000000000000L => "" // (1L << 54)
- case `lateMODULE` => "<latemodule>" // (1L << 55)
+ case SYNTHESIZE_IMPL_IN_SUBCLASS => "<sub_synth>" // (1L << 50)
+ case 0x08000000000000L => "<latedeferred>" // (1L << 51)
+ case 0x10000000000000L => "<latefinal>" // (1L << 52)
+ case 0x20000000000000L => "<latemethod>" // (1L << 53)
+ case 0x40000000000000L => "" // (1L << 54)
+ case 0x80000000000000L => "<latemodule>" // (1L << 55)
case `notPROTECTED` => "<notprotected>" // (1L << 56)
- case `notOVERRIDE` => "<notoverride>" // (1L << 57)
+ case 0x200000000000000L => "<notoverride>" // (1L << 57)
case `notPRIVATE` => "<notprivate>" // (1L << 58)
- case 0x800000000000000L => "" // (1L << 59)
+ case NEEDS_TREES => "<needs_trees>" // (1L << 59)
case 0x1000000000000000L => "" // (1L << 60)
case 0x2000000000000000L => "" // (1L << 61)
case 0x4000000000000000L => "" // (1L << 62)
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index e793586e18..dfada48c5e 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -122,9 +122,6 @@ trait HasFlags {
def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM)
def isTraitOrInterface = isTrait || isInterface
- def isDeferredOrJavaDefault = hasFlag(DEFERRED | JAVA_DEFAULTMETHOD)
- def isDeferredNotJavaDefault = isDeferred && !hasFlag(JAVA_DEFAULTMETHOD)
-
def flagBitsToString(bits: Long): String = {
// Fast path for common case
if (bits == 0L) "" else {
diff --git a/src/reflect/scala/reflect/internal/Phase.scala b/src/reflect/scala/reflect/internal/Phase.scala
index a761f686e6..eb193adbf2 100644
--- a/src/reflect/scala/reflect/internal/Phase.scala
+++ b/src/reflect/scala/reflect/internal/Phase.scala
@@ -47,6 +47,10 @@ abstract class Phase(val prev: Phase) {
final val specialized: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "specialize" || prev.specialized)
final val refChecked: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "refchecks" || prev.refChecked)
+ // are we past the fields phase, so that:
+ // - we should allow writing to vals (as part of type checking trait setters)
+ // - modules have module accessors
+ final val assignsFields: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "fields" || prev.assignsFields)
/** This is used only in unsafeTypeParams, and at this writing is
* overridden to false in parser, namer, typer, and erasure. (And NoPhase.)
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 37b99c4345..9602a2859b 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -1045,23 +1045,23 @@ trait Printers extends api.Printers { self: SymbolTable =>
print("")
}
- case l @ Literal(x) =>
- import Chars.LF
- x match {
- case Constant(v: String) if {
- val strValue = x.stringValue
- strValue.contains(LF) && strValue.contains("\"\"\"") && strValue.size > 1
- } =>
- val splitValue = x.stringValue.split(s"$LF").toList
- val multilineStringValue = if (x.stringValue.endsWith(s"$LF")) splitValue :+ "" else splitValue
- val trQuotes = "\"\"\""
- print(trQuotes); printSeq(multilineStringValue) { print(_) } { print(LF) }; print(trQuotes)
- case _ =>
- // processing Float constants
- val printValue = x.escapedStringValue + (if (x.value.isInstanceOf[Float]) "F" else "")
- print(printValue)
+ case Literal(k @ Constant(s: String)) if s.contains(Chars.LF) =>
+ val tq = "\"" * 3
+ val lines = s.lines.toList
+ if (lines.lengthCompare(1) <= 0) print(k.escapedStringValue)
+ else {
+ val tqp = """["]{3}""".r
+ val tqq = """""\\"""" // ""\" is triple-quote quoted
+ print(tq)
+ printSeq(lines.map(x => tqp.replaceAllIn(x, tqq)))(print(_))(print(Chars.LF))
+ print(tq)
}
+ case Literal(x) =>
+ // processing Float constants
+ val suffix = x.value match { case _: Float => "F" case _ => "" }
+ print(s"${x.escapedStringValue}${suffix}")
+
case an @ Annotated(ap, tree) =>
val printParentheses = needsParentheses(tree)()
parenthesize(printParentheses) { print(tree) }; print(if (tree.isType) " " else ": ")
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 30f2efd7e3..026438e421 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -285,6 +285,7 @@ trait ReificationSupport { self: SymbolTable =>
val (gvdefs, etdefs) = rawEdefs.partition(treeInfo.isEarlyValDef)
val (fieldDefs, UnCtor(ctorMods, ctorVparamss, lvdefs) :: body) = rest.splitAt(indexOfCtor(rest))
val evdefs = gvdefs.zip(lvdefs).map {
+ // TODO: in traits, early val defs are defdefs
case (gvdef @ ValDef(_, _, tpt: TypeTree, _), ValDef(_, _, _, rhs)) =>
copyValDef(gvdef)(tpt = tpt.original, rhs = rhs)
case (tr1, tr2) =>
@@ -725,6 +726,7 @@ trait ReificationSupport { self: SymbolTable =>
}
// match call to either withFilter or filter
+ // TODO: now that we no longer rewrite `filter` to `withFilter`, maybe this extractor should only look for `withFilter`?
protected object FilterCall {
def unapply(tree: Tree): Option[(Tree,Tree)] = tree match {
case Apply(Select(obj, nme.withFilter | nme.filter), arg :: Nil) =>
diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala
index 27fda9a7d4..c1f0140479 100644
--- a/src/reflect/scala/reflect/internal/Reporting.scala
+++ b/src/reflect/scala/reflect/internal/Reporting.scala
@@ -7,6 +7,8 @@ package scala
package reflect
package internal
+import settings.MutableSettings
+
/** Provides delegates to the reporter doing the actual work.
* All forwarding methods should be marked final,
* but some subclasses out of our reach still override them.
@@ -105,6 +107,13 @@ abstract class Reporter {
/** Finish reporting: print summaries, release resources. */
def finish(): Unit = ()
+
+ /** After reporting, offer advice on getting more details. */
+ def rerunWithDetails(setting: MutableSettings#Setting, name: String): String =
+ setting.value match {
+ case b: Boolean if !b => s"; re-run with ${name} for details"
+ case _ => s"; re-run enabling ${name} for details, or try -help"
+ }
}
// TODO: move into superclass once partest cuts tie on Severity
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 76e34153c9..78f360409d 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -76,4 +76,6 @@ trait StdAttachments {
* in place of the outer parameter, can help callers to avoid capturing the outer instance.
*/
case object OuterArgCanBeElided extends PlainAttachment
+
+ case object UseInvokeSpecial extends PlainAttachment
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 4f5a545c95..925018d3a6 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -95,6 +95,8 @@ trait StdNames {
val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING
val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING
val LOCAL_SUFFIX_STRING: String = NameTransformer.LOCAL_SUFFIX_STRING
+ val LAZY_LOCAL_SUFFIX_STRING: String = NameTransformer.LAZY_LOCAL_SUFFIX_STRING
+
val TRAIT_SETTER_SEPARATOR_STRING: String = NameTransformer.TRAIT_SETTER_SEPARATOR_STRING
val SINGLETON_SUFFIX: String = ".type"
@@ -337,7 +339,6 @@ trait StdNames {
val DEFAULT_CASE: NameType = "defaultCase$"
val EQEQ_LOCAL_VAR: NameType = "eqEqTemp$"
val FAKE_LOCAL_THIS: NameType = "this$"
- val LAZY_LOCAL: NameType = "$lzy"
val LAZY_SLOW_SUFFIX: NameType = "$lzycompute"
val UNIVERSE_BUILD_PREFIX: NameType = "$u.internal.reificationSupport."
val UNIVERSE_PREFIX: NameType = "$u."
@@ -1171,6 +1172,7 @@ trait StdNames {
final val Invoke: TermName = newTermName("invoke")
final val InvokeExact: TermName = newTermName("invokeExact")
+ final val Metafactory: TermName = newTermName("metafactory")
final val AltMetafactory: TermName = newTermName("altMetafactory")
final val Bootstrap: TermName = newTermName("bootstrap")
diff --git a/src/reflect/scala/reflect/internal/SymbolPairs.scala b/src/reflect/scala/reflect/internal/SymbolPairs.scala
index a52d2d8510..320c814696 100644
--- a/src/reflect/scala/reflect/internal/SymbolPairs.scala
+++ b/src/reflect/scala/reflect/internal/SymbolPairs.scala
@@ -30,27 +30,6 @@ abstract class SymbolPairs {
val global: SymbolTable
import global._
- /** Type operations relative to a prefix. All operations work on Symbols,
- * and the types are the member types of those symbols in the prefix.
- */
- class RelativeTo(val prefix: Type) {
- def this(clazz: Symbol) = this(clazz.thisType)
- import scala.language.implicitConversions // geez, it even has to hassle me when it's private
- private implicit def symbolToType(sym: Symbol): Type = prefix memberType sym
-
- def erasureOf(sym: Symbol): Type = erasure.erasure(sym)(sym: Type)
- def signature(sym: Symbol): String = sym defStringSeenAs (sym: Type)
- def erasedSignature(sym: Symbol): String = sym defStringSeenAs erasureOf(sym)
-
- def isSameType(sym1: Symbol, sym2: Symbol): Boolean = sym1 =:= sym2
- def isSubType(sym1: Symbol, sym2: Symbol): Boolean = sym1 <:< sym2
- def isSuperType(sym1: Symbol, sym2: Symbol): Boolean = sym2 <:< sym1
- def isSameErasure(sym1: Symbol, sym2: Symbol): Boolean = erasureOf(sym1) =:= erasureOf(sym2)
- def matches(sym1: Symbol, sym2: Symbol): Boolean = (sym1: Type) matches (sym2: Type)
-
- override def toString = s"RelativeTo($prefix)"
- }
-
/** Are types tp1 and tp2 equivalent seen from the perspective
* of `baseClass`? For instance List[Int] and Seq[Int] are =:=
* when viewed from IterableClass.
@@ -58,10 +37,11 @@ abstract class SymbolPairs {
def sameInBaseClass(baseClass: Symbol)(tp1: Type, tp2: Type) =
(tp1 baseType baseClass) =:= (tp2 baseType baseClass)
- case class SymbolPair(base: Symbol, low: Symbol, high: Symbol) {
+ final case class SymbolPair(base: Symbol, low: Symbol, high: Symbol) {
+ private[this] val self = base.thisType
+
def pos = if (low.owner == base) low.pos else if (high.owner == base) high.pos else base.pos
- def self: Type = base.thisType
- def rootType: Type = base.thisType
+ def rootType: Type = self
def lowType: Type = self memberType low
def lowErased: Type = erasure.specialErasure(base)(low.tpe)
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index ab52a875f8..487aadf5e5 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -96,8 +96,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM)
def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT)
def isJava: Boolean = isJavaDefined
- def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable
- def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable
+
+ def isField: Boolean = isTerm && !isModule && (!isMethod || owner.isTrait && isAccessor)
+ def isMutableVal = if (owner.isTrait) !hasFlag(STABLE) else isMutable
+ def isVal: Boolean = isField && !isMutableVal
+ def isVar: Boolean = isField && !isLazy && isMutableVal
+
def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType
def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL)
def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL)
@@ -320,17 +324,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newImport(pos: Position): TermSymbol =
newTermSymbol(nme.IMPORT, pos)
- def newModuleVarSymbol(accessor: Symbol): TermSymbol = {
- val newName = nme.moduleVarName(accessor.name.toTermName)
- val newFlags = MODULEVAR | ( if (this.isClass) PrivateLocal | SYNTHETIC else 0 )
- val newInfo = thisType.memberType(accessor).finalResultType
- val mval = newVariable(newName, accessor.pos.focus, newFlags.toLong) addAnnotation VolatileAttr
-
- if (this.isClass)
- mval setInfoAndEnter newInfo
- else
- mval setInfo newInfo
- }
final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol]
@@ -753,10 +746,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def hasGetter = isTerm && nme.isLocalName(name)
/**
- * Nested modules which have no static owner when ModuleDefs are eliminated (refchecks) are
- * given the lateMETHOD flag, which makes them appear as methods after refchecks.
+ * Nested modules with a non-static owner receive the METHOD flag during UnCurry's info transform.
+ * (They are replaced by a ClassDef and DefDef for the module accessor during the fields phase.)
*
- * Note: the lateMETHOD flag is added lazily in the info transformer of the RefChecks phase.
+ * Note: the METHOD flag is added lazily in the info transformer of the UnCurry phase.
* This means that forcing the `sym.info` may change the value of `sym.isMethod`. Forcing the
* info is in the responsibility of the caller. Doing it eagerly here was tried (0ccdb151f) but
* has proven to lead to bugs (SI-8907).
@@ -992,10 +985,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isEffectivelyFinal: Boolean = (
(this hasFlag FINAL | PACKAGE)
|| isModuleOrModuleClass && (isTopLevel || !settings.overrideObjects)
- || isTerm && (
- isPrivate
- || isLocalToBlock
- )
+ || isTerm && (isPrivate || isLocalToBlock || (hasAllFlags(notPRIVATE | METHOD) && !hasFlag(DEFERRED)))
|| isClass && originalOwner.isTerm && children.isEmpty // we track known subclasses of term-owned classes, use that infer finality
)
/** Is this symbol effectively final or a concrete term member of sealed class whose children do not override it */
@@ -1532,7 +1522,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def setInfo(info: Type): this.type = { info_=(info); this }
/** Modifies this symbol's info in place. */
def modifyInfo(f: Type => Type): this.type = setInfo(f(info))
- /** Substitute second list of symbols for first in current info. */
+ /** Substitute second list of symbols for first in current info.
+ *
+ * NOTE: this discards the type history (uses setInfo)
+ */
def substInfo(syms0: List[Symbol], syms1: List[Symbol]): this.type =
if (syms0.isEmpty) this
else modifyInfo(_.substSym(syms0, syms1))
@@ -2048,7 +2041,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
assert(hasAccessorFlag, this)
val localField = owner.info decl localName
- if (localField == NoSymbol && this.hasFlag(MIXEDIN)) {
+ if (localField == NoSymbol && this.hasFlag(MIXEDIN)) { // TODO: fields phase does not (yet?) add MIXEDIN in setMixedinAccessorFlags
// SI-8087: private[this] fields don't have a `localName`. When searching the accessed field
// for a mixin accessor of such a field, we need to look for `name` instead.
// The phase travel ensures that the field is found (`owner` is the trait class symbol, the
@@ -2088,8 +2081,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** If this is a lazy value, the lazy accessor; otherwise this symbol. */
def lazyAccessorOrSelf: Symbol = if (isLazy) lazyAccessor else this
- /** If this is an accessor, the accessed symbol. Otherwise, this symbol. */
- def accessedOrSelf: Symbol = if (hasAccessorFlag) accessed else this
+ /** `accessed`, if this is an accessor that should have an underlying field. Otherwise, `this`.
+ * Note that a "regular" accessor in a trait does not have a field, as an interface cannot define a field.
+ * "non-regular" vals are: early initialized or lazy vals.
+ * Eventually, we should delay introducing symbols for all val/vars until the fields (or lazyvals) phase,
+ * as they are an implementation detail that's irrelevant to type checking.
+ */
+ def accessedOrSelf: Symbol =
+ if (hasAccessorFlag && (!owner.isTrait || hasFlag(PRESUPER | LAZY))) accessed
+ else this
/** For an outer accessor: The class from which the outer originates.
* For all other symbols: NoSymbol
@@ -2447,14 +2447,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def makeNotPrivate(base: Symbol) {
if (this.isPrivate) {
- setFlag(notPRIVATE)
- // Marking these methods final causes problems for proxies which use subclassing. If people
- // write their code with no usage of final, we probably shouldn't introduce it ourselves
- // unless we know it is safe. ... Unfortunately if they aren't marked final the inliner
- // thinks it can't inline them. So once again marking lateFINAL, and in genjvm we no longer
- // generate ACC_FINAL on "final" methods which are actually lateFINAL.
- if (isMethod && !isDeferred)
- setFlag(lateFINAL)
+ setFlag(notPRIVATE) // this makes it effectively final (isEffectivelyFinal)
+ // don't set FINAL -- methods not marked final by user should not end up final in bytecode
+ // inliner will know it's effectively final (notPRIVATE non-deferred method)
if (!isStaticModule && !isClassConstructor) {
expandName(base)
if (isModule) moduleClass.makeNotPrivate(base)
@@ -2532,30 +2527,34 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private def symbolKind: SymbolKind = {
var kind =
- if (isTermMacro) ("term macro", "macro method", "MACM")
- else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE")
- else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY")
- else if (isPackageClass) ("package class", "package", "PKC")
- else if (hasPackageFlag) ("package", "package", "PK")
- else if (isPackageObject) ("package object", "package", "PKO")
- else if (isPackageObjectClass) ("package object class", "package", "PKOC")
- else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC")
- else if (isRefinementClass) ("refinement class", "", "RC")
- else if (isModule) ("module", "object", "MOD")
- else if (isModuleClass) ("module class", "object", "MODC")
- else if (isGetter) ("getter", if (isSourceMethod) "method" else "value", "GET")
- else if (isSetter) ("setter", if (isSourceMethod) "method" else "value", "SET")
- else if (isTerm && isLazy) ("lazy value", "lazy value", "LAZ")
- else if (isVariable) ("field", "variable", "VAR")
- else if (isTrait) ("trait", "trait", "TRT")
- else if (isClass) ("class", "class", "CLS")
- else if (isType) ("type", "type", "TPE")
- else if (isClassConstructor && (owner.hasCompleteInfo && isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR")
- else if (isClassConstructor) ("constructor", "constructor", "CTOR")
- else if (isSourceMethod) ("method", "method", "METH")
- else if (isTerm) ("value", "value", "VAL")
- else ("", "", "???")
+ if (isTermMacro) ("term macro", "macro method", "MACM")
+ else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE")
+ else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY")
+ else if (isPackageClass) ("package class", "package", "PKC")
+ else if (hasPackageFlag) ("package", "package", "PK")
+ else if (isPackageObject) ("package object", "package", "PKO")
+ else if (isPackageObjectClass) ("package object class", "package", "PKOC")
+ else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC")
+ else if (isRefinementClass) ("refinement class", "", "RC")
+ else if (isModule) ("module", "object", "MOD")
+ else if (isModuleClass) ("module class", "object", "MODC")
+ else if (isAccessor &&
+ !hasFlag(STABLE | LAZY)) ("setter", "variable", "SET")
+ else if (isAccessor && !hasFlag(LAZY)) ("getter", "value", "GET")
+ else if (isTerm && hasFlag(LAZY)) ("lazy value", "lazy value", "LAZ")
+ else if (isVariable) ("field", "variable", "VAR")
+ else if (isTrait) ("trait", "trait", "TRT")
+ else if (isClass) ("class", "class", "CLS")
+ else if (isType) ("type", "type", "TPE")
+ else if (isClassConstructor && (owner.hasCompleteInfo &&
+ isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR")
+ else if (isClassConstructor) ("constructor", "constructor", "CTOR")
+ else if (isMethod) ("method", "method", "METH")
+ else if (isTerm) ("value", "value", "VAL")
+ else ("", "", "???")
+
if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO")
+
SymbolKind(kind._1, kind._2, kind._3)
}
@@ -2623,12 +2622,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* If hasMeaninglessName is true, uses the owner's name to disambiguate identity.
*/
override def toString: String = {
- if (isPackageObjectOrClass && !settings.debug)
- s"package object ${owner.decodedName}"
- else compose(
- kindString,
- if (hasMeaninglessName) owner.decodedName + idString else nameString
- )
+ val simplifyNames = !settings.debug
+ if (isPackageObjectOrClass && simplifyNames) s"package object ${owner.decodedName}"
+ else {
+ val kind = kindString
+ val _name: String =
+ if (hasMeaninglessName) owner.decodedName + idString
+ else if (simplifyNames && (kind == "variable" || kind == "value")) unexpandedName.getterName.decode.toString // TODO: make condition less gross?
+ else nameString
+
+ compose(kind, _name)
+ }
}
/** String representation of location.
@@ -2764,18 +2768,21 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
***/
override def isValueParameter = this hasFlag PARAM
-
override def isSetterParameter = isValueParameter && owner.isSetter
- override def isAccessor = this hasFlag ACCESSOR
- override def isGetter = isAccessor && !isSetter
+
override def isDefaultGetter = name containsName nme.DEFAULT_GETTER_STRING
- override def isSetter = isAccessor && nme.isSetterName(name) // todo: make independent of name, as this can be forged.
+
+ override def isAccessor = this hasFlag ACCESSOR
+ override def isGetter = isAccessor && !nme.isSetterName(name) // TODO: make independent of name, as this can be forged.
+ override def isSetter = isAccessor && nme.isSetterName(name) // TODO: make independent of name, as this can be forged.
+
override def isLocalDummy = nme.isLocalDummyName(name)
+
override def isClassConstructor = name == nme.CONSTRUCTOR
override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR
- override def isConstructor = nme.isConstructorName(name)
+ override def isConstructor = isClassConstructor || isMixinConstructor
- override def isPackageObject = isModule && (name == nme.PACKAGE)
+ override def isPackageObject = isModule && (name == nme.PACKAGE)
// The name in comments is what it is being disambiguated from.
// TODO - rescue CAPTURED from BYNAMEPARAM so we can see all the names.
@@ -2871,7 +2878,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def owner = {
if (Statistics.hotEnabled) Statistics.incCounter(ownerCount)
- // a module symbol may have the lateMETHOD flag after refchecks, see isModuleNotMethod
+ // a non-static module symbol gets the METHOD flag in uncurry's info transform -- see isModuleNotMethod
if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner
}
@@ -2891,38 +2898,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class for method symbols */
class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
extends TermSymbol(initOwner, initPos, initName) with MethodSymbolApi {
- private[this] var mtpePeriod = NoPeriod
- private[this] var mtpePre: Type = _
- private[this] var mtpeResult: Type = _
- private[this] var mtpeInfo: Type = _
-
override def isLabel = this hasFlag LABEL
override def isVarargsMethod = this hasFlag VARARGS
override def isLiftedMethod = this hasFlag LIFTED
- // TODO - this seems a strange definition for "isSourceMethod", given that
- // it does not make any specific effort to exclude synthetics. Figure out what
- // this method is really for and what logic makes sense.
- override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors
+ // TODO: this definition of isSourceMethod makes no sense -- inline it and re-evaluate at each call site.
+ // I'm guessing it meant "method written by user, and not generated by the compiler"
+ // (And then assuming those generated by the compiler don't require certain transformations?)
+ // Use SYNTHETIC/ARTIFACT instead as an indicator? I don't see how it makes sense to only exclude getters.
+ // Note also that trait vals are modelled as getters, and thus that user-supplied code appears in their rhs.
+ // Originally, it may have been an optimization to skip methods that were not user-defined (getters),
+ // but it doesn't even exclude setters, contrary to its original comment (// exclude all accessors)
+ override def isSourceMethod = !(this hasFlag STABLE)
+
// unfortunately having the CASEACCESSOR flag does not actually mean you
// are a case accessor (you can also be a field.)
override def isCaseAccessorMethod = isCaseAccessor
- def typeAsMemberOf(pre: Type): Type = {
- if (mtpePeriod == currentPeriod) {
- if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult
- } else if (isValid(mtpePeriod)) {
- mtpePeriod = currentPeriod
- if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult
- }
- val res = pre.computeMemberType(this)
- mtpePeriod = currentPeriod
- mtpePre = pre
- mtpeInfo = info
- mtpeResult = res
- res
- }
-
override def isVarargs: Boolean = definitions.isVarArgsList(paramss.flatten)
override def returnType: Type = {
@@ -3231,7 +3223,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* returned, otherwise, `NoSymbol` is returned.
*/
protected final def companionModule0: Symbol =
- flatOwnerInfo.decl(name.toTermName).suchThat(sym => sym.isModuleNotMethod && (sym isCoDefinedWith this))
+ flatOwnerInfo.decl(name.toTermName).suchThat(sym => sym.isModule && (sym isCoDefinedWith this))
override def companionModule = companionModule0
override def companionSymbol = companionModule0
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 86b70643c9..b9f3e987ee 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -263,6 +263,12 @@ abstract class TreeInfo {
true
}
+ def isFunctionMissingParamType(tree: Tree): Boolean = tree match {
+ case Function(vparams, _) => vparams.exists(_.tpt.isEmpty)
+ case _ => false
+ }
+
+
/** Is symbol potentially a getter of a variable?
*/
def mayBeVarGetter(sym: Symbol): Boolean = sym.info match {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 895bb60a08..f8679616d1 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -172,11 +172,16 @@ trait Types
trait RewrappingTypeProxy extends SimpleTypeProxy {
protected def maybeRewrap(newtp: Type) = (
if (newtp eq underlying) this
- // BoundedWildcardTypes reach here during erroneous compilation: neg/t6258
- // Higher-kinded exclusion is because [x]CC[x] compares =:= to CC: pos/t3800
- // Otherwise, if newtp =:= underlying, don't rewrap it.
- else if (!newtp.isWildcard && !newtp.isHigherKinded && (newtp =:= underlying)) this
- else rewrap(newtp)
+ else {
+ // - BoundedWildcardTypes reach here during erroneous compilation: neg/t6258
+ // - Higher-kinded exclusion is because [x]CC[x] compares =:= to CC: pos/t3800
+ // - Avoid reusing the existing Wrapped(RefinedType) when we've be asked to wrap an =:= RefinementTypeRef, the
+ // distinction is important in base type sequences. See TypesTest.testExistentialRefinement
+ // - Otherwise, if newtp =:= underlying, don't rewrap it.
+ val hasSpecialMeaningBeyond_=:= = newtp.isWildcard || newtp.isHigherKinded || newtp.isInstanceOf[RefinementTypeRef]
+ if (!hasSpecialMeaningBeyond_=:= && (newtp =:= underlying)) this
+ else rewrap(newtp)
+ }
)
protected def rewrap(newtp: Type): Type
@@ -686,23 +691,21 @@ trait Types
* }}}
*/
def memberInfo(sym: Symbol): Type = {
- require(sym ne NoSymbol, this)
+// assert(sym ne NoSymbol, this)
sym.info.asSeenFrom(this, sym.owner)
}
/** The type of `sym`, seen as a member of this type. */
- def memberType(sym: Symbol): Type = sym match {
- case meth: MethodSymbol =>
- meth.typeAsMemberOf(this)
- case _ =>
- computeMemberType(sym)
- }
-
- def computeMemberType(sym: Symbol): Type = sym.tpeHK match { //@M don't prematurely instantiate higher-kinded types, they will be instantiated by transform, typedTypeApply, etc. when really necessary
- case OverloadedType(_, alts) =>
- OverloadedType(this, alts)
+ def memberType(sym: Symbol): Type = sym.tpeHK match {
+ case OverloadedType(_, alts) => OverloadedType(this, alts)
case tp =>
- if (sym eq NoSymbol) NoType else tp.asSeenFrom(this, sym.owner)
+ // Correct caching is nearly impossible because `sym.tpeHK.asSeenFrom(pre, sym.owner)`
+ // may have different results even for reference-identical `sym.tpeHK` and `pre` (even in the same period).
+ // For example, `pre` could be a `ThisType`. For such a type, `tpThen eq tpNow` does not imply
+ // `tpThen` and `tpNow` mean the same thing, because `tpThen.typeSymbol.info` could have been different
+ // from what it is now, and the cache won't know simply by looking at `pre`.
+ if (sym eq NoSymbol) NoType
+ else tp.asSeenFrom(this, sym.owner)
}
/** Substitute types `to` for occurrences of references to
@@ -1591,13 +1594,11 @@ trait Types
*/
case class RefinedType(override val parents: List[Type],
override val decls: Scope) extends CompoundType with RefinedTypeApi {
-
override def isHigherKinded = (
parents.nonEmpty &&
(parents forall typeIsHigherKinded) &&
!phase.erasedTypes
)
-
override def typeParams =
if (isHigherKinded) firstParent.typeParams
else super.typeParams
@@ -1899,7 +1900,7 @@ trait Types
require(sym.isRefinementClass, sym)
// I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
- override protected def normalizeImpl: Type = sym.info.normalize
+ override protected def normalizeImpl: Type = pre.memberInfo(sym).normalize
override protected def finishPrefix(rest: String) = "" + sym.info
}
@@ -2706,6 +2707,7 @@ trait Types
def isRepresentableWithWildcards = {
val qset = quantified.toSet
underlying match {
+ case _: RefinementTypeRef => false
case TypeRef(pre, sym, args) =>
def isQuantified(tpe: Type): Boolean = {
(tpe exists (t => qset contains t.typeSymbol)) ||
@@ -3471,10 +3473,10 @@ trait Types
if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
else pre.nonPrivateMember(sym.name).suchThat { sym =>
// SI-7928 `isModuleNotMethod` is here to avoid crashing with spuriously "overloaded" module accessor and module symbols.
- // These appear after refchecks eliminates ModuleDefs that implement an interface.
+ // These appear after the fields phase eliminates ModuleDefs that implement an interface.
// Here, we exclude the module symbol, which allows us to bind to the accessor.
- // SI-8054 We must only do this after refchecks, otherwise we exclude the module symbol which does not yet have an accessor!
- val isModuleWithAccessor = phase.refChecked && sym.isModuleNotMethod
+ // SI-8054 We must only do this after fields, otherwise we exclude the module symbol which does not yet have an accessor!
+ val isModuleWithAccessor = phase.assignsFields && sym.isModuleNotMethod
sym.isType || (!isModuleWithAccessor && sym.isStable && !sym.hasVolatileType)
} orElse sym
}
@@ -3523,7 +3525,9 @@ trait Types
if ((parents eq original.parents) && (decls eq original.decls)) original
else {
val owner = original.typeSymbol.owner
- val result = refinedType(parents, owner)
+ val result =
+ if (isIntersectionTypeForLazyBaseType(original)) intersectionTypeForLazyBaseType(parents)
+ else refinedType(parents, owner)
val syms1 = decls.toList
for (sym <- syms1)
result.decls.enter(sym.cloneSymbol(result.typeSymbol))
@@ -3598,6 +3602,14 @@ trait Types
case tp :: Nil => tp
case _ => refinedType(tps, commonOwner(tps))
}
+ def intersectionTypeForLazyBaseType(tps: List[Type]) = tps match {
+ case tp :: Nil => tp
+ case _ => RefinedType(tps, newScope, tps.head.typeSymbolDirect)
+ }
+ def isIntersectionTypeForLazyBaseType(tp: RefinedType) = tp.parents match {
+ case head :: _ => tp.typeSymbolDirect eq head.typeSymbolDirect
+ case _ => false
+ }
/**** This implementation to merge parents was checked in in commented-out
form and has languished unaltered for five years. I think we should
@@ -4405,89 +4417,120 @@ trait Types
finally foreach2(tvs, saved)(_.suspended = _)
}
+ final def stripExistentialsAndTypeVars(ts: List[Type], expandLazyBaseType: Boolean = false): (List[Type], List[Symbol]) = {
+ val needsStripping = ts.exists {
+ case _: RefinedType | _: TypeVar | _: ExistentialType => true
+ case _ => false
+ }
+ if (!needsStripping) (ts, Nil) // fast path for common case
+ else {
+ val tparams = mutable.ListBuffer[Symbol]()
+ val stripped = mutable.ListBuffer[Type]()
+ def stripType(tp: Type): Unit = tp match {
+ case rt: RefinedType if isIntersectionTypeForLazyBaseType(rt) =>
+ if (expandLazyBaseType)
+ rt.parents foreach stripType
+ else {
+ devWarning(s"Unexpected RefinedType in stripExistentialsAndTypeVars $ts, not expanding")
+ stripped += tp
+ }
+ case ExistentialType(qs, underlying) =>
+ tparams ++= qs
+ stripType(underlying)
+ case tv@TypeVar(_, constr) =>
+ if (tv.instValid) stripType(constr.inst)
+ else if (tv.untouchable) stripped += tv
+ else abort("trying to do lub/glb of typevar " + tv)
+ case tp => stripped += tp
+ }
+ ts foreach stripType
+ (stripped.toList, tparams.toList)
+ }
+ }
+
/** Compute lub (if `variance == Covariant`) or glb (if `variance == Contravariant`) of given list
* of types `tps`. All types in `tps` are typerefs or singletypes
* with the same symbol.
* Return `x` if the computation succeeds with result `x`.
* Return `NoType` if the computation fails.
*/
- def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Depth): Type = tps match {
- case tp :: Nil => tp
- case TypeRef(_, sym, _) :: rest =>
- val pres = tps map (_.prefix) // prefix normalizes automatically
+ def mergePrefixAndArgs(tps0: List[Type], variance: Variance, depth: Depth): Type = {
+ val (tps, tparams) = stripExistentialsAndTypeVars(tps0, expandLazyBaseType = true)
+
+ val merged = tps match {
+ case tp :: Nil => tp
+ case TypeRef(_, sym, _) :: rest =>
+ val pres = tps map (_.prefix) // prefix normalizes automatically
val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
- val argss = tps map (_.normalize.typeArgs) // symbol equality (of the tp in tps) was checked using typeSymbol, which normalizes, so should normalize before retrieving arguments
+ val argss = tps map (_.normalize.typeArgs) // symbol equality (of the tp in tps) was checked using typeSymbol, which normalizes, so should normalize before retrieving arguments
val capturedParams = new ListBuffer[Symbol]
- try {
- if (sym == ArrayClass && phase.erasedTypes) {
- // special treatment for lubs of array types after erasure:
- // if argss contain one value type and some other type, the lub is Object
- // if argss contain several reference types, the lub is an array over lub of argtypes
- if (argss exists typeListIsEmpty) {
- NoType // something is wrong: an array without a type arg.
- }
- else {
- val args = argss map (_.head)
- if (args.tail forall (_ =:= args.head)) typeRef(pre, sym, List(args.head))
- else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) ObjectTpe
- else typeRef(pre, sym, List(lub(args)))
+ try {
+ if (sym == ArrayClass && phase.erasedTypes) {
+ // special treatment for lubs of array types after erasure:
+ // if argss contain one value type and some other type, the lub is Object
+ // if argss contain several reference types, the lub is an array over lub of argtypes
+ if (argss exists typeListIsEmpty) {
+ NoType // something is wrong: an array without a type arg.
+ }
+ else {
+ val args = argss map (_.head)
+ if (args.tail forall (_ =:= args.head)) typeRef(pre, sym, List(args.head))
+ else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) ObjectTpe
+ else typeRef(pre, sym, List(lub(args)))
+ }
}
- }
- else transposeSafe(argss) match {
- case None =>
- // transpose freaked out because of irregular argss
- // catching just in case (shouldn't happen, but also doesn't cost us)
- // [JZ] It happens: see SI-5683.
- debuglog(s"transposed irregular matrix!? tps=$tps argss=$argss")
- NoType
- case Some(argsst) =>
- val args = map2(sym.typeParams, argsst) { (tparam, as0) =>
- val as = as0.distinct
- if (as.size == 1) as.head
- else if (depth.isZero) {
- log("Giving up merging args: can't unify %s under %s".format(as.mkString(", "), tparam.fullLocationString))
- // Don't return "Any" (or "Nothing") when we have to give up due to
- // recursion depth. Return NoType, which prevents us from poisoning
- // lublist's results. It can recognize the recursion and deal with it, but
- // only if we aren't returning invalid types.
- NoType
- }
- else {
- if (tparam.variance == variance) lub(as, depth.decr)
- else if (tparam.variance == variance.flip) glb(as, depth.decr)
+ else transposeSafe(argss) match {
+ case None =>
+ // transpose freaked out because of irregular argss
+ // catching just in case (shouldn't happen, but also doesn't cost us)
+ // [JZ] It happens: see SI-5683.
+ debuglog(s"transposed irregular matrix!? tps=$tps argss=$argss")
+ NoType
+ case Some(argsst) =>
+ val args = map2(sym.typeParams, argsst) { (tparam, as0) =>
+ val as = as0.distinct
+ if (as.size == 1) as.head
+ else if (depth.isZero) {
+ log("Giving up merging args: can't unify %s under %s".format(as.mkString(", "), tparam.fullLocationString))
+ // Don't return "Any" (or "Nothing") when we have to give up due to
+ // recursion depth. Return NoType, which prevents us from poisoning
+ // lublist's results. It can recognize the recursion and deal with it, but
+ // only if we aren't returning invalid types.
+ NoType
+ }
else {
- val l = lub(as, depth.decr)
- val g = glb(as, depth.decr)
- if (l <:< g) l
- else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we
- // just err on the conservative side, i.e. with a bound that is too high.
- // if(!(tparam.info.bounds contains tparam)) //@M can't deal with f-bounds, see #2251
-
- val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l)
- capturedParams += qvar
- qvar.tpe
+ if (tparam.variance == variance) lub(as, depth.decr)
+ else if (tparam.variance == variance.flip) glb(as, depth.decr)
+ else {
+ val l = lub(as, depth.decr)
+ val g = glb(as, depth.decr)
+ if (l <:< g) l
+ else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we
+ // just err on the conservative side, i.e. with a bound that is too high.
+ // if(!(tparam.info.bounds contains tparam)) //@M can't deal with f-bounds, see #2251
+
+ val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l)
+ capturedParams += qvar
+ qvar.tpe
+ }
}
}
}
- }
- if (args contains NoType) NoType
- else existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))
+ if (args contains NoType) NoType
+ else existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))
+ }
+ } catch {
+ case ex: MalformedType => NoType
}
- } catch {
- case ex: MalformedType => NoType
- }
- case SingleType(_, sym) :: rest =>
- val pres = tps map (_.prefix)
- val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
- try singleType(pre, sym)
- catch { case ex: MalformedType => NoType }
- case ExistentialType(tparams, quantified) :: rest =>
- mergePrefixAndArgs(quantified :: rest, variance, depth) match {
- case NoType => NoType
- case tpe => existentialAbstraction(tparams, tpe)
- }
- case _ =>
- abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
+ case SingleType(_, sym) :: rest =>
+ val pres = tps map (_.prefix)
+ val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
+ try singleType(pre, sym)
+ catch { case ex: MalformedType => NoType }
+ case _ =>
+ abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
+ }
+ existentialAbstraction(tparams, merged)
}
def addMember(thistp: Type, tp: Type, sym: Symbol): Unit = addMember(thistp, tp, sym, AnyDepth)
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index 24a2f46b75..98b4e881af 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -171,7 +171,9 @@ trait Variances {
case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) =>
validateVariance(sym)
super.traverse(tree)
- // ModuleDefs need not be considered because they have been eliminated already
+ case ModuleDef(_, _, _) =>
+ validateVariance(sym.moduleClass)
+ super.traverse(tree)
case ValDef(_, _, _, _) =>
validateVariance(sym)
case DefDef(_, _, tparams, vparamss, _, _) =>
diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
index 123b44aa05..108ce45cca 100644
--- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
+++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
@@ -118,7 +118,7 @@ private[internal] trait GlbLubs {
// ts0 is the 1-dimensional frontier of symbols cutting through 2-dimensional tsBts.
// Invariant: all symbols "under" (closer to the first row) the frontier
// are smaller (according to _.isLess) than the ones "on and beyond" the frontier
- val ts0 = tsBts map (_.head)
+ val ts0 = tsBts map (_.head)
// Is the frontier made up of types with the same symbol?
val isUniformFrontier = (ts0: @unchecked) match {
@@ -210,24 +210,6 @@ private[internal] trait GlbLubs {
}
}
- private def stripExistentialsAndTypeVars(ts: List[Type]): (List[Type], List[Symbol]) = {
- val quantified = ts flatMap {
- case ExistentialType(qs, _) => qs
- case t => List()
- }
- def stripType(tp: Type): Type = tp match {
- case ExistentialType(_, res) =>
- res
- case tv@TypeVar(_, constr) =>
- if (tv.instValid) stripType(constr.inst)
- else if (tv.untouchable) tv
- else abort("trying to do lub/glb of typevar "+tp)
- case t => t
- }
- val strippedTypes = ts mapConserve stripType
- (strippedTypes, quantified)
- }
-
/** Does this set of types have the same weak lub as
* it does regular lub? This is exposed so lub callers
* can discover whether the trees they are typing will
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index c3f92f1bce..ba4f2bec4b 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -610,11 +610,26 @@ private[internal] trait TypeMaps {
}
// Does the candidate symbol match the given prefix and class?
- // Since pre may be something like ThisType(A) where trait A { self: B => },
- // we have to test the typeSymbol of the widened type, not pre.typeSymbol, or
- // B will not be considered.
- private def matchesPrefixAndClass(pre: Type, clazz: Symbol)(candidate: Symbol) =
- (clazz == candidate) && (pre.widen.typeSymbol isSubClass clazz)
+ private def matchesPrefixAndClass(pre: Type, clazz: Symbol)(candidate: Symbol) = (clazz == candidate) && {
+ val pre1 = pre match {
+ case tv: TypeVar =>
+ // Needed with existentials in prefixes, e.g. test/files/pos/typevar-in-prefix.scala
+ // Perhaps the base type sequence of a type var should include its bounds?
+ tv.origin
+ case _ => pre
+ }
+ // widen needed (at least) because of https://github.com/scala/scala-dev/issues/166
+ (
+ if (clazz.isRefinementClass)
+ // base type seqs of aliases over refinement types have copied refinement types based on beta reduction
+ // for reliable lookup we need to consult the base type of the type symbol. (example: pos/t8177b.scala)
+ pre1.widen.typeSymbol isSubClass clazz
+ else
+ // In the general case, we look at the base type sequence of the prefix itself,
+ // which can have more concrete base classes than `.typeSymbol.baseClasses` (example: t5294, t6161)
+ pre1.widen.baseTypeIndex(clazz) != -1
+ )
+ }
// Whether the annotation tree currently being mapped over has had a This(_) node rewritten.
private[this] var wroteAnnotation = false
@@ -1012,6 +1027,9 @@ private[internal] trait TypeMaps {
case _ =>
tp.normalize match {
case TypeRef(_, sym1, _) if (sym == sym1) => result = true
+ case refined: RefinedType =>
+ mapOver(tp.prefix)
+ mapOver(refined)
case SingleType(_, sym1) if (sym == sym1) => result = true
case _ => mapOver(tp)
}
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 412c49f571..62ca50d035 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -148,9 +148,19 @@ trait Erasure {
apply(atp)
case ClassInfoType(parents, decls, clazz) =>
ClassInfoType(
- if (clazz == ObjectClass || isPrimitiveValueClass(clazz)) Nil
+ if (clazz == ObjectClass || isPrimitiveValueClass(clazz) || parents.isEmpty) Nil
else if (clazz == ArrayClass) ObjectTpe :: Nil
- else removeLaterObjects(parents map this),
+ else {
+ val erasedParents = parents map this
+
+ // drop first parent for traits -- it has been normalized to a class by now,
+ // but we should drop that in bytecode
+ val firstParent =
+ if (clazz.hasFlag(Flags.TRAIT) && !clazz.hasFlag(Flags.JAVA)) ObjectTpe
+ else erasedParents.head
+
+ firstParent :: erasedParents.tail.filter(_.typeSymbol != ObjectClass)
+ },
decls, clazz)
case _ =>
mapOver(tp)
diff --git a/src/reflect/scala/reflect/internal/transform/RefChecks.scala b/src/reflect/scala/reflect/internal/transform/RefChecks.scala
index 4ca114e781..e69de29bb2 100644
--- a/src/reflect/scala/reflect/internal/transform/RefChecks.scala
+++ b/src/reflect/scala/reflect/internal/transform/RefChecks.scala
@@ -1,14 +0,0 @@
-package scala
-package reflect
-package internal
-package transform
-
-trait RefChecks {
-
- val global: SymbolTable
- import global._
-
- def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isModule && !sym.isStatic) NullaryMethodType(tp)
- else tp
-}
diff --git a/src/reflect/scala/reflect/internal/transform/Transforms.scala b/src/reflect/scala/reflect/internal/transform/Transforms.scala
index 0d2f355aa5..de5bfbd39a 100644
--- a/src/reflect/scala/reflect/internal/transform/Transforms.scala
+++ b/src/reflect/scala/reflect/internal/transform/Transforms.scala
@@ -23,12 +23,10 @@ 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
@@ -36,8 +34,7 @@ trait Transforms { self: SymbolTable =>
def transformedType(sym: Symbol) =
postErasure.transformInfo(sym,
erasure.transformInfo(sym,
- uncurry.transformInfo(sym,
- refChecks.transformInfo(sym, sym.info))))
+ uncurry.transformInfo(sym, sym.info)))
def transformedType(tpe: Type) =
postErasure.elimErasedValueType(erasure.scalaErasure(uncurry.uncurry(tpe)))
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
index 85e3ac60e8..a50084f40d 100644
--- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
@@ -83,5 +83,10 @@ trait UnCurry {
* @MAT: starting with this phase, the info of every symbol will be normalized
*/
def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isType) uncurryType(tp) else uncurry(tp)
+ if (sym.isType) uncurryType(tp)
+ else if ((sym hasFlag MODULE) && !sym.isStatic) { // see Fields::nonStaticModuleToMethod
+ sym setFlag METHOD | STABLE
+ MethodType(Nil, uncurry(tp))
+ }
+ else uncurry(tp)
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 0a90a141d3..f55b33959a 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -46,6 +46,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.NoInlineCallsiteAttachment
this.InlineCallsiteAttachment
this.OuterArgCanBeElided
+ this.UseInvokeSpecial
this.noPrint
this.typeDebug
this.Range
@@ -247,7 +248,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.SymbolModule
definitions.StringAddClass
definitions.ScalaNumberClass
- definitions.TraitSetterAnnotationClass
definitions.DelayedInitClass
definitions.TypeConstraintClass
definitions.SingletonClass
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
index 313ec89311..237afa082b 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -199,12 +199,7 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb
trait SynchronizedTermSymbol extends SynchronizedSymbol
- trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol {
- // we can keep this lock fine-grained, because it's just a cache over asSeenFrom, which makes deadlocks impossible
- // unfortunately we cannot elide this lock, because the cache depends on `pre`
- private lazy val typeAsMemberOfLock = new Object
- override def typeAsMemberOf(pre: Type): Type = gilSynchronizedIfNotThreadsafe { typeAsMemberOfLock.synchronized { super.typeAsMemberOf(pre) } }
- }
+ trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol
trait SynchronizedModuleSymbol extends ModuleSymbol with SynchronizedTermSymbol