diff options
60 files changed, 539 insertions, 164 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 } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 78e639fdff..645d6aa4ff 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -898,12 +898,15 @@ trait Definitions extends api.StandardDefinitions { * * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }. */ + // TODO Review the way this is used. I see two potential problems: + // 1. `existentialAbstraction` here doesn't create fresh existential type symbols, it just + // uses the class type parameter symbols directly as the list of quantified symbols. + // See SI-8244 for the trouble that this can cause. + // Compare with callers of `typeParamsToExistentials` (used in Java raw type handling) + // 2. Why don't we require a prefix? Could its omission lead to wrong results in CheckabilityChecker? def classExistentialType(clazz: Symbol): Type = existentialAbstraction(clazz.typeParams, clazz.tpe_*) - def unsafeClassExistentialType(clazz: Symbol): Type = - existentialAbstraction(clazz.unsafeTypeParams, clazz.tpe_*) - // members of class scala.Any // TODO these aren't final! They are now overriden in AnyRef/Object. Prior to the fix diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 218ad28a03..6010d4eb12 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2103,6 +2103,10 @@ trait Types trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args)) toBoolean(trivial) } + private[scala] def invalidateCaches(): Unit = { + parentsPeriod = NoPeriod + baseTypeSeqPeriod = NoPeriod + } private[reflect] var parentsCache: List[Type] = _ private[reflect] var parentsPeriod = NoPeriod private[reflect] var baseTypeSeqCache: BaseTypeSeq = _ diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index f427813c01..07c9242bf3 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -863,31 +863,24 @@ private[internal] trait TypeMaps { private val existentials = new Array[Symbol](actuals.size) def existentialsNeeded: List[Symbol] = existentials.iterator.filter(_ ne null).toList - private object StableArg { - def unapply(param: Symbol) = Arg unapply param map actuals filter (tp => - tp.isStable && (tp.typeSymbol != NothingClass) - ) - } - private object Arg { - def unapply(param: Symbol) = Some(params indexOf param) filter (_ >= 0) - } - - def apply(tp: Type): Type = mapOver(tp) match { - // unsound to replace args by unstable actual #3873 - case SingleType(NoPrefix, StableArg(arg)) => arg - // (soundly) expand type alias selections on implicit arguments, - // see depmet_implicit_oopsla* test cases -- typically, `param.isImplicit` - case tp1 @ TypeRef(SingleType(NoPrefix, Arg(pid)), sym, targs) => - val arg = actuals(pid) - val res = typeRef(arg, sym, targs) - if (res.typeSymbolDirect.isAliasType) res.dealias else tp1 - // don't return the original `tp`, which may be different from `tp1`, - // due to dropping annotations - case tp1 => tp1 + private object StableArgTp { + // type of actual arg corresponding to param -- if the type is stable + def unapply(param: Symbol): Option[Type] = (params indexOf param) match { + case -1 => None + case pid => + val tp = actuals(pid) + if (tp.isStable && (tp.typeSymbol != NothingClass)) Some(tp) + else None + } } - /* Return the type symbol for referencing a parameter inside the existential quantifier. - * (Only needed if the actual is unstable.) + /** Return the type symbol for referencing a parameter that's instantiated to an unstable actual argument. + * + * To soundly abstract over an unstable value (x: T) while retaining the most type information, + * use `x.type forSome { type x.type <: T with Singleton}` + * `typeOf[T].narrowExistentially(symbolOf[x])`. + * + * See also: captureThis in AsSeenFromMap. */ private def existentialFor(pid: Int) = { if (existentials(pid) eq null) { @@ -900,6 +893,38 @@ private[internal] trait TypeMaps { existentials(pid) } + private object UnstableArgTp { + // existential quantifier and type of corresponding actual arg with unstable type + def unapply(param: Symbol): Option[(Symbol, Type)] = (params indexOf param) match { + case -1 => None + case pid => + val sym = existentialFor(pid) + Some((sym, sym.tpe_*)) // refers to an actual value, must be kind-* + } + } + + private object StabilizedArgTp { + def unapply(param: Symbol): Option[Type] = + param match { + case StableArgTp(tp) => Some(tp) // (1) + case UnstableArgTp(_, tp) => Some(tp) // (2) + case _ => None + } + } + + /** instantiate `param.type` to the (sound approximation of the) type `T` + * of the actual argument `arg` that was passed in for `param` + * + * (1) If `T` is stable, we can just use that. + * + * (2) SI-3873: it'd be unsound to instantiate `param.type` to an unstable `T`, + * so we approximate to `X forSome {type X <: T with Singleton}` -- we can't soundly say more. + */ + def apply(tp: Type): Type = tp match { + case SingleType(NoPrefix, StabilizedArgTp(tp)) => tp + case _ => mapOver(tp) + } + //AM propagate more info to annotations -- this seems a bit ad-hoc... (based on code by spoon) override def mapOver(arg: Tree, giveup: ()=>Nothing): Tree = { // TODO: this should be simplified; in the stable case, one can @@ -922,13 +947,9 @@ private[internal] trait TypeMaps { // Both examples are from run/constrained-types.scala. object treeTrans extends Transformer { override def transform(tree: Tree): Tree = tree.symbol match { - case StableArg(actual) => - gen.mkAttributedQualifier(actual, tree.symbol) - case Arg(pid) => - val sym = existentialFor(pid) - Ident(sym) copyAttrs tree setType typeRef(NoPrefix, sym, Nil) - case _ => - super.transform(tree) + case StableArgTp(tp) => gen.mkAttributedQualifier(tp, tree.symbol) + case UnstableArgTp(quant, tp) => Ident(quant) copyAttrs tree setType tp + case _ => super.transform(tree) } } treeTrans transform arg diff --git a/test/files/neg/package-ob-case.check b/test/files/neg/package-ob-case.check deleted file mode 100644 index 9b0ede1c6d..0000000000 --- a/test/files/neg/package-ob-case.check +++ /dev/null @@ -1,10 +0,0 @@ -package-ob-case.scala:3: warning: it is not recommended to define classes/objects inside of package objects. -If possible, define class X in package foo instead. - case class X(z: Int) { } - ^ -package-ob-case.scala:3: warning: class X should be placed directly in package foo instead of package object foo. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - case class X(z: Int) { } - ^ -error: No warnings can be incurred under -Xfatal-warnings. -two warnings found -one error found diff --git a/test/files/neg/package-ob-case.flags b/test/files/neg/package-ob-case.flags deleted file mode 100644 index 6c1dd108ae..0000000000 --- a/test/files/neg/package-ob-case.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings -Xlint
\ No newline at end of file diff --git a/test/files/neg/t3873.check b/test/files/neg/t3873.check index 54d6abdf63..f9f413aeaf 100644 --- a/test/files/neg/t3873.check +++ b/test/files/neg/t3873.check @@ -1,6 +1,6 @@ t3873.scala:11: error: type mismatch; found : Test.a.B - required: a.B - wrongf(new A)(a.b) // should not compile -- TODO: improve error message? the "a" is ambiguous + required: a.B where val a: A + wrongf(new A)(a.b) // should not compile ^ one error found diff --git a/test/files/neg/t3873.scala b/test/files/neg/t3873.scala index e7815f0937..b27b4e9c9d 100644 --- a/test/files/neg/t3873.scala +++ b/test/files/neg/t3873.scala @@ -8,5 +8,5 @@ object Test { val a = new A wrongf(a)(a.b) - wrongf(new A)(a.b) // should not compile -- TODO: improve error message? the "a" is ambiguous + wrongf(new A)(a.b) // should not compile }
\ No newline at end of file diff --git a/test/files/neg/t4818.check b/test/files/neg/t4818.check index 8a2c024b30..a5e15e456b 100644 --- a/test/files/neg/t4818.check +++ b/test/files/neg/t4818.check @@ -1,6 +1,6 @@ t4818.scala:4: error: type mismatch; found : Int(5) - required: A + required: Nothing def f(x: Any) = x match { case Fn(f) => f(5) } ^ one error found diff --git a/test/files/neg/t5189.check b/test/files/neg/t5189.check index aecc1d11c4..4885de99cd 100644 --- a/test/files/neg/t5189.check +++ b/test/files/neg/t5189.check @@ -1,5 +1,5 @@ t5189.scala:3: error: type mismatch; - found : T => U + found : Nothing => Any required: Any => Any def f(x: Any): Any => Any = x match { case Foo(bar) => bar } ^ diff --git a/test/files/neg/t5760-pkgobj-warn.check b/test/files/neg/t5760-pkgobj-warn.check deleted file mode 100644 index a89398c3f7..0000000000 --- a/test/files/neg/t5760-pkgobj-warn.check +++ /dev/null @@ -1,4 +0,0 @@ -stalepkg_2.scala:6: error: Foo is already defined as class Foo in package object stalepkg - class Foo - ^ -one error found diff --git a/test/files/neg/t5954.check b/test/files/neg/t5954.check deleted file mode 100644 index 3950d14e4e..0000000000 --- a/test/files/neg/t5954.check +++ /dev/null @@ -1,18 +0,0 @@ -t5954.scala:36: warning: class D should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - case class D() - ^ -t5954.scala:35: warning: object C should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - object C - ^ -t5954.scala:34: warning: trait C should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - trait C - ^ -t5954.scala:33: warning: object B should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - object B - ^ -t5954.scala:32: warning: class B should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - class B - ^ -error: No warnings can be incurred under -Xfatal-warnings. -5 warnings found -one error found diff --git a/test/files/neg/t5954.scala b/test/files/neg/t5954.scala deleted file mode 100644 index 3ccb5ed3ff..0000000000 --- a/test/files/neg/t5954.scala +++ /dev/null @@ -1,46 +0,0 @@ -// if you ever think you've fixed the underlying reason for the warning -// imposed by SI-5954, then here's a test that should pass with two "succes"es -// -//import scala.tools.partest._ -// -//object Test extends DirectTest { -// def code = ??? -// -// def problemCode = """ -// package object A { -// class B -// object B -// case class C() -// } -// """ -// -// def compileProblemCode() = { -// val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") -// compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(problemCode) -// } -// -// def show() : Unit = { -// for (i <- 0 until 2) { -// compileProblemCode() -// println(s"success ${i + 1}") -// } -// } -//} - -package object A { - // these should be prevented by the implementation restriction - class B - object B - trait C - object C - case class D() - // all the rest of these should be ok - class E - object F - val g = "omg" - var h = "wtf" - def i = "lol" - type j = String - class K(val k : Int) extends AnyVal - implicit class L(val l : Int) -} diff --git a/test/files/neg/t6680a.flags b/test/files/neg/t6680a.flags new file mode 100644 index 0000000000..19243266d1 --- /dev/null +++ b/test/files/neg/t6680a.flags @@ -0,0 +1 @@ +-Xstrict-inference
\ No newline at end of file diff --git a/test/files/neg/t6829.check b/test/files/neg/t6829.check index a0b43e3b52..914a1c9260 100644 --- a/test/files/neg/t6829.check +++ b/test/files/neg/t6829.check @@ -16,32 +16,32 @@ t6829.scala:49: error: not found: value nextState val (s,a,s2) = (state,actions(agent),nextState) ^ t6829.scala:50: error: type mismatch; - found : s.type (with underlying type T1) + found : s.type (with underlying type Any) required: _53.State where val _53: G val r = rewards(agent).r(s,a,s2) ^ t6829.scala:50: error: type mismatch; - found : a.type (with underlying type T2) + found : a.type (with underlying type Any) required: _53.Action where val _53: G val r = rewards(agent).r(s,a,s2) ^ t6829.scala:50: error: type mismatch; - found : s2.type (with underlying type T3) + found : s2.type (with underlying type Any) required: _53.State where val _53: G val r = rewards(agent).r(s,a,s2) ^ t6829.scala:51: error: type mismatch; - found : s.type (with underlying type T1) + found : s.type (with underlying type Any) required: _50.State agent.learn(s,a,s2,r): G#Agent ^ t6829.scala:51: error: type mismatch; - found : a.type (with underlying type T2) + found : a.type (with underlying type Any) required: _50.Action agent.learn(s,a,s2,r): G#Agent ^ t6829.scala:51: error: type mismatch; - found : s2.type (with underlying type T3) + found : s2.type (with underlying type Any) required: _50.State agent.learn(s,a,s2,r): G#Agent ^ diff --git a/test/files/neg/t7886.check b/test/files/neg/t7886.check deleted file mode 100644 index 338eee9708..0000000000 --- a/test/files/neg/t7886.check +++ /dev/null @@ -1,6 +0,0 @@ -t7886.scala:10: error: type mismatch; - found : Contra[A] - required: Contra[Any] - case Unravel(m, msg) => g(m) - ^ -one error found diff --git a/test/files/neg/t8244.check b/test/files/neg/t8244.check new file mode 100644 index 0000000000..90b2bf6f46 --- /dev/null +++ b/test/files/neg/t8244.check @@ -0,0 +1,4 @@ +Test_2.scala:9: error: value exxx is not a member of ?0 + raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X + ^ +one error found diff --git a/test/files/neg/t8244/Raw_1.java b/test/files/neg/t8244/Raw_1.java new file mode 100644 index 0000000000..0c667f1106 --- /dev/null +++ b/test/files/neg/t8244/Raw_1.java @@ -0,0 +1,4 @@ +public abstract class Raw_1<T>{ + public Raw_1 raw() { return new Raw_1<String>() { public String t() { return ""; } }; } + public abstract T t(); +} diff --git a/test/files/neg/t8244/Test_2.scala b/test/files/neg/t8244/Test_2.scala new file mode 100644 index 0000000000..152bb0b870 --- /dev/null +++ b/test/files/neg/t8244/Test_2.scala @@ -0,0 +1,12 @@ +class X extends Raw_1[X] { + override def t = this + def exxx = 0 +} + +object Test extends App { + def c(s: X) = { + val raw = s.raw + raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X + } + c(new X()) +} diff --git a/test/files/neg/t8244b.check b/test/files/neg/t8244b.check new file mode 100644 index 0000000000..f6cbf99eb5 --- /dev/null +++ b/test/files/neg/t8244b.check @@ -0,0 +1,4 @@ +t8244b.scala:15: error: value exxx is not a member of _$1 + raw.t.exxx + ^ +one error found diff --git a/test/files/neg/t8244b.scala b/test/files/neg/t8244b.scala new file mode 100644 index 0000000000..2fb4f451a1 --- /dev/null +++ b/test/files/neg/t8244b.scala @@ -0,0 +1,18 @@ +class Raw_1[T]{ + def raw(): Raw_1[_] = { new Raw_1[String] { def t() = "" } } + def t(): T +} + + +class X extends Raw_1[X] { + override def t = this + def exxx = 0 +} + +object Test extends App { + def c(s: X) = { + val raw = s.raw + raw.t.exxx + } + c(new X()) +} diff --git a/test/files/neg/t8244c.check b/test/files/neg/t8244c.check new file mode 100644 index 0000000000..fd58a5847c --- /dev/null +++ b/test/files/neg/t8244c.check @@ -0,0 +1,4 @@ +t8244c.scala:15: error: value exxx is not a member of _$1 + raw.t.exxx + ^ +one error found diff --git a/test/files/neg/t8244c.scala b/test/files/neg/t8244c.scala new file mode 100644 index 0000000000..2fb4f451a1 --- /dev/null +++ b/test/files/neg/t8244c.scala @@ -0,0 +1,18 @@ +class Raw_1[T]{ + def raw(): Raw_1[_] = { new Raw_1[String] { def t() = "" } } + def t(): T +} + + +class X extends Raw_1[X] { + override def t = this + def exxx = 0 +} + +object Test extends App { + def c(s: X) = { + val raw = s.raw + raw.t.exxx + } + c(new X()) +} diff --git a/test/files/neg/t8244e.check b/test/files/neg/t8244e.check new file mode 100644 index 0000000000..ebd74036e5 --- /dev/null +++ b/test/files/neg/t8244e.check @@ -0,0 +1,4 @@ +Test.scala:9: error: value exxx is not a member of ?0 + raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X + ^ +one error found diff --git a/test/files/neg/t8244e/Raw.java b/test/files/neg/t8244e/Raw.java new file mode 100644 index 0000000000..53202e319d --- /dev/null +++ b/test/files/neg/t8244e/Raw.java @@ -0,0 +1,4 @@ +public abstract class Raw<T>{ + public Raw raw() { return new Raw<String>() { public String t() { return ""; } }; } + public abstract T t(); +} diff --git a/test/files/neg/t8244e/Test.scala b/test/files/neg/t8244e/Test.scala new file mode 100644 index 0000000000..ca2a90583f --- /dev/null +++ b/test/files/neg/t8244e/Test.scala @@ -0,0 +1,12 @@ +class X extends Raw[X] { + override def t = this + def exxx = 0 +} + +object Test extends App { + def c(s: X) = { + val raw = s.raw + raw.t.exxx // java.lang.ClassCastException: java.lang.String cannot be cast to X + } + c(new X()) +} diff --git a/test/files/neg/t5954.flags b/test/files/pos/package-ob-case.flags index 85d8eb2ba2..85d8eb2ba2 100644 --- a/test/files/neg/t5954.flags +++ b/test/files/pos/package-ob-case.flags diff --git a/test/files/neg/package-ob-case.scala b/test/files/pos/package-ob-case/A_1.scala index 91a1fb7e48..91a1fb7e48 100644 --- a/test/files/neg/package-ob-case.scala +++ b/test/files/pos/package-ob-case/A_1.scala diff --git a/test/files/pos/package-ob-case/B_2.scala b/test/files/pos/package-ob-case/B_2.scala new file mode 100644 index 0000000000..91a1fb7e48 --- /dev/null +++ b/test/files/pos/package-ob-case/B_2.scala @@ -0,0 +1,5 @@ +package foo { + package object foo { + case class X(z: Int) { } + } +} diff --git a/test/files/pos/t1786-cycle.scala b/test/files/pos/t1786-cycle.scala new file mode 100644 index 0000000000..af5d892c6a --- /dev/null +++ b/test/files/pos/t1786-cycle.scala @@ -0,0 +1,57 @@ +trait GenTraversableLike[+A, +Repr] extends Any + +object O { + (null: Any) match { + case _: LongTraversableLike[_] => + } +} + +trait LongTraversable extends LongTraversableLike[LongTraversable] + +trait LongTraversableLike[+Repr <: LongTraversableLike[Repr]] extends GenTraversableLike[Any, Repr] + +/* +% scalac-hash v2.11.0-M8 test/files/pos/t1786-cycle.scala +[warn] v2.11.0-M8 failed, using closest available +test/files/pos/t1786-cycle.scala:11: error: illegal cyclic reference involving trait LongTraversableLike +trait LongTraversableLike[+Repr <: LongTraversableLike[Repr]] extends GenTraversableLike[Any, Repr] + ^ +one error found + +Okay again after SI-1786 was reverted. + + +|-- object O BYVALmode-EXPRmode (site: package <empty>) +| |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in O) +| | |-- this EXPRmode (silent: <init> in O) +| | | \-> O.type +| | \-> O.type +| |-- (null: Any) match { case (_: LongTraversableLike[(_ @ <em... BYVALmode-EXPRmode (site: value <local O> in O) +| | |-- (null: Any) BYVALmode-EXPRmode (site: value <local O> in O) +| | | |-- Any TYPEmode (site: value <local O> in O) +| | | | \-> Any +| | | |-- null : pt=Any EXPRmode (site: value <local O> in O) +| | | | \-> Null(null) +| | | \-> Any +| | |-- (_: LongTraversableLike[(_ @ <empty>)]) : pt=Any PATTERNmode (site: value <local O> in O) enrichment only +| | | |-- LongTraversableLike[(_ @ <empty>)] TYPEPATmode-TYPEmode (site: value <local O> in O) enrichment only +| | | | |-- <: LongTraversableLike[Repr] TYPEmode (site: type Repr in <empty>) +| | | | | |-- LongTraversableLike[Repr] TYPEmode (site: type Repr in <empty>) +| | | | | | |-- Repr NOmode (site: type Repr in <empty>) +| | | | | | | \-> Repr +| | | | | | \-> LongTraversableLike[Repr] +| | | | | [adapt] <: LongTraversableLike[Repr] is now a TypeTree( <: LongTraversableLike[Repr]) +| | | | | \-> <: LongTraversableLike[Repr] +| | | | |-- (_ @ <empty>) TYPEPATmode-TYPEmode (site: value <local O> in O) enrichment only +| | | | | \-> _ +| | | | |-- GenTraversableLike FUNmode-TYPEmode (site: trait LongTraversableLike) +| | | | | \-> GenTraversableLike +| | | | |-- GenTraversableLike[Any, Repr] TYPEmode (site: trait LongTraversableLike) +| | | | | |-- Any TYPEmode (site: trait LongTraversableLike) +| | | | | | \-> Any +| | | | | |-- Repr TYPEmode (site: trait LongTraversableLike) +| | | | | | \-> Repr +| | | | | caught scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving trait LongTraversableLike: while typing GenTraversableLike[Any, Repr] +test/files/pos/t1786-cycle.scala:11: error: illegal cyclic reference involving trait LongTraversableLike +trait LongTraversableLike[+Repr <: LongTraversableLike[Repr]] extends GenT +*/
\ No newline at end of file diff --git a/test/files/neg/t5760-pkgobj-warn/stalepkg_1.scala b/test/files/pos/t5760-pkgobj-warn/stalepkg_1.scala index ed4b731bb0..ed4b731bb0 100644 --- a/test/files/neg/t5760-pkgobj-warn/stalepkg_1.scala +++ b/test/files/pos/t5760-pkgobj-warn/stalepkg_1.scala diff --git a/test/files/neg/t5760-pkgobj-warn/stalepkg_2.scala b/test/files/pos/t5760-pkgobj-warn/stalepkg_2.scala index 9abcdbab17..9abcdbab17 100644 --- a/test/files/neg/t5760-pkgobj-warn/stalepkg_2.scala +++ b/test/files/pos/t5760-pkgobj-warn/stalepkg_2.scala diff --git a/test/files/pos/t5900a.scala b/test/files/pos/t5900a.scala new file mode 100644 index 0000000000..cb02f67fb2 --- /dev/null +++ b/test/files/pos/t5900a.scala @@ -0,0 +1,9 @@ +case class Transition[S](x: S) + +object C + +object Test { + (??? : Any) match { + case Transition(C) => + } +} diff --git a/test/files/pos/t5954a/A_1.scala b/test/files/pos/t5954a/A_1.scala new file mode 100644 index 0000000000..10ead0b1ca --- /dev/null +++ b/test/files/pos/t5954a/A_1.scala @@ -0,0 +1,6 @@ +package p1 { + object `package` { + implicit class Foo(a: Any) + object Foo + } +} diff --git a/test/files/pos/t5954a/B_2.scala b/test/files/pos/t5954a/B_2.scala new file mode 100644 index 0000000000..10ead0b1ca --- /dev/null +++ b/test/files/pos/t5954a/B_2.scala @@ -0,0 +1,6 @@ +package p1 { + object `package` { + implicit class Foo(a: Any) + object Foo + } +} diff --git a/test/files/pos/t5954b/A_1.scala b/test/files/pos/t5954b/A_1.scala new file mode 100644 index 0000000000..8465e8f8c6 --- /dev/null +++ b/test/files/pos/t5954b/A_1.scala @@ -0,0 +1,6 @@ +package p { + package object base { + class B + object B + } +} diff --git a/test/files/pos/t5954b/B_2.scala b/test/files/pos/t5954b/B_2.scala new file mode 100644 index 0000000000..f7e4704b3e --- /dev/null +++ b/test/files/pos/t5954b/B_2.scala @@ -0,0 +1,5 @@ +package p { + package object base { + case class B() + } +} diff --git a/test/files/pos/t5954c.flags b/test/files/pos/t5954c.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/pos/t5954c.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/pos/t5954c/A_1.scala b/test/files/pos/t5954c/A_1.scala new file mode 100644 index 0000000000..29ad9547a2 --- /dev/null +++ b/test/files/pos/t5954c/A_1.scala @@ -0,0 +1,18 @@ +package object A { + // these used to should be prevented by the implementation restriction + // but are now allowed + class B + object B + trait C + object C + case class D() + // all the rest of these should be ok + class E + object F + val g = "omg" + var h = "wtf" + def i = "lol" + type j = String + class K(val k : Int) extends AnyVal + implicit class L(val l : Int) +} diff --git a/test/files/pos/t5954c/B_2.scala b/test/files/pos/t5954c/B_2.scala new file mode 100644 index 0000000000..29ad9547a2 --- /dev/null +++ b/test/files/pos/t5954c/B_2.scala @@ -0,0 +1,18 @@ +package object A { + // these used to should be prevented by the implementation restriction + // but are now allowed + class B + object B + trait C + object C + case class D() + // all the rest of these should be ok + class E + object F + val g = "omg" + var h = "wtf" + def i = "lol" + type j = String + class K(val k : Int) extends AnyVal + implicit class L(val l : Int) +} diff --git a/test/files/pos/t5954d.flags b/test/files/pos/t5954d.flags new file mode 100644 index 0000000000..6ced0e7090 --- /dev/null +++ b/test/files/pos/t5954d.flags @@ -0,0 +1 @@ +-Xfatal-warnings -Xdev diff --git a/test/files/pos/t5954d/A_1.scala b/test/files/pos/t5954d/A_1.scala new file mode 100644 index 0000000000..8465e8f8c6 --- /dev/null +++ b/test/files/pos/t5954d/A_1.scala @@ -0,0 +1,6 @@ +package p { + package object base { + class B + object B + } +} diff --git a/test/files/pos/t5954d/B_2.scala b/test/files/pos/t5954d/B_2.scala new file mode 100644 index 0000000000..a4aa2eb587 --- /dev/null +++ b/test/files/pos/t5954d/B_2.scala @@ -0,0 +1,7 @@ +package p { + trait T { + class B + object B + } + package object base extends T +} diff --git a/test/files/pos/t7753.scala b/test/files/pos/t7753.scala new file mode 100644 index 0000000000..93ad23f114 --- /dev/null +++ b/test/files/pos/t7753.scala @@ -0,0 +1,36 @@ +import scala.language.{ higherKinds, implicitConversions } + +trait Foo { type Out } + +trait SI { + val instance: Foo + type Out +} + +object Test { + def test { + def indirect(si: SI)(v: si.instance.Out) = v + + val foo: Foo { type Out = Int } = ??? + def conv(i: Foo): SI { type Out = i.Out; val instance: i.type } = ??? + + val converted = conv(foo) + + val v1: Int = indirect(converted)(23) // Okay (after refining the return type `instance` in the return type of `conv`) + /* + indirect(converted){(v: converted.instance.Out)converted.instance.Out}( + 23{Int(23)} + ){converted.instance.Out}; + */ + + val v2: Int = indirect(conv(foo))(23) // Used to fail as follows: + /* + indirect( + conv(foo){si.SI{type Out = foo.Out; val instance: si.Test.<refinement>.type}} + ){(v: si.instance.Out)si.instance.Out}( + 23{<error>} + ){<error>}; + */ + + } +} diff --git a/test/files/pos/t8134/A_1.scala b/test/files/pos/t8134/A_1.scala new file mode 100644 index 0000000000..32bce003fb --- /dev/null +++ b/test/files/pos/t8134/A_1.scala @@ -0,0 +1,4 @@ +// a.scala +package object pkg { + class AnyOps(val x: Any) extends AnyVal +} diff --git a/test/files/pos/t8134/B_2.scala b/test/files/pos/t8134/B_2.scala new file mode 100644 index 0000000000..32bce003fb --- /dev/null +++ b/test/files/pos/t8134/B_2.scala @@ -0,0 +1,4 @@ +// a.scala +package object pkg { + class AnyOps(val x: Any) extends AnyVal +} diff --git a/test/files/pos/t8223.scala b/test/files/pos/t8223.scala new file mode 100644 index 0000000000..52d6b0098e --- /dev/null +++ b/test/files/pos/t8223.scala @@ -0,0 +1,29 @@ +package p { + class ViewEnv[AIn] { + type A = AIn + class SubView { def has(x: A): Boolean = ??? } + def get: SubView = new SubView + } + + trait HasA { type A } + trait Indexable[R] extends HasA + class ArrayTC[AIn] extends Indexable[Array[AIn]] { type A = AIn } +} + +package object p { + implicit def arrayTypeClass[A] : ArrayTC[A] = new ArrayTC[A] + object intArrayTC extends ArrayTC[Int] + + type EnvAlias[W <: HasA] = ViewEnv[W#A] + type SubAlias[W <: HasA] = ViewEnv[W#A]#SubView + + def f0[R](xs: R)(implicit tc: Indexable[R]): ViewEnv[tc.A]#SubView = new ViewEnv[tc.A]() get + def f1[R](xs: R)(implicit tc: Indexable[R]): EnvAlias[tc.type]#SubView = new ViewEnv[tc.A]() get + def f2[R](xs: R)(implicit tc: Indexable[R]): SubAlias[tc.type] = new ViewEnv[tc.A]() get + + def g0 = f0(Array(1)) has 2 // ok + def g1 = f1(Array(1)) has 2 // ok + def g2 = f2(Array(1)) has 2 // "found: Int(2), required: tc.A" + def g3 = f2(Array(1))(new ArrayTC[Int]) has 2 // "found: Int(2), required: tc.A" + def g4 = f2(Array(1))(intArrayTC) has 2 // ok +} diff --git a/test/files/pos/t8244d/InodeBase_1.java b/test/files/pos/t8244d/InodeBase_1.java new file mode 100644 index 0000000000..36c2123418 --- /dev/null +++ b/test/files/pos/t8244d/InodeBase_1.java @@ -0,0 +1,6 @@ +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +abstract class INodeBase_1<K, V> { + @SuppressWarnings("rawtypes") + public static final AtomicReferenceFieldUpdater<INodeBase_1, Object> updater = null; +} diff --git a/test/files/pos/t8244d/Test_2.scala b/test/files/pos/t8244d/Test_2.scala new file mode 100644 index 0000000000..cb39c9692c --- /dev/null +++ b/test/files/pos/t8244d/Test_2.scala @@ -0,0 +1,3 @@ +class INodeX[K, V] extends INodeBase_1[K, V] { + INodeBase_1.updater.set(this, null) +} diff --git a/test/files/run/t8280.check b/test/files/run/t8280.check new file mode 100644 index 0000000000..ed392841c7 --- /dev/null +++ b/test/files/run/t8280.check @@ -0,0 +1,9 @@ +Int +Int +Int +Int +Int +Int +Int +Int +Int diff --git a/test/files/run/t8280.scala b/test/files/run/t8280.scala new file mode 100644 index 0000000000..0734d63b6e --- /dev/null +++ b/test/files/run/t8280.scala @@ -0,0 +1,82 @@ +import scala.language.implicitConversions + +object Test { + def main(args: Array[String]): Unit = { + Moop1.ob1 + Moop1.ob2 + Moop1.ob3 + Moop2.ob1 + Moop2.ob2 + Moop2.ob3 + Moop3.ob1 + Moop3.ob2 + Moop3.ob3 + } +} + +// int object vs. +object Moop1 { + object ob1 { + implicit object f1 extends (Int => String) { def apply(x: Int): String = "Int" } + implicit object f2 extends (Long => String) { def apply(x: Long): String = "Long" } + + println(5: String) + } + object ob2 { + implicit object f1 extends (Int => String) { def apply(x: Int): String = "Int" } + implicit def f2(x: Long): String = "Long" + + println(5: String) + } + object ob3 { + implicit object f1 extends (Int => String) { def apply(x: Int): String = "Int" } + implicit val f2: Long => String = _ => "Long" + + println(5: String) + } +} + +// int def vs. +object Moop2 { + object ob1 { + implicit def f1(x: Int): String = "Int" + implicit object f2 extends (Long => String) { def apply(x: Long): String = "Long" } + + println(5: String) + } + object ob2 { + implicit def f1(x: Int): String = "Int" + implicit def f2(x: Long): String = "Long" + + println(5: String) + } + object ob3 { + implicit def f1(x: Int): String = "Int" + implicit val f2: Long => String = _ => "Long" + + println(5: String) + } +} + +// int val vs. +object Moop3 { + object ob1 { + implicit val f1: Int => String = _ => "Int" + implicit object f2 extends (Long => String) { def apply(x: Long): String = "Long" } + + println(5: String) + } + object ob2 { + implicit val f1: Int => String = _ => "Int" + implicit def f2(x: Long): String = "Long" + + println(5: String) + } + object ob3 { + implicit val f1: Int => String = _ => "Int" + implicit val f2: Long => String = _ => "Long" + + println(5: String) + } +} + diff --git a/test/files/neg/t7886.scala b/test/pending/neg/t7886.scala index 55d80a0a43..55d80a0a43 100644 --- a/test/files/neg/t7886.scala +++ b/test/pending/neg/t7886.scala diff --git a/test/pending/neg/t7886b.scala b/test/pending/neg/t7886b.scala new file mode 100644 index 0000000000..1db8be9821 --- /dev/null +++ b/test/pending/neg/t7886b.scala @@ -0,0 +1,23 @@ +trait Covariant[+A] +trait Contra[-A] { def accept(p: A): Unit } +trait Invariant[A] extends Covariant[A] with Contra[A] + +trait T +case class Unravel[A](m: Contra[A], msg: A) extends T + +object Test extends Covariant[Any] { + def g(m: Contra[Any]): Unit = m accept 5 + def f(x: T): Unit = x match { + case Unravel(m, msg) => g(m) + case _ => + } + def main(args: Array[String]) { + f(Unravel[String](new Contra[String] { def accept(x: String) = x.length }, "")) + } +} +// java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String +// at Test$$anon$1.accept(a.scala:18) +// at Test$.g(a.scala:13) +// at Test$.f(a.scala:15) +// at Test$.main(a.scala:18) +// at Test.main(a.scala) diff --git a/test/files/pos/pattern-typing.scala b/test/pending/pos/pattern-typing.scala index 7286cc38af..7286cc38af 100644 --- a/test/files/pos/pattern-typing.scala +++ b/test/pending/pos/pattern-typing.scala |