summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-14 23:49:53 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-14 23:49:53 +0100
commit465e538ef59171ac7d9e811dbdaec776f8a64ac7 (patch)
tree159f11ee7736daffa1a25abaaca9da49418a7ab6 /src/compiler
parent3dff364399d63c2dd317eb7bdf03f9d5216b2936 (diff)
parente86675f582ed8fef880f71744241f30e0d57a51c (diff)
downloadscala-465e538ef59171ac7d9e811dbdaec776f8a64ac7.tar.gz
scala-465e538ef59171ac7d9e811dbdaec776f8a64ac7.tar.bz2
scala-465e538ef59171ac7d9e811dbdaec776f8a64ac7.zip
Merge remote-tracking branch 'origin/master' into topic/palladium0
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala30
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala26
9 files changed, 70 insertions, 43 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 31733da338..52ddcb154b 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -93,7 +93,7 @@ trait GenSymbols {
// todo. make sure that free methods work correctly
if (sym.isExistential) reifySymDef(sym)
else if (sym.isTerm) reifyFreeTerm(Ident(sym))
- else reifyFreeType(Ident(sym))
+ else reifyFreeType(Ident(sym)) // TODO: reify refinement classes
}
}
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 1098766a07..a82407ea42 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1219,7 +1219,26 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Have we already supplemented the error message of a compiler crash? */
private[nsc] final var supplementedError = false
- private val unitbuf = new mutable.ListBuffer[CompilationUnit]
+ private class SyncedCompilationBuffer { self =>
+ private val underlying = new mutable.ArrayBuffer[CompilationUnit]
+ def size = synchronized { underlying.size }
+ def +=(cu: CompilationUnit): this.type = { synchronized { underlying += cu }; this }
+ def head: CompilationUnit = synchronized{ underlying.head }
+ def apply(i: Int): CompilationUnit = synchronized { underlying(i) }
+ def iterator: Iterator[CompilationUnit] = new collection.AbstractIterator[CompilationUnit] {
+ private var used = 0
+ def hasNext = self.synchronized{ used < underlying.size }
+ def next = self.synchronized {
+ if (!hasNext) throw new NoSuchElementException("next on empty Iterator")
+ used += 1
+ underlying(used-1)
+ }
+ }
+ def toList: List[CompilationUnit] = synchronized{ underlying.toList }
+ }
+
+ private val unitbuf = new SyncedCompilationBuffer
+
val compiledFiles = new mutable.HashSet[String]
/** A map from compiled top-level symbols to their source files */
@@ -1230,9 +1249,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
private var phasec: Int = 0 // phases completed
private var unitc: Int = 0 // units completed this phase
- private var _unitbufSize = 0
- def size = _unitbufSize
+ def size = unitbuf.size
override def toString = "scalac Run for:\n " + compiledFiles.toList.sorted.mkString("\n ")
// Calculate where to stop based on settings -Ystop-before or -Ystop-after.
@@ -1457,7 +1475,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** add unit to be compiled in this run */
private def addUnit(unit: CompilationUnit) {
unitbuf += unit
- _unitbufSize += 1 // counting as they're added so size is cheap
compiledFiles += unit.source.file.path
}
private def checkDeprecatedSettings(unit: CompilationUnit) {
@@ -1473,11 +1490,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/* !!! Note: changing this to unitbuf.toList.iterator breaks a bunch
of tests in tests/res. This is bad, it means the resident compiler
relies on an iterator of a mutable data structure reflecting changes
- made to the underlying structure (in whatever accidental way it is
- currently depending upon.)
+ made to the underlying structure.
*/
def units: Iterator[CompilationUnit] = unitbuf.iterator
-
+
def registerPickle(sym: Symbol): Unit = ()
/** does this run compile given class, module, or case factory? */
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 664645e53e..2f9cc01c0b 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -665,8 +665,11 @@ abstract class ClassfileParser {
// so have to check unsafeTypeParams.isEmpty before worrying about raw type case below,
// or we'll create a boatload of needless existentials.
else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp
- // raw type - existentially quantify all type parameters
- else debuglogResult(s"raw type from $classSym")(unsafeClassExistentialType(classSym))
+ else debuglogResult(s"raw type from $classSym"){
+ // raw type - existentially quantify all type parameters
+ val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams)
+ newExistentialType(eparams, typeRef(pre, classSym, eparams.map(_.tpeHK)))
+ }
case tp =>
assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")
tp
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index b4329965fc..c3fbfae322 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -20,12 +20,16 @@ abstract class Flatten extends InfoTransform {
/** Updates the owning scope with the given symbol, unlinking any others.
*/
private def replaceSymbolInCurrentScope(sym: Symbol): Unit = exitingFlatten {
+ removeSymbolInCurrentScope(sym)
+ sym.owner.info.decls enter sym
+ }
+
+ private def removeSymbolInCurrentScope(sym: Symbol): Unit = exitingFlatten {
val scope = sym.owner.info.decls
val old = (scope lookupUnshadowedEntries sym.name).toList
old foreach (scope unlink _)
- scope enter sym
def old_s = old map (_.sym) mkString ", "
- debuglog(s"In scope of ${sym.owner}, unlinked $old_s and entered $sym")
+ if (old.nonEmpty) debuglog(s"In scope of ${sym.owner}, unlinked $old_s")
}
private def liftClass(sym: Symbol) {
@@ -121,6 +125,8 @@ abstract class Flatten extends InfoTransform {
val liftedBuffer = liftedDefs(tree.symbol.enclosingTopLevelClass.owner)
val index = liftedBuffer.length
liftedBuffer.insert(index, super.transform(tree))
+ if (tree.symbol.sourceModule.isStaticModule)
+ removeSymbolInCurrentScope(tree.symbol.sourceModule)
EmptyTree
case _ =>
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index e4f8d96dd8..0977e8cd4d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -306,7 +306,10 @@ trait Implicits {
*/
object Function1 {
val Sym = FunctionClass(1)
- def unapply(tp: Type) = tp baseType Sym match {
+ // It is tempting to think that this should be inspecting "tp baseType Sym"
+ // rather than tp. See test case run/t8280 and the commit message which
+ // accompanies it for explanation why that isn't done.
+ def unapply(tp: Type) = tp match {
case TypeRef(_, Sym, arg1 :: arg2 :: _) => Some((arg1, arg2))
case _ => None
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 60cae0c880..9b5b0e1f37 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -169,6 +169,13 @@ trait Namers extends MethodSynthesis {
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
debuglog("[overwrite] " + sym)
val newFlags = (sym.flags & LOCKED) | flags
+ sym.rawInfo match {
+ case tr: TypeRef =>
+ // !!! needed for: pos/t5954d; the uniques type cache will happilly serve up the same TypeRef
+ // over this mutated symbol, and we witness a stale cache for `parents`.
+ tr.invalidateCaches()
+ case _ =>
+ }
sym reset NoType setFlag newFlags setPos pos
sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
@@ -457,6 +464,17 @@ trait Namers extends MethodSynthesis {
var m: Symbol = context.scope lookupModule tree.name
val moduleFlags = tree.mods.flags | MODULE
if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) {
+ // This code accounts for the way the package objects found in the classpath are opened up
+ // early by the completer of the package itself. If the `packageobjects` phase then finds
+ // the same package object in sources, we have to clean the slate and remove package object
+ // members from the package class.
+ //
+ // TODO SI-4695 Pursue the approach in https://github.com/scala/scala/pull/2789 that avoids
+ // opening up the package object on the classpath at all if one exists in source.
+ if (m.isPackageObject) {
+ val packageScope = m.enclosingPackageClass.rawInfo.decls
+ packageScope.filter(_.owner != m.enclosingPackageClass).toList.foreach(packageScope unlink _)
+ }
updatePosFlags(m, tree.pos, moduleFlags)
setPrivateWithin(tree, m)
m.moduleClass andAlso (setPrivateWithin(tree, _))
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index 41c656f8ce..cf3f265f0c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -221,10 +221,12 @@ trait PatternTypers {
* see test/files/../t5189*.scala
*/
private def convertToCaseConstructor(tree: Tree, caseClass: Symbol, ptIn: Type): Tree = {
- def untrustworthyPt = (
+ // TODO SI-7886 / SI-5900 This is well intentioned but doesn't quite hit the nail on the head.
+ // For now, I've put it completely behind -Xstrict-inference.
+ val untrustworthyPt = settings.strictInference && (
ptIn =:= AnyTpe
|| ptIn =:= NothingTpe
- || settings.strictInference && ptIn.typeSymbol != caseClass
+ || ptIn.typeSymbol != caseClass
)
val variantToSkolem = new VariantToSkolemMap
val caseClassType = tree.tpe.prefix memberType caseClass
@@ -371,4 +373,4 @@ trait PatternTypers {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 8acc682063..b166bf988d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -467,6 +467,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// overrideError("may not override parameterized type");
// @M: substSym
def checkOverrideAlias() {
+ // Important: first check the pair has the same kind, since the substitution
+ // carries high's type parameter's bounds over to low, so that
+ // type equality doesn't consider potentially different bounds on low/high's type params.
+ // In b781e25afe this went from using memberInfo to memberType (now lowType/highType), tested by neg/override.scala.
+ // TODO: was that the right fix? it seems type alias's RHS should be checked by looking at the symbol's info
if (pair.sameKind && lowType.substSym(low.typeParams, high.typeParams) =:= highType) ()
else overrideTypeError() // (1.6)
}
@@ -853,7 +858,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val baseClass = clazz.info.baseTypeSeq(i).typeSymbol
seenTypes(i) match {
case Nil =>
- println("??? base "+baseClass+" not found in basetypes of "+clazz)
+ devWarning(s"base $baseClass not found in basetypes of $clazz. This might indicate incorrect caching of TypeRef#parents.")
case _ :: Nil =>
;// OK
case tp1 :: tp2 :: _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e13304c6ba..ea8ad0bf42 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1799,32 +1799,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (settings.isScala211 && mdef.symbol == PredefModule)
ensurePredefParentsAreInSameSourceFile(impl2)
- // SI-5954. On second compile of a companion class contained in a package object we end up
- // with some confusion of names which leads to having two symbols with the same name in the
- // same owner. Until that can be straightened out we will warn on companion objects in package
- // objects. But this code also tries to be friendly by distinguishing between case classes and
- // user written companion pairs
- def warnPackageObjectMembers(mdef : ModuleDef) = for (m <- mdef.symbol.info.members) {
- // ignore synthetic objects, because the "companion" object to a case class is synthetic and
- // we only want one error per case class
- if (!m.isSynthetic) {
- // can't handle case classes in package objects
- if (m.isCaseClass) pkgObjectWarning(m, mdef, "case")
- // can't handle companion class/object pairs in package objects
- else if ((m.isClass && m.companionModule != NoSymbol && !m.companionModule.isSynthetic) ||
- (m.isModule && m.companionClass != NoSymbol && !m.companionClass.isSynthetic))
- pkgObjectWarning(m, mdef, "companion")
- }
-
- def pkgObjectWarning(m : Symbol, mdef : ModuleDef, restricted : String) = {
- val pkgName = mdef.symbol.ownerChain find (_.isPackage) map (_.decodedName) getOrElse mdef.symbol.toString
- context.warning(if (m.pos.isDefined) m.pos else mdef.pos, s"${m} should be placed directly in package ${pkgName} instead of package object ${pkgName}. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954.")
- }
- }
-
- if (mdef.symbol.isPackageObject)
- warnPackageObjectMembers(mdef)
-
treeCopy.ModuleDef(mdef, typedMods, mdef.name, impl2) setType NoType
}