diff options
Diffstat (limited to 'src/compiler')
7 files changed, 41 insertions, 35 deletions
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 776920ed42..8f5778862d 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 02dd63f011..916b8a3e0c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -858,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 1a53fef4aa..5971782e37 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 } |