diff options
224 files changed, 2224 insertions, 873 deletions
@@ -1930,7 +1930,7 @@ DISTRIBUTION </target> <target name="dist.latest.unix" depends="dist.src" unless="os.win"> - <symlink link="${dists.dir}/latest" resource="${dist.dir}" overwrite="yes"/> + <symlink link="${dists.dir}/latest" resource="${dist.name}" overwrite="yes"/> </target> <target name="dist.latest.win" depends="dist.src" if="os.win"> diff --git a/lib/forkjoin.jar.desired.sha1 b/lib/forkjoin.jar.desired.sha1 index b8c48df830..d37b84d8c7 100644 --- a/lib/forkjoin.jar.desired.sha1 +++ b/lib/forkjoin.jar.desired.sha1 @@ -1 +1 @@ -e29a62ba3abe56ba004b344e22be86dbeb12176f ?forkjoin.jar +996fc132b05046112b9d4dc62e2d2c9057d836bc ?forkjoin.jar diff --git a/lib/msil.jar.desired.sha1 b/lib/msil.jar.desired.sha1 index 7dd6b5d66b..2c2fe79dda 100644 --- a/lib/msil.jar.desired.sha1 +++ b/lib/msil.jar.desired.sha1 @@ -1 +1 @@ -58f64cd00399c724e7d526e5bdcbce3e2b79f78b ?msil.jar +d48cb950ceded82a5e0ffae8ef2c68d0923ed00c ?msil.jar diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 2a56ab3880..0bbbea1e7b 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -797b3233ce29c4c565118742160c6c5c08800b94 ?scala-compiler.jar +f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index b187227638..51704e29c9 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -dab2f9528a6135e2026650a86eea7aea542515f9 ?scala-library-src.jar +d407ee67fa7e0d79e8e5786fb32ea7c9bdf5b088 ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index a1c2895ff9..703eb006da 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -c294c9d88e1b65320caf21fc96b65b11785cb381 ?scala-library.jar +1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar diff --git a/src/android-library/scala/ScalaObject.scala b/src/android-library/scala/ScalaObject.scala deleted file mode 100644 index f44116d1ce..0000000000 --- a/src/android-library/scala/ScalaObject.scala +++ /dev/null @@ -1,13 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala - -trait ScalaObject extends AnyRef diff --git a/src/build/genprod.scala b/src/build/genprod.scala index cce00321df..6016f6fb92 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -608,7 +608,7 @@ object {className} {{ /** {className} is a cartesian product of {i} component{s}. * @since 2.3 */ -trait {className}{covariantArgs} extends Product {{ +trait {className}{covariantArgs} extends Any with Product {{ /** The arity of this product. * @return {i} */ diff --git a/src/build/pack.xml b/src/build/pack.xml index 90aec8e25b..1b0cf19151 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -299,7 +299,7 @@ MAIN DISTRIBUTION SBAZ <target name="pack-maven.latest.unix" depends="pack-maven.docs" unless="os.win"> <symlink link="${dists.dir}/maven/latest" - resource="${dists.dir}/maven/${version.number}" + resource="${version.number}" overwrite="yes"/> </target> diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index ec171c5f2c..1d53b83b75 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -22,15 +22,17 @@ trait Definitions extends reflect.api.StandardDefinitions { */ private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type) - private def newClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = { + private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = { val clazz = owner.newClassSymbol(name, NoPosition, flags) clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz) } private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = { val msym = owner.newMethod(name.encode, NoPosition, flags) val params = msym.newSyntheticValueParams(formals) - msym setInfoAndEnter MethodType(params, restpe) + msym setInfo MethodType(params, restpe) } + private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = + owner.info.decls enter newMethod(owner, name, formals, restpe, flags) // the scala value classes trait ValueClassDefinitions { @@ -101,7 +103,6 @@ trait Definitions extends reflect.api.StandardDefinitions { def isGetClass(sym: Symbol) = (sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty) - lazy val AnyValClass = valueCache(tpnme.AnyVal) lazy val UnitClass = valueCache(tpnme.Unit) lazy val ByteClass = valueCache(tpnme.Byte) lazy val ShortClass = valueCache(tpnme.Short) @@ -205,8 +206,20 @@ trait Definitions extends reflect.api.StandardDefinitions { case _ => null } + private def fixupAsAnyTrait(tpe: Type): Type = tpe match { + case ClassInfoType(parents, decls, clazz) => + if (parents.head.typeSymbol == AnyClass) tpe + else { + assert(parents.head.typeSymbol == ObjectClass, parents) + ClassInfoType(AnyClass.tpe :: parents.tail, decls, clazz) + } + case PolyType(tparams, restpe) => + PolyType(tparams, fixupAsAnyTrait(restpe)) +// case _ => tpe + } + // top types - lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) + lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor) lazy val ObjectClass = getClass(sn.Object) @@ -216,6 +229,14 @@ trait Definitions extends reflect.api.StandardDefinitions { @deprecated("Use AnyRefModule", "2.10.0") def Predef_AnyRef = AnyRefModule + lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse { + val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT) + val av_constr = anyval.newClassConstructor(NoPosition) + anyval.info.decls enter av_constr + anyval + } + lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe)) + // bottom types lazy val RuntimeNothingClass = getClass(fulltpnme.RuntimeNothing) lazy val RuntimeNullClass = getClass(fulltpnme.RuntimeNull) @@ -248,7 +269,6 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val UninitializedErrorClass = getRequiredClass("scala.UninitializedFieldError") // fundamental reference classes - lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject) lazy val PartialFunctionClass = getRequiredClass("scala.PartialFunction") lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction") lazy val SymbolClass = getRequiredClass("scala.Symbol") @@ -319,10 +339,10 @@ trait Definitions extends reflect.api.StandardDefinitions { // .setInfo(UnitClass.tpe) lazy val TypeConstraintClass = getRequiredClass("scala.annotation.TypeConstraint") - lazy val SingletonClass = newClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL) + lazy val SingletonClass = enterNewClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL) lazy val SerializableClass = getRequiredClass("scala.Serializable") - lazy val JavaSerializableClass = getClass(sn.JavaSerializable) - lazy val ComparableClass = getRequiredClass("java.lang.Comparable") + lazy val JavaSerializableClass = getClass(sn.JavaSerializable) modifyInfo fixupAsAnyTrait + lazy val ComparableClass = getRequiredClass("java.lang.Comparable") modifyInfo fixupAsAnyTrait lazy val JavaCloneableClass = getRequiredClass("java.lang.Cloneable") lazy val RemoteInterfaceClass = getRequiredClass("java.rmi.Remote") lazy val RemoteExceptionClass = getRequiredClass("java.rmi.RemoteException") @@ -351,7 +371,7 @@ trait Definitions extends reflect.api.StandardDefinitions { } def isPrimitiveArray(tp: Type) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => isValueClass(arg.typeSymbol) + case TypeRef(_, ArrayClass, arg :: Nil) => isPrimitiveValueClass(arg.typeSymbol) case _ => false } def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match { @@ -660,12 +680,12 @@ trait Definitions extends reflect.api.StandardDefinitions { } // members of class scala.Any - lazy val Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL) - lazy val Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype, FINAL) - lazy val Any_equals = newMethod(AnyClass, nme.equals_, anyparam, booltype) - lazy val Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype) - lazy val Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype) - lazy val Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL) + lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL) + lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, anyparam, booltype, FINAL) + lazy val Any_equals = enterNewMethod(AnyClass, nme.equals_, anyparam, booltype) + lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, inttype) + lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, stringtype) + lazy val Any_## = enterNewMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL) // Any_getClass requires special handling. The return type is determined on // a per-call-site basis as if the function being called were actually: @@ -676,22 +696,89 @@ trait Definitions extends reflect.api.StandardDefinitions { // Since getClass is not actually a polymorphic method, this requires compiler // participation. At the "Any" level, the return type is Class[_] as it is in // java.lang.Object. Java also special cases the return type. - lazy val Any_getClass = newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED) + lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED) lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype) lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) + // A type function from T => Class[U], used to determine the return + // type of getClass calls. The returned type is: + // + // 1. If T is a value type, Class[T]. + // 2. If T is a phantom type (Any or AnyVal), Class[_]. + // 3. If T is a local class, Class[_ <: |T|]. + // 4. Otherwise, Class[_ <: T]. + // + // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the + // receiver is AnyVal, it implies the receiver is boxed, so the correct + // class object is that of java.lang.Integer, not Int. + // + // TODO: If T is final, return type could be Class[T]. Should it? + def getClassReturnType(tp: Type): Type = { + val sym = tp.typeSymbol + + if (phase.erasedTypes) ClassClass.tpe + else if (isPrimitiveValueClass(sym)) ClassType(tp.widen) + else { + val eparams = typeParamsToExistentials(ClassClass, ClassClass.typeParams) + val upperBound = ( + if (isPhantomClass(sym)) AnyClass.tpe + else if (sym.isLocalClass) erasure.intersectionDominator(tp.parents) + else tp.widen + ) + + existentialAbstraction( + eparams, + ClassType(eparams.head setInfo TypeBounds.upper(upperBound) tpe) + ) + } + } + + /** 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 + case x :: xs => + if (x.typeSymbol == ObjectClass) + x :: xs.filterNot(_.typeSymbol == ObjectClass) + else + x :: removeRedundantObjects(xs) + } + /** Order a list of types with non-trait classes before others. */ + def classesFirst(tps: List[Type]): List[Type] = { + val (classes, others) = tps partition (t => t.typeSymbol.isClass && !t.typeSymbol.isTrait) + if (classes.isEmpty || others.isEmpty || (tps startsWith classes)) tps + else classes ::: others + } + /** The following transformations applied to a list of parents. + * If any parent is a class/trait, all parents which normalize to + * Object are discarded. Otherwise, all parents which normalize + * to Object except the first one found are discarded. + */ + def normalizedParents(parents: List[Type]): List[Type] = { + if (parents exists (t => (t.typeSymbol ne ObjectClass) && t.typeSymbol.isClass)) + parents filterNot (_.typeSymbol eq ObjectClass) + else + removeRedundantObjects(parents) + } + def parentsString(parents: List[Type]) = + normalizedParents(parents) mkString " with " + // members of class java.lang.{ Object, String } - lazy val Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL) - lazy val Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL) - lazy val Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL) - lazy val Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL) - lazy val Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL) + lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL) + lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL) + lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL) + lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL) + lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL) lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC)(_ => booltype) lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(_.typeConstructor) lazy val Object_synchronized = newPolyMethod(1, ObjectClass, nme.synchronized_, FINAL)(tps => (Some(List(tps.head.typeConstructor)), tps.head.typeConstructor) ) - lazy val String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL) + lazy val String_+ = enterNewMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL) def Object_getClass = getMember(ObjectClass, nme.getClass_) def Object_clone = getMember(ObjectClass, nme.clone_) @@ -776,7 +863,7 @@ trait Definitions extends reflect.api.StandardDefinitions { ) lazy val AnnotationDefaultAttr: Symbol = { - val attr = newClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor)) + val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor)) // This attribute needs a constructor so that modifiers in parsed Java code make sense attr.info.decls enter attr.newClassConstructor(NoPosition) attr @@ -853,11 +940,11 @@ trait Definitions extends reflect.api.StandardDefinitions { owner.newAliasType(name) setInfoAndEnter alias private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): Symbol = { - val clazz = newClass(ScalaPackageClass, name, Nil) + val clazz = enterNewClass(ScalaPackageClass, name, Nil) val tparam = clazz.newSyntheticTypeParam("T0", flags) val parents = List(AnyRefClass.tpe, parentFn(tparam)) - clazz setInfo polyType(List(tparam), ClassInfoType(parents, newScope, clazz)) + clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz)) } def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): Symbol = { @@ -890,14 +977,14 @@ trait Definitions extends reflect.api.StandardDefinitions { /** Is the symbol that of a parent which is added during parsing? */ lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass - private lazy val scalaValueClassesSet = ScalaValueClasses.toSet + lazy val scalaValueClassesSet = ScalaValueClasses.toSet private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass /** Is symbol a value class? */ - def isValueClass(sym: Symbol) = scalaValueClassesSet(sym) - def isNonUnitValueClass(sym: Symbol) = isValueClass(sym) && (sym != UnitClass) - def isSpecializableClass(sym: Symbol) = isValueClass(sym) || (sym == AnyRefClass) - def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol) + def isPrimitiveValueClass(sym: Symbol) = scalaValueClassesSet(sym) + def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass) + def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass) + def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol) /** Is symbol a boxed value class, e.g. java.lang.Integer? */ def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym) @@ -906,7 +993,7 @@ trait Definitions extends reflect.api.StandardDefinitions { * value class. Otherwise, NoSymbol. */ def unboxedValueClass(sym: Symbol): Symbol = - if (isValueClass(sym)) sym + if (isPrimitiveValueClass(sym)) sym else if (sym == BoxedUnitClass) UnitClass else boxedClass.map(_.swap).getOrElse(sym, NoSymbol) @@ -929,7 +1016,7 @@ trait Definitions extends reflect.api.StandardDefinitions { else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName def signature1(etp: Type): String = { if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head)) - else if (isValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString() + else if (isPrimitiveValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString() else "L" + flatNameString(etp.typeSymbol, '/') + ";" } val etp = erasure(tp) @@ -1007,16 +1094,11 @@ trait Definitions extends reflect.api.StandardDefinitions { Object_synchronized, Object_isInstanceOf, Object_asInstanceOf, - String_+ + String_+, + ComparableClass, + JavaSerializableClass ) - /** Removing the anyref parent they acquire from having a source file. - */ - setParents(AnyValClass, anyparam) - ScalaValueClasses foreach { sym => - setParents(sym, anyvalparam) - } - isInitialized = true } //init @@ -1029,7 +1111,7 @@ trait Definitions extends reflect.api.StandardDefinitions { // tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the // type parameter =-> a MethodType in this case // TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam - val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC) + val newCaller = enterNewMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC) // val newCaller = newPolyMethod(DelegateClass, name, // tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC) Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller) diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 1ae4f755ed..1003fa804f 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -88,7 +88,7 @@ trait Importers { self: SymbolTable => case from.PolyType(_, res) => res case result => result } - s setInfo polyType(mytypeParams, importType(result)) + s setInfo GenPolyType(mytypeParams, importType(result)) s setAnnotations (sym.annotations map importAnnotationInfo) } } @@ -200,7 +200,7 @@ trait Importers { self: SymbolTable => val myclazz = importSymbol(clazz) val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) - myclazz setInfo polyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope + myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope decls foreach importSymbol // will enter itself into myclazz myclazzTpe case from.RefinedType(parents, decls) => diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index ef2114b608..84007425ed 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -145,7 +145,6 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Object: NameType = "Object" final val PartialFunction: NameType = "PartialFunction" final val Product: NameType = "Product" - final val ScalaObject: NameType = "ScalaObject" final val Serializable: NameType = "Serializable" final val Singleton: NameType = "Singleton" final val String: NameType = "String" diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index e13341e105..b58a0ef7d5 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -128,6 +128,10 @@ abstract class SymbolTable extends api.Universe final def period(rid: RunId, pid: Phase#Id): Period = (rid << 8) + pid + /** Are we later than given phase in compilation? */ + final def isAtPhaseAfter(p: Phase) = + p != NoPhase && phase.id > p.id + /** Perform given operation at given phase. */ @inline final def atPhase[T](ph: Phase)(op: => T): T = { val saved = pushPhase(ph) @@ -145,7 +149,7 @@ abstract class SymbolTable extends api.Universe @inline final def beforePrevPhase[T](op: => T): T = atPhase(phase.prev)(op) @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = - if (target != NoPhase && phase.id > target.id) atPhase(target)(op) else op + if (isAtPhaseAfter(target)) atPhase(target)(op) else op final def isValid(period: Period): Boolean = period != 0 && runId(period) == currentRunId && { @@ -184,7 +188,7 @@ abstract class SymbolTable extends api.Universe } // enter decls of parent classes for (p <- container.parentSymbols) { - if (p != definitions.ObjectClass && p != definitions.ScalaObjectClass) { + if (p != definitions.ObjectClass) { openPackageModule(p, dest) } } diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 828b8ca1f1..febc2ef330 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -441,7 +441,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!! final def isTypeParameter = isType && isParameter && !isSkolem - final def isValueClass = definitions.isValueClass(this) + final def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) final def isVarargsMethod = isMethod && hasFlag(VARARGS) /** Package tests */ @@ -499,6 +499,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) + final def isDerivedValueClass = + isClass && info.parents.headOption.getOrElse(AnyClass.tpe).typeSymbol == AnyValClass && + !isPrimitiveValueClass + + final def isMethodWithExtension = + isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) + final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME) final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass @@ -1835,7 +1842,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => base.info.decl(sname) filter (_.hasAccessorFlag) } - /** The case module corresponding to this case class + /** Return the accessor method of the first parameter of this class. + * or NoSymbol if it does not exist. + */ + def firstParamAccessor: Symbol = NoSymbol + + /** The case module corresponding to this case class * @pre case class is a member of some other class or package */ final def caseModule: Symbol = { @@ -2510,7 +2522,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final override def isAbstractType = false final override def isAliasType = false - override def existentialBound = polyType(this.typeParams, TypeBounds.upper(this.classBound)) + override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound)) override def sourceFile = if (owner.isPackageClass) source @@ -2585,6 +2597,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def sourceModule = if (isModuleClass) companionModule else NoSymbol + override def firstParamAccessor = + info.decls.find(m => (m hasFlag PARAMACCESSOR) && m.isMethod) getOrElse NoSymbol + + private[this] var childSet: Set[Symbol] = Set() override def children = childSet override def addChild(sym: Symbol) { childSet = childSet + sym } @@ -2742,7 +2758,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** An exception for cyclic references of symbol definitions */ case class CyclicReference(sym: Symbol, info: Type) extends TypeError("illegal cyclic reference involving " + sym) { - // printStackTrace() // debug + if (settings.debug.value) printStackTrace() } case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable( diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index 8c2a067d4d..141ff12f8a 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -10,11 +10,10 @@ abstract class TreeGen { def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) - def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) - def scalaUnitConstr = scalaDot(tpnme.Unit) - def scalaScalaObjectConstr = scalaDot(tpnme.ScalaObject) - def productConstr = scalaDot(tpnme.Product) - def serializableConstr = scalaDot(tpnme.Serializable) + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass + def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass + def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass + def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = { val cls = if (abstractFun) @@ -149,22 +148,6 @@ abstract class TreeGen { None } - /** Cast `tree` to type `pt` */ - def mkCast(tree: Tree, pt: Type): Tree = { - debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase) - assert(!tree.tpe.isInstanceOf[MethodType], tree) - assert(!pt.typeSymbol.isPackageClass && !pt.typeSymbol.isPackageObjectClass, pt) - // called during (at least): typer, uncurry, explicitouter, cleanup. - // TODO: figure out the truth table for any/wrapInApply - // - the `any` flag seems to relate to erasure's adaptMember: "x.asInstanceOf[T] becomes x.$asInstanceOf[T]", - // where asInstanceOf is Any_asInstanceOf and $asInstanceOf is Object_asInstanceOf - // erasure will only unbox the value in a tree made by mkCast if `any && wrapInApply` - // - the `wrapInApply` flag need not be true if the tree will be adapted to have the empty argument list added before it gets to erasure - // in fact, I think it should be false for trees that will be type checked during typer - assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize)) - atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = false, wrapInApply = true)) - } - /** Builds a reference with stable type to given symbol */ def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = stabilize(mkAttributedRef(pre, sym)) @@ -268,25 +251,6 @@ abstract class TreeGen { case _ => Constant(null) } - def mkZeroContravariantAfterTyper(tp: Type): Tree = { - // contravariant -- for replacing an argument in a method call - // must use subtyping, as otherwise we miss types like `Any with Int` - val tree = - if (NullClass.tpe <:< tp) Literal(Constant(null)) - else if (UnitClass.tpe <:< tp) Literal(Constant()) - else if (BooleanClass.tpe <:< tp) Literal(Constant(false)) - else if (FloatClass.tpe <:< tp) Literal(Constant(0.0f)) - else if (DoubleClass.tpe <:< tp) Literal(Constant(0.0d)) - else if (ByteClass.tpe <:< tp) Literal(Constant(0.toByte)) - else if (ShortClass.tpe <:< tp) Literal(Constant(0.toShort)) - else if (IntClass.tpe <:< tp) Literal(Constant(0)) - else if (LongClass.tpe <:< tp) Literal(Constant(0L)) - else if (CharClass.tpe <:< tp) Literal(Constant(0.toChar)) - else mkCast(Literal(Constant(null)), tp) - - tree - } - /** Builds a tuple */ def mkTuple(elems: List[Tree]): Tree = if (elems.isEmpty) Literal(Constant()) diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 3252b970d1..769d7a9ed1 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -440,15 +440,6 @@ abstract class TreeInfo { EmptyTree } - /** Is the tree Predef, scala.Predef, or _root_.scala.Predef? - */ - def isPredefExpr(t: Tree) = t match { - case Ident(nme.Predef) => true - case Select(Ident(nme.scala_), nme.Predef) => true - case Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.Predef) => true - case _ => false - } - /** Does list of trees start with a definition of * a class of module with given name (ignoring imports) */ @@ -468,7 +459,7 @@ abstract class TreeInfo { // Top-level definition whose leading imports include Predef. def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match { case PackageDef(_, defs1) :: _ => containsLeadingPredefImport(defs1) - case Import(expr, _) :: rest => isPredefExpr(expr) || containsLeadingPredefImport(rest) + case Import(expr, _) :: rest => isReferenceToPredef(expr) || containsLeadingPredefImport(rest) case _ => false } @@ -479,7 +470,6 @@ abstract class TreeInfo { } ( isUnitInScala(body, nme.Predef) - || isUnitInScala(body, tpnme.ScalaObject) || containsLeadingPredefImport(List(body))) } diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 2b1d833c73..f823110440 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -242,6 +242,10 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => case Template(parents, self, body) => val currentOwner1 = currentOwner if (tree.symbol != NoSymbol) currentOwner = tree.symbol.owner +// if (parents exists isReferenceToAnyVal) { +// print("AnyVal") +// } +// else { printRow(parents, " with ") if (!body.isEmpty) { if (self.name != nme.WILDCARD) { @@ -253,6 +257,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => } printColumn(body, "", ";", "}") } +// } currentOwner = currentOwner1 case Block(stats, expr) => diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 54cc53aaac..77ea7392a8 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -11,6 +11,18 @@ import api.Modifier trait Trees extends api.Trees { self: SymbolTable => + // Belongs in TreeInfo but then I can't reach it from TreePrinters. + def isReferenceToScalaMember(t: Tree, Id: Name) = t match { + case Ident(Id) => true + case Select(Ident(nme.scala_), Id) => true + case Select(Select(Ident(nme.ROOTPKG), nme.scala_), Id) => true + case _ => false + } + /** Is the tree Predef, scala.Predef, or _root_.scala.Predef? + */ + def isReferenceToPredef(t: Tree) = isReferenceToScalaMember(t, nme.Predef) + def isReferenceToAnyVal(t: Tree) = isReferenceToScalaMember(t, tpnme.AnyVal) + // --- modifiers implementation --------------------------------------- /** @param privateWithin the qualifier for a private (a type name) @@ -122,11 +134,14 @@ trait Trees extends api.Trees { self: SymbolTable => } } - def substTreeSyms(pairs: (Symbol, Symbol)*): Tree = { - val list = pairs.toList - val subst = new TreeSymSubstituter(list map (_._1), list map (_._2)) - subst(tree) - } + def substTreeSyms(pairs: (Symbol, Symbol)*): Tree = + substTreeSyms(pairs.map(_._1).toList, pairs.map(_._2).toList) + + def substTreeSyms(from: List[Symbol], to: List[Symbol]): Tree = + new TreeSymSubstituter(from, to)(tree) + + def substTreeThis(clazz: Symbol, to: Tree): Tree = new ThisSubstituter(clazz, to) transform tree + def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree def shortClass: String = tree.getClass.getName split "[.$]" last @@ -303,10 +318,14 @@ trait Trees extends api.Trees { self: SymbolTable => } class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser { - def changeOwner(tree: Tree) = { - if ((tree.isDef || tree.isInstanceOf[Function]) && - tree.symbol != NoSymbol && tree.symbol.owner == oldowner) - tree.symbol.owner = newowner + def changeOwner(tree: Tree) = tree match { + case Return(expr) => + if (tree.symbol == oldowner) + tree.symbol = newowner + case _: DefTree | _: Function => + if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner) + tree.symbol.owner = newowner + case _ => } override def traverse(tree: Tree) { changeOwner(tree) @@ -342,6 +361,19 @@ trait Trees extends api.Trees { self: SymbolTable => override def toString = substituterString("Symbol", "Tree", from, to) } + /** Substitute clazz.this with `to`. `to` must be an attributed tree. + */ + class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer { + val newtpe = to.tpe + override def transform(tree: Tree) = { + if (tree.tpe ne null) tree.tpe = tree.tpe.substThis(clazz, newtpe) + tree match { + case This(_) if tree.symbol == clazz => to + case _ => super.transform(tree) + } + } + } + class TypeMapTreeSubstituter(val typeMap: TypeMap) extends Traverser { override def traverse(tree: Tree) { if (tree.tpe ne null) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index b7b7ca5840..2382413a9a 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -65,6 +65,8 @@ import util.Statistics._ // inst is the instantiation and constr is a list of bounds. case DeBruijnIndex(level, index) // for dependent method types: a type referring to a method parameter. + case ErasedValueType(tp) + // only used during erasure of derived value classes. */ trait Types extends api.Types { self: SymbolTable => @@ -410,6 +412,11 @@ trait Types extends api.Types { self: SymbolTable => * The empty list for all other types */ def parents: List[Type] = List() + /** For a class with nonEmpty parents, the first parent. + * Otherwise some specific fixed top type. + */ + def firstParent = if (parents.nonEmpty) parents.head else ObjectClass.tpe + /** For a typeref or single-type, the prefix of the normalized type (@see normalize). * NoType for all other types. */ def prefix: Type = NoType @@ -1418,14 +1425,14 @@ trait Types extends api.Types { self: SymbolTable => // override def isNullable: Boolean = // parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType); - override def safeToString: String = - parents.mkString(" with ") + + override def safeToString: String = parentsString(parents) + ( (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) decls.mkString("{", "; ", "}") else "") + ) } protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = { - val period = tpe.baseTypeSeqPeriod; + val period = tpe.baseTypeSeqPeriod if (period != currentPeriod) { tpe.baseTypeSeqPeriod = currentPeriod if (!isValidForBaseClasses(period)) { @@ -1483,7 +1490,7 @@ trait Types extends api.Types { self: SymbolTable => else { //Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG // optimized, since this seems to be performance critical - val superclazz = tpe.parents.head + val superclazz = tpe.firstParent var mixins = tpe.parents.tail val sbcs = superclazz.baseClasses var bcs = sbcs @@ -1530,7 +1537,7 @@ trait Types extends api.Types { self: SymbolTable => ) override def typeParams = - if (isHigherKinded) parents.head.typeParams + if (isHigherKinded) firstParent.typeParams else super.typeParams //@M may result in an invalid type (references to higher-order args become dangling ) @@ -2099,7 +2106,7 @@ trait Types extends api.Types { self: SymbolTable => !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial) override def isNotNull = - sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull + sym.isModuleClass || sym == NothingClass || (sym isNonBottomSubClass NotNullClass) || super.isNotNull override def parents: List[Type] = { val cache = parentsCache @@ -2148,12 +2155,12 @@ trait Types extends api.Types { self: SymbolTable => ) else "" ) + private def finishPrefix(rest: String) = ( if (sym.isPackageClass) packagePrefix + rest else if (sym.isModuleClass) objectPrefix + rest else if (!sym.isInitialized) rest - else if (sym.isAnonymousClass && !phase.erasedTypes) - thisInfo.parents.mkString("", " with ", refinementString) + else if (sym.isAnonymousClass && !phase.erasedTypes) parentsString(thisInfo.parents) + refinementString else if (sym.isRefinementClass) "" + thisInfo else rest ) @@ -3088,6 +3095,17 @@ trait Types extends api.Types { self: SymbolTable => } } + abstract case class ErasedValueType(sym: Symbol) extends Type { + override def safeToString = sym.name+"$unboxed" + } + + final class UniqueErasedValueType(sym: Symbol) extends ErasedValueType(sym) with UniqueType + + object ErasedValueType { + def apply(sym: Symbol): Type = + unique(new UniqueErasedValueType(sym)) + } + /** A class representing an as-yet unevaluated type. */ abstract class LazyType extends Type { @@ -3234,11 +3252,21 @@ trait Types extends api.Types { self: SymbolTable => * comment or in the code? */ def intersectionType(tps: List[Type], owner: Symbol): Type = tps match { - case List(tp) => - tp - case _ => - refinedType(tps, owner) -/* + case tp :: Nil => tp + case _ => refinedType(tps, owner) + } + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. + */ + def intersectionType(tps: List[Type]): Type = tps match { + case tp :: Nil => tp + case _ => refinedType(tps, commonOwner(tps)) + } + +/**** This implementation to merge parents was checked in in commented-out + form and has languished unaltered for five years. I think we should + use it or lose it. + def merge(tps: List[Type]): List[Type] = tps match { case tp :: tps1 => val tps1a = tps1 filter (_.typeSymbol.==(tp.typeSymbol)) @@ -3253,14 +3281,6 @@ trait Types extends api.Types { self: SymbolTable => } refinedType(merge(tps), owner) */ - } - - /** A creator for intersection type where intersections of a single type are - * replaced by the type itself. */ - def intersectionType(tps: List[Type]): Type = tps match { - case List(tp) => tp - case _ => refinedType(tps, commonOwner(tps)) - } /** A creator for type applications */ def appliedType(tycon: Type, args: List[Type]): Type = @@ -3299,7 +3319,7 @@ trait Types extends api.Types { self: SymbolTable => } } - /** A creator for type parameterizations that strips empty type parameter lists. + /** A creator and extractor for type parameterizations that strips empty type parameter lists. * Use this factory method to indicate the type has kind * (it's a polymorphic value) * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). * @@ -3308,9 +3328,18 @@ trait Types extends api.Types { self: SymbolTable => * can we instead say this is the canonical creator for polyTypes which * may or may not be poly? (It filched the standard "canonical creator" name.) */ - def polyType(tparams: List[Symbol], tpe: Type): Type = + object GenPolyType { + def apply(tparams: List[Symbol], tpe: Type): Type = if (tparams nonEmpty) typeFun(tparams, tpe) else tpe // it's okay to be forgiving here + def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match { + case PolyType(tparams, restpe) => Some(tparams, restpe) + case _ => Some(List(), tpe) + } + } + + @deprecated("use GenPolyType(...) instead") + def polyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe) /** A creator for anonymous type functions, where the symbol for the type function still needs to be created. * @@ -3762,6 +3791,7 @@ trait Types extends api.Types { self: SymbolTable => case WildcardType => tp case NoType => tp case NoPrefix => tp + case ErasedSingleType(sym) => tp */ case _ => tp @@ -4519,9 +4549,7 @@ trait Types extends api.Types { self: SymbolTable => else { commonOwnerMap.clear() tps foreach (commonOwnerMap traverse _) - val result = if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol - debuglog(tps.mkString("commonOwner(", ", ", ") == " + result)) - result + if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol } } @@ -5419,8 +5447,7 @@ trait Types extends api.Types { self: SymbolTable => case NullClass => tp2 match { case TypeRef(_, sym2, _) => - sym2.isClass && (sym2 isNonBottomSubClass ObjectClass) && - !(tp2.normalize.typeSymbol isNonBottomSubClass NotNullClass) + containsNull(sym2) case _ => isSingleType(tp2) && tp1 <:< tp2.widen } @@ -5451,6 +5478,11 @@ trait Types extends api.Types { self: SymbolTable => firstTry } + private def containsNull(sym: Symbol): Boolean = + sym.isClass && sym != NothingClass && + !(sym isNonBottomSubClass AnyValClass) && + !(sym isNonBottomSubClass NotNullClass) + /** Are `tps1` and `tps2` lists of equal length such that all elements * of `tps1` conform to corresponding elements of `tps2`? */ @@ -5462,7 +5494,7 @@ trait Types extends api.Types { self: SymbolTable => */ def specializesSym(tp: Type, sym: Symbol): Boolean = tp.typeSymbol == NothingClass || - tp.typeSymbol == NullClass && (sym.owner isSubClass ObjectClass) || + tp.typeSymbol == NullClass && containsNull(sym.owner) || (tp.nonPrivateMember(sym.name).alternatives exists (alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym))) @@ -5853,14 +5885,6 @@ trait Types extends api.Types { self: SymbolTable => loop(initialBTSes) } - // @AM the following problem is solved by elimHOTparams in lublist - // @PP lubLists gone bad: lubList(List( - // List(scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq], ScalaObject, java.lang.Object, Any) - // List(scala.collection.generic.GenericCompanion[scala.collection.mutable.Seq], ScalaObject, java.lang.Object, Any) - // )) == ( - // List(scala.collection.generic.GenericCompanion[Seq**[Any]**], ScalaObject, java.lang.Object, Any) - // ) - /** The minimal symbol (wrt Symbol.isLess) of a list of types */ private def minSym(tps: List[Type]): Symbol = (tps.head.typeSymbol /: tps.tail) { @@ -6310,7 +6334,7 @@ trait Types extends api.Types { self: SymbolTable => } else { val args = argss map (_.head) if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head))) - else if (args exists (arg => isValueClass(arg.typeSymbol))) Some(ObjectClass.tpe) + else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectClass.tpe) else Some(typeRef(pre, sym, List(lub(args)))) } } @@ -6441,7 +6465,9 @@ trait Types extends api.Types { self: SymbolTable => // but that would be a big change. Left for further refactoring. /** An exception for cyclic references from which we can recover */ case class RecoverableCyclicReference(sym: Symbol) - extends TypeError("illegal cyclic reference involving " + sym) + extends TypeError("illegal cyclic reference involving " + sym) { + if (settings.debug.value) printStackTrace() + } class NoCommonType(tps: List[Type]) extends Throwable( "lub/glb of incompatible types: " + tps.mkString("", " and ", "")) with ControlThrowable diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index 34163d54f8..f1ec64bda9 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -229,6 +229,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { // (3) Try as a nested object symbol. nestedObjectSymbol orElse { // (4) Otherwise, fail. + //System.err.println("missing "+name+" in "+owner+"/"+owner.id+" "+owner.info.decls) adjust(errorMissingRequirement(name, owner)) } } diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala index d59fc6d564..e87de8db80 100644 --- a/src/compiler/scala/reflect/internal/transform/Erasure.scala +++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala @@ -2,6 +2,8 @@ package scala.reflect package internal package transform +import Flags.PARAMACCESSOR + trait Erasure { val global: SymbolTable @@ -63,49 +65,62 @@ trait Erasure { if (cls.owner.isClass) cls.owner.tpe else pre // why not cls.isNestedClass? } + def underlyingOfValueClass(clazz: Symbol): Type = + clazz.firstParamAccessor.tpe.resultType + abstract class ErasureMap extends TypeMap { def mergeParents(parents: List[Type]): Type - def apply(tp: Type): Type = { - tp match { - case ConstantType(_) => - tp - case st: SubType => - apply(st.supertype) - case TypeRef(pre, sym, args) => - if (sym == ArrayClass) - if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe - else if (args.head.typeSymbol.isBottomClass) ObjectArray - else typeRef(apply(pre), sym, args map this) - else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass) - else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) - else if (sym.isRefinementClass) apply(mergeParents(tp.parents)) - else if (sym.isClass) typeRef(apply(rebindInnerClass(pre, sym)), sym, List()) // #2585 - else apply(sym.info) // alias type or abstract type - case PolyType(tparams, restpe) => - apply(restpe) - case ExistentialType(tparams, restpe) => - apply(restpe) - case mt @ MethodType(params, restpe) => - MethodType( - cloneSymbolsAndModify(params, ErasureMap.this), - if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) - // this replaces each typeref that refers to an argument - // by the type `p.tpe` of the actual argument p (p in params) - else apply(mt.resultType(params map (_.tpe)))) - case RefinedType(parents, decls) => - apply(mergeParents(parents)) - case AnnotatedType(_, atp, _) => - apply(atp) - case ClassInfoType(parents, decls, clazz) => - ClassInfoType( - if (clazz == ObjectClass || isValueClass(clazz)) Nil - else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass)) - else removeDoubleObject(parents map this), - decls, clazz) - case _ => - mapOver(tp) - } + def eraseNormalClassRef(pre: Type, clazz: Symbol): Type = + typeRef(apply(rebindInnerClass(pre, clazz)), clazz, List()) // #2585 + + protected def eraseDerivedValueClassRef(clazz: Symbol): Type = + scalaErasure(underlyingOfValueClass(clazz)) + + def apply(tp: Type): Type = tp match { + case ConstantType(_) => + tp + case st: SubType => + apply(st.supertype) + case TypeRef(pre, sym, args) => + if (sym == ArrayClass) + if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe + else if (args.head.typeSymbol.isBottomClass) ObjectArray + else typeRef(apply(pre), sym, args map applyInArray) + else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass) + else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) + else if (sym.isRefinementClass) apply(mergeParents(tp.parents)) + else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(sym) + else if (sym.isClass) eraseNormalClassRef(pre, sym) + else apply(sym.info) // alias type or abstract type + case PolyType(tparams, restpe) => + apply(restpe) + case ExistentialType(tparams, restpe) => + apply(restpe) + case mt @ MethodType(params, restpe) => + MethodType( + cloneSymbolsAndModify(params, ErasureMap.this), + if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) + // this replaces each typeref that refers to an argument + // by the type `p.tpe` of the actual argument p (p in params) + else apply(mt.resultType(params map (_.tpe)))) + case RefinedType(parents, decls) => + apply(mergeParents(parents)) + case AnnotatedType(_, atp, _) => + apply(atp) + case ClassInfoType(parents, decls, clazz) => + ClassInfoType( + if (clazz == ObjectClass || isPrimitiveValueClass(clazz)) Nil + else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass)) + else removeLaterObjects(parents map this), + decls, clazz) + case _ => + mapOver(tp) + } + + def applyInArray(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) if (sym.isDerivedValueClass) => eraseNormalClassRef(pre, sym) + case _ => apply(tp) } } @@ -138,17 +153,41 @@ trait Erasure { * parents |Ps|, but with duplicate references of Object removed. * - for all other types, the type itself (with any sub-components erased) */ - def erasure(sym: Symbol, tp: Type): Type = { - if (sym != NoSymbol && sym.enclClass.isJavaDefined) { - val res = javaErasure(tp) - if (verifyJavaErasure && sym.isMethod) { - val old = scalaErasure(tp) - if (!(res =:= old)) - log("Identified divergence between java/scala erasure:\n scala: " + old + "\n java: " + res) - } - res + def erasure(sym: Symbol): ErasureMap = + if (sym == NoSymbol || !sym.enclClass.isJavaDefined) scalaErasure + else if (verifyJavaErasure && sym.isMethod) verifiedJavaErasure + else javaErasure + + /** This is used as the Scala erasure during the erasure phase itself + * It differs from normal erasure in that value classes are erased to ErasedValueTypes which + * are then later converted to the underlying parameter type in phase posterasure. + */ + def specialErasure(sym: Symbol)(tp: Type): Type = + if (sym != NoSymbol && sym.enclClass.isJavaDefined) + erasure(sym)(tp) + else if (sym.isTerm && sym.owner.isDerivedValueClass) + specialErasureAvoiding(sym.owner, tp) + else if (sym.isValue && sym.owner.isMethodWithExtension) + specialErasureAvoiding(sym.owner.owner, tp) + else + specialScalaErasure(tp) + + def specialErasureAvoiding(clazz: Symbol, tpe: Type): Type = { + tpe match { + case PolyType(tparams, restpe) => + specialErasureAvoiding(clazz, restpe) + case ExistentialType(tparams, restpe) => + specialErasureAvoiding(clazz, restpe) + case mt @ MethodType(params, restpe) => + MethodType( + cloneSymbolsAndModify(params, specialErasureAvoiding(clazz, _)), + if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) + else specialErasureAvoiding(clazz, (mt.resultType(params map (_.tpe))))) + case TypeRef(pre, `clazz`, args) => + typeRef(pre, clazz, List()) + case _ => + specialScalaErasure(tpe) } - else scalaErasure(tp) } /** Scala's more precise erasure than java's is problematic as follows: @@ -163,7 +202,7 @@ trait Erasure { * For this reason and others (such as distinguishing constructors from other methods) * erasure is now (Symbol, Type) => Type rather than Type => Type. */ - object scalaErasure extends ErasureMap { + class ScalaErasureMap extends ErasureMap { /** In scala, calculate a useful parent. * An intersection such as `Object with Trait` erases to Trait. */ @@ -171,6 +210,37 @@ trait Erasure { intersectionDominator(parents) } + class JavaErasureMap extends ErasureMap { + /** In java, always take the first parent. + * An intersection such as `Object with Trait` erases to Object. + */ + def mergeParents(parents: List[Type]): Type = + if (parents.isEmpty) ObjectClass.tpe + else parents.head + } + + object scalaErasure extends ScalaErasureMap + + /** This is used as the Scala erasure during the erasure phase itself + * It differs from normal erasure in that value classes are erased to ErasedValueTypes which + * are then later converted to the underlying parameter type in phase posterasure. + */ + object specialScalaErasure extends ScalaErasureMap { + override def eraseDerivedValueClassRef(clazz: Symbol): Type = ErasedValueType(clazz) + } + + object javaErasure extends JavaErasureMap + + object verifiedJavaErasure extends JavaErasureMap { + override def apply(tp: Type): Type = { + val res = javaErasure(tp) + val old = scalaErasure(tp) + if (!(res =:= old)) + log("Identified divergence between java/scala erasure:\n scala: " + old + "\n java: " + res) + res + } + } + /** The intersection dominator (SLS 3.7) of a list of types is computed as follows. * * - If the list contains one or more occurrences of scala.Array with @@ -206,26 +276,9 @@ trait Erasure { } } - object javaErasure extends ErasureMap { - /** In java, always take the first parent. - * An intersection such as `Object with Trait` erases to Object. - */ - def mergeParents(parents: List[Type]): Type = - if (parents.isEmpty) ObjectClass.tpe - else parents.head - } - /** Type reference after erasure */ def erasedTypeRef(sym: Symbol): Type = - typeRef(erasure(sym, sym.owner.tpe), sym, List()) - - /** Remove duplicate references to class Object in a list of parent classes */ - private def removeDoubleObject(tps: List[Type]): List[Type] = tps match { - case List() => List() - case tp :: tps1 => - if (tp.typeSymbol == ObjectClass) tp :: tps1.filter(_.typeSymbol != ObjectClass) - else tp :: removeDoubleObject(tps1) - } + typeRef(erasure(sym)(sym.owner.tpe), sym, Nil) /** The symbol's erased info. This is the type's erasure, except for the following symbols: * @@ -239,25 +292,25 @@ trait Erasure { if (sym == Object_asInstanceOf) sym.info else if (sym == Object_isInstanceOf || sym == ArrayClass) - PolyType(sym.info.typeParams, erasure(sym, sym.info.resultType)) + PolyType(sym.info.typeParams, specialErasure(sym)(sym.info.resultType)) else if (sym.isAbstractType) TypeBounds(WildcardType, WildcardType) else if (sym.isTerm && sym.owner == ArrayClass) { if (sym.isClassConstructor) tp match { case MethodType(params, TypeRef(pre, sym1, args)) => - MethodType(cloneSymbolsAndModify(params, erasure(sym, _)), - typeRef(erasure(sym, pre), sym1, args)) + MethodType(cloneSymbolsAndModify(params, specialErasure(sym)), + typeRef(specialErasure(sym)(pre), sym1, args)) } else if (sym.name == nme.apply) tp else if (sym.name == nme.update) (tp: @unchecked) match { case MethodType(List(index, tvar), restpe) => - MethodType(List(index.cloneSymbol.setInfo(erasure(sym, index.tpe)), tvar), + MethodType(List(index.cloneSymbol.setInfo(specialErasure(sym)(index.tpe)), tvar), erasedTypeRef(UnitClass)) } - else erasure(sym, tp) + else specialErasure(sym)(tp) } else if ( sym.owner != NoSymbol && sym.owner.owner == ArrayClass && @@ -267,7 +320,7 @@ trait Erasure { // symbol here tp } else { - erasure(sym, tp) + specialErasure(sym)(tp) } } } diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala index 4c49c0221f..89fd6bab64 100644 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala @@ -186,7 +186,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => } finally { parentsLevel -= 1 } - clazz setInfo polyType(tparams, new ClassInfoType(parents, newScope, clazz)) + clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz)) if (module != NoSymbol) { module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass) } @@ -534,7 +534,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => } private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = { - meth setInfo polyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe)) + meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe)) } /** @@ -572,7 +572,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => val tparams = jconstr.getTypeParameters.toList map createTypeParameter val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala setMethType(constr, tparams, paramtpes, clazz.tpe) - constr setInfo polyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe)) + constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe)) copyAnnotations(constr, jconstr) constr } diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala index 405a00de8d..87cdd11652 100644 --- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala +++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala @@ -28,7 +28,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable => def classToJava(clazz: Symbol): jClass[_] = classCache.toJava(clazz) { def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found") //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug - if (clazz.isValueClass) + if (clazz.isPrimitiveValueClass) valueClassToJavaType(clazz) else if (clazz == ArrayClass) noClass diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index f52662ce6f..8cc4d5f788 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -59,7 +59,7 @@ trait ToolBoxes extends { self: Universe => def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = { val obj = EmptyPackageClass.newModule(nextWrapperModuleName()) - val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), newScope, obj.moduleClass) + val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass) obj.moduleClass setInfo minfo obj setInfo obj.moduleClass.tpe val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index 700f819226..324fee87ab 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -37,6 +37,12 @@ class Universe extends SymbolTable { type Position = String // source file? val NoPosition = "" + definitions.AnyValClass // force it. + // establish root association to avoid cyclic dependency errors later classToScala(classOf[java.lang.Object]).initialize + +// println("initializing definitions") + definitions.init() + } diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index 7c9599dc45..0869350dd3 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -182,7 +182,7 @@ trait AnyValReps { def classLines: List[String] def objectLines: List[String] def commonClassLines = List( - "def getClass(): Class[@name@]" + "override def getClass(): Class[@name@]" ) def lcname = name.toLowerCase @@ -429,7 +429,7 @@ def &(x: Boolean): Boolean = sys.error("stub") */ def ^(x: Boolean): Boolean = sys.error("stub") -def getClass(): Class[Boolean] = sys.error("stub") +override def getClass(): Class[Boolean] = sys.error("stub") """.trim.lines.toList def objectLines = interpolate(allCompanions).lines.toList @@ -443,7 +443,7 @@ def getClass(): Class[Boolean] = sys.error("stub") */ """ def classLines = List( - """def getClass(): Class[Unit] = sys.error("stub")""" + """override def getClass(): Class[Unit] = sys.error("stub")""" ) def objectLines = interpolate(allCompanions).lines.toList diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 552479bc0b..bc2cc8191c 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -456,141 +456,155 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb // phaseName = "superaccessors" object superAccessors extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("typer") + val runsAfter = List("typer") val runsRightAfter = None } with SuperAccessors + // phaseName = "extmethods" + object extensionMethods extends { + val global: Global.this.type = Global.this + val runsAfter = List("superaccessors") + val runsRightAfter = None + } with ExtensionMethods + // phaseName = "pickler" object pickler extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("superaccessors") + val runsAfter = List("extmethods") val runsRightAfter = None } with Pickler // phaseName = "refchecks" override object refChecks extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("pickler") + val runsAfter = List("pickler") val runsRightAfter = None } with RefChecks // phaseName = "uncurry" override object uncurry extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("refchecks") + val runsAfter = List("refchecks") val runsRightAfter = None } with UnCurry // phaseName = "tailcalls" object tailCalls extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("uncurry") + val runsAfter = List("uncurry") val runsRightAfter = None } with TailCalls // phaseName = "explicitouter" object explicitOuter extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("tailcalls") + val runsAfter = List("tailcalls") val runsRightAfter = None } with ExplicitOuter // phaseName = "specialize" object specializeTypes extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("") + val runsAfter = List("") val runsRightAfter = Some("tailcalls") } with SpecializeTypes // phaseName = "erasure" override object erasure extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("explicitouter") + val runsAfter = List("explicitouter") val runsRightAfter = Some("explicitouter") } with Erasure + // phaseName = "posterasure" + object postErasure extends { + val global: Global.this.type = Global.this + val runsAfter = List("erasure") + val runsRightAfter = Some("erasure") + } with PostErasure + // phaseName = "lazyvals" object lazyVals extends { final val FLAGS_PER_WORD = 32 val global: Global.this.type = Global.this - val runsAfter = List[String]("erasure") + val runsAfter = List("erasure") val runsRightAfter = None } with LazyVals // phaseName = "lambdalift" object lambdaLift extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("lazyvals") + val runsAfter = List("lazyvals") val runsRightAfter = None } with LambdaLift // phaseName = "constructors" object constructors extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("lambdalift") + val runsAfter = List("lambdalift") val runsRightAfter = None } with Constructors // phaseName = "flatten" object flatten extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("constructors") + val runsAfter = List("constructors") val runsRightAfter = None } with Flatten // phaseName = "mixin" object mixer extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("flatten", "constructors") + val runsAfter = List("flatten", "constructors") val runsRightAfter = None } with Mixin // phaseName = "cleanup" object cleanup extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("mixin") + val runsAfter = List("mixin") val runsRightAfter = None } with CleanUp // phaseName = "icode" object genicode extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("cleanup") + val runsAfter = List("cleanup") val runsRightAfter = None } with GenICode // phaseName = "inliner" object inliner extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("icode") + val runsAfter = List("icode") val runsRightAfter = None } with Inliners // phaseName = "inlineExceptionHandlers" object inlineExceptionHandlers extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("inliner") + val runsAfter = List("inliner") val runsRightAfter = None } with InlineExceptionHandlers // phaseName = "closelim" object closureElimination extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("inlineExceptionHandlers") + val runsAfter = List("inlineExceptionHandlers") val runsRightAfter = None } with ClosureElimination // phaseName = "dce" object deadCode extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("closelim") + val runsAfter = List("closelim") val runsRightAfter = None } with DeadCodeElimination // phaseName = "jvm" object genJVM extends { val global: Global.this.type = Global.this - val runsAfter = List[String]("dce") + val runsAfter = List("dce") val runsRightAfter = None } with GenJVM @@ -606,7 +620,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb object terminal extends { val global: Global.this.type = Global.this val phaseName = "terminal" - val runsAfter = List[String]("jvm", "msil") + val runsAfter = List("jvm", "msil") val runsRightAfter = None } with SubComponent { private var cache: Option[GlobalPhase] = None @@ -660,6 +674,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb analyzer.packageObjects -> "load package objects", analyzer.typerFactory -> "the meat and potatoes: type the trees", superAccessors -> "add super accessors in traits and nested classes", + extensionMethods -> "add extension methods for inline classes", pickler -> "serialize symbol tables", refChecks -> "reference/override checking, translate nested objects", uncurry -> "uncurry, translate function values to anonymous classes", @@ -667,6 +682,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb specializeTypes -> "@specialized-driven class and method specialization", explicitOuter -> "this refs to outer pointers, translate patterns", erasure -> "erase types, add interfaces for traits", + postErasure -> "clean up erased inline classes", lazyVals -> "allocate bitmaps, translate lazy vals into lazified defs", lambdaLift -> "move nested functions to top level", constructors -> "move field definitions into constructors", @@ -1102,6 +1118,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb val namerPhase = phaseNamed("namer") // val packageobjectsPhase = phaseNamed("packageobjects") val typerPhase = phaseNamed("typer") + val inlineclassesPhase = phaseNamed("inlineclasses") // val superaccessorsPhase = phaseNamed("superaccessors") val picklerPhase = phaseNamed("pickler") val refchecksPhase = phaseNamed("refchecks") @@ -1433,7 +1450,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** * Re-orders the source files to - * 1. ScalaObject + * 1. This Space Intentionally Left Blank * 2. LowPriorityImplicits / EmbeddedControls (i.e. parents of Predef) * 3. the rest * @@ -1461,7 +1478,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def rank(f: SourceFile) = { if (f.file.container.name != "scala") goLast else f.file.name match { - case "ScalaObject.scala" => 1 case "LowPriorityImplicits.scala" => 2 case "StandardEmbeddings.scala" => 2 case "EmbeddedControls.scala" => 2 diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index d7159c5fa8..6d95b6ffdd 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -263,6 +263,22 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { ) } + /** Cast `tree` to type `pt` by creating + * one of the calls of the form + * + * x.asInstanceOf[`pt`] up to phase uncurry + * x.asInstanceOf[`pt`]() if after uncurry but before erasure + * x.$asInstanceOf[`pt`]() if at or after erasure + */ + def mkCast(tree: Tree, pt: Type): Tree = { + debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase) + assert(!tree.tpe.isInstanceOf[MethodType], tree) + assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize)) + atPos(tree.pos) { + mkAsInstanceOf(tree, pt, any = !phase.next.erasedTypes, wrapInApply = isAtPhaseAfter(currentRun.uncurryPhase)) + } + } + /** Generate a cast for tree Tree representing Array with * elem type elemtp to expected type pt. */ @@ -272,6 +288,25 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { else mkCast(tree, pt) + def mkZeroContravariantAfterTyper(tp: Type): Tree = { + // contravariant -- for replacing an argument in a method call + // must use subtyping, as otherwise we miss types like `Any with Int` + val tree = + if (NullClass.tpe <:< tp) Literal(Constant(null)) + else if (UnitClass.tpe <:< tp) Literal(Constant()) + else if (BooleanClass.tpe <:< tp) Literal(Constant(false)) + else if (FloatClass.tpe <:< tp) Literal(Constant(0.0f)) + else if (DoubleClass.tpe <:< tp) Literal(Constant(0.0d)) + else if (ByteClass.tpe <:< tp) Literal(Constant(0.toByte)) + else if (ShortClass.tpe <:< tp) Literal(Constant(0.toShort)) + else if (IntClass.tpe <:< tp) Literal(Constant(0)) + else if (LongClass.tpe <:< tp) Literal(Constant(0L)) + else if (CharClass.tpe <:< tp) Literal(Constant(0.toChar)) + else mkCast(Literal(Constant(null)), tp) + + tree + } + /** Translate names in Select/Ident nodes to type names. */ def convertToTypeName(tree: Tree): Option[RefTree] = tree match { diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index b16b3c89a0..9f361e5bcc 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -6,6 +6,7 @@ package scala.tools.nsc package ast +import reflect.internal.HasFlags import reflect.internal.Flags._ import symtab._ @@ -41,4 +42,14 @@ abstract class TreeInfo extends reflect.internal.TreeInfo { case ClassDef(_, `name`, _, _) :: Nil => true case _ => super.firstDefinesClassOrObject(trees, name) } + + def isInterface(mods: HasFlags, body: List[Tree]) = + mods.hasTraitFlag && (body forall isInterfaceMember) + + def isAllowedInUniversalTrait(stat: Tree): Boolean = stat match { + case _: ValDef => false + case Import(_, _) | EmptyTree => true + case _: DefTree => true + case _ => false + } } diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index ad87889145..a1d3846557 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -34,6 +34,12 @@ trait Trees extends reflect.internal.Trees { self: Global => case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type) extends TermTree with RefTree + /** Derived value class injection (equivalent to: new C(arg) after easure); only used during erasure + * The class C is stored as the symbol of the tree node. + */ + case class InjectDerivedValue(arg: Tree) + extends SymTree + /** emitted by typer, eliminated by refchecks */ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree @@ -149,6 +155,8 @@ trait Trees extends reflect.internal.Trees { self: Global => traverser.traverse(definition) case SelectFromArray(qualifier, selector, erasure) => traverser.traverse(qualifier) + case InjectDerivedValue(arg) => + traverser.traverse(arg) case ReferenceToBoxed(idt) => traverser.traverse(idt) case TypeTreeWithDeferredRefCheck() => @@ -159,6 +167,7 @@ trait Trees extends reflect.internal.Trees { self: Global => trait TreeCopier extends super.TreeCopierOps { def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray + def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck } @@ -171,6 +180,8 @@ trait Trees extends reflect.internal.Trees { self: Global => new DocDef(comment, definition).copyAttrs(tree) def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) = new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree) + def InjectDerivedValue(tree: Tree, arg: Tree) = + new InjectDerivedValue(arg) def ReferenceToBoxed(tree: Tree, idt: Ident) = new ReferenceToBoxed(idt).copyAttrs(tree) def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { @@ -189,6 +200,11 @@ trait Trees extends reflect.internal.Trees { self: Global => if (qualifier0 == qualifier) && (selector0 == selector) => t case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure) } + def InjectDerivedValue(tree: Tree, arg: Tree) = tree match { + case t @ InjectDerivedValue(arg0) + if (arg0 == arg) => t + case _ => this.treeCopy.InjectDerivedValue(tree, arg) + } def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { case t @ ReferenceToBoxed(idt0) if (idt0 == idt) => t @@ -217,6 +233,9 @@ trait Trees extends reflect.internal.Trees { self: Global => case SelectFromArray(qualifier, selector, erasure) => transformer.treeCopy.SelectFromArray( tree, transformer.transform(qualifier), selector, erasure) + case InjectDerivedValue(arg) => + transformer.treeCopy.InjectDerivedValue( + tree, transformer.transform(arg)) case ReferenceToBoxed(idt) => transformer.treeCopy.ReferenceToBoxed( tree, transformer.transform(idt) match { case idt1: Ident => idt1 }) @@ -333,6 +352,7 @@ trait Trees extends reflect.internal.Trees { self: Global => case DocDef(comment, defn) => (eliminated by typer) case TypeTreeWithDeferredRefCheck() => (created and eliminated by typer) case SelectFromArray(_, _, _) => (created and eliminated by erasure) + case InjectDerivedValue(_) => (created and eliminated by erasure) */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 077f0f9c0e..ab6125df61 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -249,6 +249,8 @@ self => final val InBlock = 1 final val InTemplate = 2 + lazy val ScalaValueClassNames: Set[Name] = definitions.scalaValueClassesSet map (_.name) + import nme.raw abstract class Parser extends ParserCommon { @@ -290,11 +292,11 @@ self => inScalaPackage = false currentPackage = "" } - private lazy val anyValNames: Set[Name] = tpnme.ScalaValueNames.toSet + tpnme.AnyVal + private lazy val primitiveNames: Set[Name] = tpnme.ScalaValueNames.toSet private def inScalaRootPackage = inScalaPackage && currentPackage == "scala" private def isScalaArray(name: Name) = inScalaRootPackage && name == tpnme.Array - private def isAnyValType(name: Name) = inScalaRootPackage && anyValNames(name) + private def isPrimitiveType(name: Name) = inScalaRootPackage && primitiveNames(name) def parseStartRule: () => Tree @@ -392,7 +394,7 @@ self => // object Main def moduleName = newTermName(ScriptRunner scriptMain settings) - def moduleBody = Template(List(scalaScalaObjectConstr), emptyValDef, List(emptyInit, mainDef)) + def moduleBody = Template(List(scalaAnyRefConstr), emptyValDef, List(emptyInit, mainDef)) def moduleDef = ModuleDef(NoMods, moduleName, moduleBody) // package <empty> { ... } @@ -2722,23 +2724,6 @@ self => * }}} */ def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = { - /** Extra parents for case classes. */ - def caseParents() = ( - if (mods.isCase) { - val arity = if (vparamss.isEmpty || vparamss.head.isEmpty) 0 else vparamss.head.size - productConstr :: serializableConstr :: { - Nil - // if (arity == 0 || settings.YnoProductN.value) Nil - // else List( - // AppliedTypeTree( - // productConstrN(arity), - // vparamss.head map (vd => vd.tpt.duplicate setPos vd.tpt.pos.focus) - // ) - // ) - } - } - else Nil - ) val (parents0, argss, self, body) = ( if (in.token == EXTENDS || in.token == SUBTYPE && mods.hasTraitFlag) { in.nextToken() @@ -2750,21 +2735,27 @@ self => (List(), List(List()), self, body) } ) - + def anyrefParents() = { + val caseParents = if (mods.isCase) List(productConstr, serializableConstr) else Nil + parents0 ::: caseParents match { + case Nil => List(scalaAnyRefConstr) + case ps => ps + } + } + def anyvalConstructor() = ( + // Not a well-formed constructor, has to be finished later - see note + // regarding AnyVal constructor in AddInterfaces. + DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(), Block(Nil, Literal(Constant()))) + ) val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart + atPos(tstart0) { - if (isAnyValType(name)) { - val parent = if (name == tpnme.AnyVal) tpnme.Any else tpnme.AnyVal - Template(List(scalaDot(parent)), self, body) - } - else { - val parents = ( - if (!isInterface(mods, body) && !isScalaArray(name)) parents0 :+ scalaScalaObjectConstr - else if (parents0.isEmpty) List(scalaAnyRefConstr) - else parents0 - ) ++ caseParents() - Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart)) - } + // [Martin to Paul: This needs to be refined. We should only include the 9 primitive classes, + // not any other value classes that happen to be defined in the Scala package. + if (inScalaRootPackage && (name == tpnme.AnyVal || (ScalaValueClassNames contains name))) + Template(parents0, self, anyvalConstructor :: body) + else + Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart)) } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index ad93b4753f..0d2fbc5372 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -29,12 +29,13 @@ abstract class TreeBuilder { def rootId(name: Name) = gen.rootId(name) def rootScalaDot(name: Name) = gen.rootScalaDot(name) def scalaDot(name: Name) = gen.scalaDot(name) - def scalaAnyRefConstr = gen.scalaAnyRefConstr - def scalaUnitConstr = gen.scalaUnitConstr - def scalaScalaObjectConstr = gen.scalaScalaObjectConstr - def productConstr = gen.productConstr + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) + def scalaAnyValConstr = scalaDot(tpnme.AnyVal) + def scalaAnyConstr = scalaDot(tpnme.Any) + def scalaUnitConstr = scalaDot(tpnme.Unit) + def productConstr = scalaDot(tpnme.Product) def productConstrN(n: Int) = scalaDot(newTypeName("Product" + n)) - def serializableConstr = gen.serializableConstr + def serializableConstr = scalaDot(tpnme.Serializable) def convertToTypeName(t: Tree) = gen.convertToTypeName(t) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index c609f126d3..4c77cb7082 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -746,7 +746,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if ((settings.check.value contains "genjvm")) { val normalizedTpe = beforeErasure(erasure.prepareSigMap(memberTpe)) val bytecodeTpe = owner.thisType.memberInfo(sym) - if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym, normalizedTpe) =:= bytecodeTpe)) { + if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) { clasz.cunit.warning(sym.pos, """|compiler bug: created generic signature for %s in %s that does not conform to its erasure |signature: %s diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 127faf8ed9..496d004fd8 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -20,7 +20,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory: ModelFactory with CommentFactory with TreeFactory => import global._ - import definitions.{ ObjectClass, ScalaObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass } + import definitions.{ ObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass } private var droppedPackages = 0 def templatesCount = templatesCache.size - droppedPackages @@ -42,7 +42,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym)) } - private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass, ScalaObjectClass) + private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass) /** */ def makeModel: Option[Universe] = { @@ -217,13 +217,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } def parentType = { if (sym.isPackage || sym == AnyClass) None else { - val tps = - (sym.tpe.parents filter (_ != ScalaObjectClass.tpe)) map { _.asSeenFrom(sym.thisType, sym) } + val tps = sym.tpe.parents map { _.asSeenFrom(sym.thisType, sym) } Some(makeType(RefinedType(tps, EmptyScope), inTpl)) } } val linearization: List[(TemplateEntity, TypeEntity)] = { - sym.ancestors filter (_ != ScalaObjectClass) map { ancestor => + sym.ancestors map { ancestor => val typeEntity = makeType(sym.info.baseType(ancestor), this) val tmplEntity = makeTemplate(ancestor) match { case tmpl: DocTemplateImpl => tmpl registerSubClass this ; tmpl @@ -316,7 +315,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def normalizeTemplate(aSym: Symbol): Symbol = aSym match { case null | EmptyPackage | NoSymbol => normalizeTemplate(RootPackage) - case ScalaObjectClass | ObjectClass => + case ObjectClass => normalizeTemplate(AnyRefClass) case _ if aSym.isPackageObject => aSym diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 7e032753f2..68bfeafbc6 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -183,7 +183,7 @@ trait MemberHandlers { // TODO: Need to track these specially to honor Predef masking attempts, // because they must be the leading imports in the code generated for each // line. We can use the same machinery as Contexts now, anyway. - def isPredefImport = treeInfo.isPredefExpr(expr) + def isPredefImport = isReferenceToPredef(expr) // wildcard imports, e.g. import foo._ private def selectorWild = selectors filter (_.name == nme.USCOREkw) diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index e72a0007a0..ef17367ce0 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -20,7 +20,7 @@ trait MatrixAdditions extends ast.TreeDSL { import CODE._ import Debug._ import treeInfo._ - import definitions.{ isValueClass } + import definitions.{ isPrimitiveValueClass } /** The Squeezer, responsible for all the squeezing. */ @@ -141,7 +141,7 @@ trait MatrixAdditions extends ast.TreeDSL { (sym.isMutable) && // indicates that have not yet checked exhaustivity !(sym hasFlag NO_EXHAUSTIVE) && // indicates @unchecked (sym.tpe.typeSymbol.isSealed) && - !isValueClass(sym.tpe.typeSymbol) // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte + !isPrimitiveValueClass(sym.tpe.typeSymbol) // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte } private lazy val inexhaustives: List[List[Combo]] = { @@ -155,7 +155,7 @@ trait MatrixAdditions extends ast.TreeDSL { pv.tpe.typeSymbol.sealedDescendants.toList sortBy (_.sealedSortName) // symbols which are both sealed and abstract need not be covered themselves, because // all of their children must be and they cannot otherwise be created. - filterNot (x => x.isSealed && x.isAbstractClass && !isValueClass(x)) + filterNot (x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x)) // have to filter out children which cannot match: see ticket #3683 for an example filter (_.tpe matchesPattern pv.tpe) ) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 07d132f7dd..1cd4ab21ea 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -843,7 +843,7 @@ abstract class ClassfileParser { } ClassInfoType(parents.toList, instanceDefs, sym) } - polyType(ownTypeParams, tpe) + GenPolyType(ownTypeParams, tpe) } // sigToType class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType { diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 1abaf1c1d6..555d0700ae 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -11,7 +11,7 @@ import Flags._ import scala.collection.{ mutable, immutable } import collection.mutable.ListBuffer -abstract class AddInterfaces extends InfoTransform { +abstract class AddInterfaces extends InfoTransform { self: Erasure => import global._ // the global environment import definitions._ // standard classes and methods @@ -21,14 +21,6 @@ abstract class AddInterfaces extends InfoTransform { */ override def phaseNewFlags: Long = lateDEFERRED | lateINTERFACE - /** Type reference after erasure; defined in Erasure. - */ - def erasedTypeRef(sym: Symbol): Type - - /** Erasure calculation; defined in Erasure. - */ - def erasure(sym: Symbol, tpe: Type): Type - /** A lazily constructed map that associates every non-interface trait with * its implementation class. */ @@ -176,14 +168,14 @@ abstract class AddInterfaces extends InfoTransform { /** If `tp` refers to a non-interface trait, return a * reference to its implementation class. Otherwise return `tp`. */ - def mixinToImplClass(tp: Type): Type = erasure(sym, + def mixinToImplClass(tp: Type): Type = erasure(sym) { tp match { //@MATN: no normalize needed (comes after erasure) case TypeRef(pre, sym, _) if sym.needsImplClass => typeRef(pre, implClass(sym), Nil) case _ => tp } - ) + } def implType(tp: Type): Type = tp match { case ClassInfoType(parents, decls, _) => assert(phase == implClassPhase, tp) @@ -299,14 +291,22 @@ abstract class AddInterfaces extends InfoTransform { } val mixinConstructorCalls: List[Tree] = { for (mc <- clazz.mixinClasses.reverse - if mc.hasFlag(lateINTERFACE) && mc != ScalaObjectClass) + if mc.hasFlag(lateINTERFACE)) yield mixinConstructorCall(implClass(mc)) } - (tree: @unchecked) match { + tree match { + case Block(Nil, expr) => + // AnyVal constructor - have to provide a real body so the + // jvm doesn't throw a VerifyError. But we can't add the + // body until now, because the typer knows that Any has no + // constructor and won't accept a call to super.init. + assert((clazz isSubClass AnyValClass) || clazz.info.parents.isEmpty, clazz) + val superCall = Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil) + Block(List(superCall), expr) + case Block(stats, expr) => // needs `hasSymbol` check because `supercall` could be a block (named / default args) val (presuper, supercall :: rest) = stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER)) - // assert(supercall.symbol.isClassConstructor, supercall) treeCopy.Block(tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr) } } diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index d04c6115ca..8ed44b5a31 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -94,7 +94,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { localTyper.typedPos(pos)(tree) /** A value class is defined to be only Java-compatible values: unit is - * not part of it, as opposed to isValueClass in definitions. scala.Int is + * not part of it, as opposed to isPrimitiveValueClass in definitions. scala.Int is * a value class, java.lang.Integer is not. */ def isJavaValueClass(sym: Symbol) = boxedClass contains sym def isJavaValueType(tp: Type) = isJavaValueClass(tp.typeSymbol) @@ -551,7 +551,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { case Literal(c) if (c.tag == ClassTag) && !forMSIL=> val tpe = c.typeValue typedWithPos(tree.pos) { - if (isValueClass(tpe.typeSymbol)) { + if (isPrimitiveValueClass(tpe.typeSymbol)) { if (tpe.typeSymbol == UnitClass) REF(BoxedUnit_TYPE) else diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index d8f19f85c0..4f833c82d3 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -44,11 +44,14 @@ abstract class Constructors extends Transform with ast.TreeDSL { ) // decompose primary constructor into the three entities above. val constrInfo: ConstrInfo = { - val primary = stats find (_.symbol.isPrimaryConstructor) - assert(primary.isDefined, "no constructor in template: impl = " + impl) - - val ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, _)) = primary.get + stats find (_.symbol.isPrimaryConstructor) match { + case Some(ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, _))) => ConstrInfo(ddef, vparams map (_.symbol), rhs) + case x => + // AnyVal constructor is OK + assert(clazz eq AnyValClass, "no constructor in template: impl = " + impl) + return impl + } } import constrInfo._ @@ -443,7 +446,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { localTyper.typed { atPos(impl.pos) { val closureClass = clazz.newClass(nme.delayedInitArg.toTypeName, impl.pos, SYNTHETIC | FINAL) - val closureParents = List(AbstractFunctionClass(0).tpe, ScalaObjectClass.tpe) + val closureParents = List(AbstractFunctionClass(0).tpe) closureClass setInfoAndEnter new ClassInfoType(closureParents, newScope, closureClass) @@ -565,7 +568,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { override def transform(tree: Tree): Tree = tree match { - case ClassDef(_,_,_,_) if !tree.symbol.isInterface && !isValueClass(tree.symbol) => + case ClassDef(_,_,_,_) if !tree.symbol.isInterface && !isPrimitiveValueClass(tree.symbol) => deriveClassDef(tree)(transformClassTemplate) case _ => super.transform(tree) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index d54ce78e18..a98cd5c6b1 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -31,33 +31,6 @@ abstract class Erasure extends AddInterfaces // -------- erasure on types -------------------------------------------------------- - // A type function from T => Class[U], used to determine the return - // type of getClass calls. The returned type is: - // - // 1. If T is a value type, Class[T]. - // 2. If T is a phantom type (Any or AnyVal), Class[_]. - // 3. If T is a local class, Class[_ <: |T|]. - // 4. Otherwise, Class[_ <: T]. - // - // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the - // receiver is AnyVal, it implies the receiver is boxed, so the correct - // class object is that of java.lang.Integer, not Int. - // - // TODO: If T is final, return type could be Class[T]. Should it? - def getClassReturnType(tpe: Type): Type = { - if (phase.erasedTypes) ClassClass.tpe else { - val tp = tpe.widen.normalize - val sym = tp.typeSymbol - - if (isValueClass(sym)) ClassType(tp) - else boundedClassType( - if (isPhantomClass(sym)) ObjectClass.tpe - else if (sym.isLocalClass) intersectionDominator(tp.parents) - else tp - ) - } - } - // convert a numeric with a toXXX method def numericConversion(tree: Tree, numericSym: Symbol): Tree = { val mname = newTermName("to" + numericSym.name) @@ -257,7 +230,7 @@ abstract class Erasure extends AddInterfaces // Anything which could conceivably be a module (i.e. isn't known to be // a type parameter or similar) must go through here or the signature is // likely to end up with Foo<T>.Empty where it needs Foo<T>.Empty$. - def fullNameInSig(sym: Symbol) = "L" + beforeIcode(sym.javaBinaryName.toString) + def fullNameInSig(sym: Symbol) = "L" + beforeIcode(sym.javaBinaryName) def jsig(tp0: Type, existentiallyBound: List[Symbol] = Nil, toplevel: Boolean = false, primitiveOK: Boolean = true): String = { val tp = tp0.dealias @@ -294,7 +267,7 @@ abstract class Erasure extends AddInterfaces jsig(RuntimeNothingClass.tpe) else if (sym == NullClass) jsig(RuntimeNullClass.tpe) - else if (isValueClass(sym)) { + else if (isPrimitiveValueClass(sym)) { if (!primitiveOK) jsig(ObjectClass.tpe) else if (sym == UnitClass) jsig(BoxedUnitClass.tpe) else abbrvTag(sym).toString @@ -317,7 +290,7 @@ abstract class Erasure extends AddInterfaces ) ) } - else jsig(erasure(sym0, tp), existentiallyBound, toplevel, primitiveOK) + else jsig(erasure(sym0)(tp), existentiallyBound, toplevel, primitiveOK) case PolyType(tparams, restpe) => assert(tparams.nonEmpty) val poly = if (toplevel) polyParamSig(tparams) else "" @@ -337,7 +310,7 @@ abstract class Erasure extends AddInterfaces println("something's wrong: "+sym0+":"+sym0.tpe+" has a bounded wildcard type") jsig(bounds.hi, existentiallyBound, toplevel, primitiveOK) case _ => - val etp = erasure(sym0, tp) + val etp = erasure(sym0)(tp) if (etp eq tp) throw new UnknownSig else jsig(etp) } @@ -396,36 +369,79 @@ abstract class Erasure extends AddInterfaces override def newTyper(context: Context) = new Eraser(context) - /** An extractor object for boxed expressions + private def safeToRemoveUnbox(cls: Symbol): Boolean = + (cls == definitions.NullClass) || isBoxedValueClass(cls) + + /** An extractor object for unboxed expressions (maybe subsumed by posterasure?) */ + object Unboxed { + def unapply(tree: Tree): Option[Tree] = tree match { + case Apply(fn, List(arg)) if isUnbox(fn.symbol) && safeToRemoveUnbox(arg.tpe.typeSymbol) => + Some(arg) + case Apply( + TypeApply( + cast @ Select( + Apply( + sel @ Select(arg, acc), + List()), + asinstanceof), + List(tpt)), + List()) + if cast.symbol == Object_asInstanceOf && + tpt.tpe.typeSymbol.isDerivedValueClass && + sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor => + Some(arg) + case _ => + None + } + } + + /** An extractor object for boxed expressions (maybe subsumed by posterasure?) */ object Boxed { def unapply(tree: Tree): Option[Tree] = tree match { + case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) => + Some(arg) case LabelDef(name, params, Boxed(rhs)) => Some(treeCopy.LabelDef(tree, name, params, rhs) setType rhs.tpe) - case Select(_, _) if tree.symbol == BoxedUnit_UNIT => - Some(Literal(Constant()) setPos tree.pos setType UnitClass.tpe) - case Block(List(unboxed), ret @ Select(_, _)) if ret.symbol == BoxedUnit_UNIT => - Some(if (unboxed.tpe.typeSymbol == UnitClass) tree - else Block(List(unboxed), Literal(Constant()) setPos tree.pos setType UnitClass.tpe)) - case Apply(fn, List(unboxed)) if isBox(fn.symbol) => - Some(unboxed) case _ => None } } - */ /** The modifier typer which retypes with erased types. */ class Eraser(_context: Context) extends Typer(_context) { - private def safeToRemoveUnbox(cls: Symbol): Boolean = - (cls == definitions.NullClass) || isBoxedValueClass(cls) + + private def isPrimitiveValueType(tpe: Type) = isPrimitiveValueClass(tpe.typeSymbol) + + private def isErasedValueType(tpe: Type) = tpe.isInstanceOf[ErasedValueType] + + private def isDifferentErasedValueType(tpe: Type, other: Type) = + isErasedValueType(tpe) && (tpe ne other) + + private def isPrimitiveValueMember(sym: Symbol) = + sym != NoSymbol && isPrimitiveValueClass(sym.owner) + + private def box(tree: Tree, target: => String): Tree = { + val result = box1(tree) + log("boxing "+tree+":"+tree.tpe+" to "+target+" = "+result+":"+result.tpe) + result + } /** Box `tree` of unboxed type */ - private def box(tree: Tree): Tree = tree match { + private def box1(tree: Tree): Tree = tree match { case LabelDef(_, _, _) => - val ldef = deriveLabelDef(tree)(box) + val ldef = deriveLabelDef(tree)(box1) ldef setType ldef.rhs.tpe case _ => - typedPos(tree.pos)(tree.tpe.typeSymbol match { + val tree1 = tree.tpe match { + case ErasedValueType(clazz) => + tree match { + case Unboxed(arg) if arg.tpe.typeSymbol == clazz => + log("shortcircuiting unbox -> box "+arg); arg + case _ => + New(clazz, cast(tree, underlyingOfValueClass(clazz))) + } + case _ => + tree.tpe.typeSymbol match { case UnitClass => if (treeInfo isExprSafeToInline tree) REF(BoxedUnit_UNIT) else BLOCK(tree, REF(BoxedUnit_UNIT)) @@ -445,7 +461,15 @@ abstract class Erasure extends AddInterfaces case _ => (REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectClass.tpe } - }) + } + } + typedPos(tree.pos)(tree1) + } + + private def unbox(tree: Tree, pt: Type): Tree = { + val result = unbox1(tree, pt) + log("unboxing "+tree+":"+tree.tpe+" to "+pt+" = "+result+":"+result.tpe) + result } /** Unbox `tree` of boxed type to expected type `pt`. @@ -454,7 +478,7 @@ abstract class Erasure extends AddInterfaces * @param pt the expected type. * @return the unboxed tree */ - private def unbox(tree: Tree, pt: Type): Tree = tree match { + private def unbox1(tree: Tree, pt: Type): Tree = tree match { /* case Boxed(unboxed) => println("unbox shorten: "+tree) // this never seems to kick in during build and test; therefore disabled. @@ -464,7 +488,19 @@ abstract class Erasure extends AddInterfaces val ldef = deriveLabelDef(tree)(unbox(_, pt)) ldef setType ldef.rhs.tpe case _ => - typedPos(tree.pos)(pt.typeSymbol match { + val tree1 = pt match { + case ErasedValueType(clazz) => + tree match { + case Boxed(arg) if arg.tpe.isInstanceOf[ErasedValueType] => + log("shortcircuiting box -> unbox "+arg) + arg + case _ => + log("not boxed: "+tree) + val tree0 = adaptToType(tree, clazz.tpe) + cast(Apply(Select(tree0, clazz.firstParamAccessor), List()), pt) + } + case _ => + pt.typeSymbol match { case UnitClass => if (treeInfo isExprSafeToInline tree) UNIT else BLOCK(tree, UNIT) @@ -472,7 +508,9 @@ abstract class Erasure extends AddInterfaces assert(x != ArrayClass) // don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type Apply(unboxMethod(pt.typeSymbol), tree) - }) + } + } + typedPos(tree.pos)(tree1) } /** Generate a synthetic cast operation from tree.tpe to pt. @@ -487,9 +525,6 @@ abstract class Erasure extends AddInterfaces else gen.mkAttributedCast(tree, pt) } - private def isUnboxedValueMember(sym: Symbol) = - sym != NoSymbol && isValueClass(sym.owner) - /** Adapt `tree` to expected type `pt`. * * @param tree the given tree @@ -501,29 +536,30 @@ abstract class Erasure extends AddInterfaces log("adapting " + tree + ":" + tree.tpe + " : " + tree.tpe.parents + " to " + pt)//debug if (tree.tpe <:< pt) tree - else if (isValueClass(tree.tpe.typeSymbol) && !isValueClass(pt.typeSymbol)) - adaptToType(box(tree), pt) - else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) { + else if (isDifferentErasedValueType(tree.tpe, pt)) + adaptToType(box(tree, pt.toString), pt) + else if (isDifferentErasedValueType(pt, tree.tpe)) + adaptToType(unbox(tree, pt), pt) + else if (isPrimitiveValueType(tree.tpe) && !isPrimitiveValueType(pt)) { + adaptToType(box(tree, pt.toString), pt) + } else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) { assert(tree.symbol.isStable, "adapt "+tree+":"+tree.tpe+" to "+pt) adaptToType(Apply(tree, List()) setPos tree.pos setType tree.tpe.resultType, pt) - } else if (pt <:< tree.tpe) - cast(tree, pt) - else if (isValueClass(pt.typeSymbol) && !isValueClass(tree.tpe.typeSymbol)) +// } else if (pt <:< tree.tpe) +// cast(tree, pt) + } else if (isPrimitiveValueType(pt) && !isPrimitiveValueType(tree.tpe)) adaptToType(unbox(tree, pt), pt) else cast(tree, pt) } - // @PP 1/25/2011: This is less inaccurate than it was (I removed - // BoxedAnyArray, asInstanceOf$erased, and other long ago eliminated symbols) - // but I do not think it yet describes the code beneath it. - /** Replace member references as follows: * * - `x == y` for == in class Any becomes `x equals y` with equals in class Object. * - `x != y` for != in class Any becomes `!(x equals y)` with equals in class Object. * - x.asInstanceOf[T] becomes x.$asInstanceOf[T] * - x.isInstanceOf[T] becomes x.$isInstanceOf[T] + * - x.isInstanceOf[ErasedValueType(clazz)] becomes x.isInstanceOf[clazz.tpe] * - x.m where m is some other member of Any becomes x.m where m is a member of class Object. * - x.m where x has unboxed value type T and m is not a directly translated member of T becomes T.box(x).m * - x.m where x is a reference type and m is a directly translated member of value type T becomes x.TValue().m @@ -533,22 +569,34 @@ abstract class Erasure extends AddInterfaces private def adaptMember(tree: Tree): Tree = { //Console.println("adaptMember: " + tree); tree match { - case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf => + case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) + if tree.symbol == Any_asInstanceOf => val qual1 = typedQualifier(qual, NOmode, ObjectClass.tpe) // need to have an expected type, see #3037 val qualClass = qual1.tpe.typeSymbol - val targClass = targ.tpe.typeSymbol /* + val targClass = targ.tpe.typeSymbol + if (isNumericValueClass(qualClass) && isNumericValueClass(targClass)) // convert numeric type casts atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List())) else */ - if (isValueClass(targClass)) unbox(qual1, targ.tpe) + if (isPrimitiveValueType(targ.tpe) || isErasedValueType(targ.tpe)) unbox(qual1, targ.tpe) else tree - case Select(qual, name) if (name != nme.CONSTRUCTOR) => - if (tree.symbol == NoSymbol) + case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) + if tree.symbol == Any_isInstanceOf => + targ.tpe match { + case ErasedValueType(clazz) => targ.setType(clazz.tpe) + case _ => + } tree - else if (tree.symbol == Any_asInstanceOf) + case Select(qual, name) => + if (tree.symbol == NoSymbol) { + tree + } else if (name == nme.CONSTRUCTOR) { + if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor + tree + } else if (tree.symbol == Any_asInstanceOf) adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf))) else if (tree.symbol == Any_isInstanceOf) adaptMember(atPos(tree.pos)(Select(qual, Object_isInstanceOf))) @@ -556,12 +604,13 @@ abstract class Erasure extends AddInterfaces adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, name)))) else { var qual1 = typedQualifier(qual) - if ((isValueClass(qual1.tpe.typeSymbol) && !isUnboxedValueMember(tree.symbol))) - qual1 = box(qual1) - else if (!isValueClass(qual1.tpe.typeSymbol) && isUnboxedValueMember(tree.symbol)) + if ((isPrimitiveValueType(qual1.tpe) && !isPrimitiveValueMember(tree.symbol)) || + isErasedValueType(qual1.tpe)) + qual1 = box(qual1, "owner "+tree.symbol.owner) + else if (!isPrimitiveValueType(qual1.tpe) && isPrimitiveValueMember(tree.symbol)) qual1 = unbox(qual1, tree.symbol.owner.tpe) - if (isValueClass(tree.symbol.owner) && !isValueClass(qual1.tpe.typeSymbol)) + if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe)) tree.symbol = NoSymbol else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.params.isEmpty) { assert(qual1.symbol.isStable, qual1.symbol); @@ -590,13 +639,22 @@ abstract class Erasure extends AddInterfaces */ override protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = { val tree1 = try { + tree match { + case InjectDerivedValue(arg) => + val clazz = tree.symbol + val result = typed1(arg, mode, underlyingOfValueClass(clazz)) setType ErasedValueType(clazz) + log("transforming inject "+arg+":"+underlyingOfValueClass(clazz)+"/"+ErasedValueType(clazz)+" = "+result) + return result + + case _ => super.typed1(adaptMember(tree), mode, pt) + } } catch { case er: TypeError => Console.println("exception when typing " + tree) Console.println(er.msg + " in file " + context.owner.sourceFile) er.printStackTrace - abort() + abort("unrecoverable error") case ex: Exception => //if (settings.debug.value) try Console.println("exception when typing " + tree) @@ -646,6 +704,7 @@ abstract class Erasure extends AddInterfaces * but their erased types are the same. */ private def checkNoDoubleDefs(root: Symbol) { + def afterErasure[T](op: => T): T = atPhase(phase.next.next)(op) def doubleDefError(sym1: Symbol, sym2: Symbol) { // the .toString must also be computed at the earlier phase val tpe1 = afterRefchecks(root.thisType.memberType(sym1)) @@ -740,7 +799,7 @@ abstract class Erasure extends AddInterfaces var bridges: List[Tree] = List() val opc = beforeExplicitOuter { new overridingPairs.Cursor(owner) { - override def parents: List[Type] = List(owner.info.parents.head) + override def parents: List[Type] = List(owner.info.firstParent) override def exclude(sym: Symbol): Boolean = !sym.isMethod || sym.isPrivate || super.exclude(sym) } @@ -750,7 +809,7 @@ abstract class Erasure extends AddInterfaces val other = opc.overridden //println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG if (beforeExplicitOuter(!member.isDeferred)) { - val otpe = erasure(owner, other.tpe) + val otpe = erasure(owner)(other.tpe) val bridgeNeeded = afterErasure ( !(other.tpe =:= member.tpe) && !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) && @@ -795,7 +854,7 @@ abstract class Erasure extends AddInterfaces IF (typeTest) THEN bridgingCall ELSE REF(NoneModule) } else bridgingCall }); - debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner, member.tpe) + member.locationString + " =\n " + bridgeDef); + debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner)(member.tpe) + member.locationString + " =\n " + bridgeDef); bridgeDef } } :: bridges @@ -841,6 +900,7 @@ abstract class Erasure extends AddInterfaces * - Given a selection q.s, where the owner of `s` is not accessible but the * type symbol of q's type qT is accessible, insert a cast (q.asInstanceOf[qT]).s * This prevents illegal access errors (see #4283). + * - Remove all instance creations new C(arg) where C is an inlined class. * - Reset all other type attributes to null, thus enforcing a retyping. */ private val preTransformer = new TypingTransformer(unit) { @@ -866,7 +926,7 @@ abstract class Erasure extends AddInterfaces gen.mkMethodCall( qual1(), fun.symbol, - List(erasure(fun.symbol, arg.tpe)), + List(specialErasure(fun.symbol)(arg.tpe)), Nil ), isArrayTest(qual1()) @@ -899,7 +959,7 @@ abstract class Erasure extends AddInterfaces // need to do the cast in adaptMember treeCopy.Apply( tree, - SelectFromArray(qual, name, erasure(tree.symbol, qual.tpe)).copyAttrs(fn), + SelectFromArray(qual, name, erasure(tree.symbol)(qual.tpe)).copyAttrs(fn), args) } case Apply(fn @ Select(qual, _), Nil) if interceptedMethods(fn.symbol) => @@ -918,12 +978,18 @@ abstract class Erasure extends AddInterfaces } } // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) - else if (isValueClass(qual.tpe.typeSymbol)) + else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual))) else tree + case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) => + InjectDerivedValue(arg) setSymbol tpt.tpe.typeSymbol case Apply(fn, args) => + def qualifier = fn match { + case Select(qual, _) => qual + case TypeApply(Select(qual, _), _) => qual + } if (fn.symbol == Any_asInstanceOf) (fn: @unchecked) match { case TypeApply(Select(qual, _), List(targ)) => @@ -938,7 +1004,7 @@ abstract class Erasure extends AddInterfaces else if (fn.symbol == Any_isInstanceOf) { fn match { case TypeApply(sel @ Select(qual, name), List(targ)) => - if (qual.tpe != null && isValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefClass.tpe) + if (qual.tpe != null && isPrimitiveValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefClass.tpe) unit.error(sel.pos, "isInstanceOf cannot test if value types are references.") def mkIsInstanceOf(q: () => Tree)(tp: Type): Tree = @@ -973,20 +1039,13 @@ abstract class Erasure extends AddInterfaces } case _ => tree } - } - else { - def doDynamic(fn: Tree, qual: Tree): Tree = { - if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) - ApplyDynamic(qual, args) setSymbol fn.symbol setPos tree.pos - else tree - } - fn match { - case Select(qual, _) => doDynamic(fn, qual) - case TypeApply(fni@Select(qual, _), _) => doDynamic(fni, qual)// type parameters are irrelevant in case of dynamic call - case _ => + } else if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) { + ApplyDynamic(qualifier, args) setSymbol fn.symbol setPos tree.pos + } else if (fn.symbol.isMethodWithExtension) { + Apply(gen.mkAttributedRef(extensionMethods.extensionMethod(fn.symbol)), qualifier :: args) + } else { tree } - } case Select(qual, name) => val owner = tree.symbol.owner @@ -1019,7 +1078,11 @@ abstract class Erasure extends AddInterfaces case Literal(ct) if ct.tag == ClassTag && ct.typeValue.typeSymbol != definitions.UnitClass => - treeCopy.Literal(tree, Constant(erasure(NoSymbol, ct.typeValue))) + val erased = ct.typeValue match { + case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz) + case tpe => specialScalaErasure(tpe) + } + treeCopy.Literal(tree, Constant(erased)) case _ => tree @@ -1037,10 +1100,13 @@ abstract class Erasure extends AddInterfaces val tree1 = preErase(tree) tree1 match { case EmptyTree | TypeTree() => - tree1 setType erasure(NoSymbol, tree1.tpe) + tree1 setType specialScalaErasure(tree1.tpe) + case ArrayValue(elemtpt, trees) => + treeCopy.ArrayValue( + tree1, elemtpt setType specialScalaErasure.applyInArray(elemtpt.tpe), trees map transform) setType null case DefDef(_, _, _, _, tpt, _) => val result = super.transform(tree1) setType null - tpt.tpe = erasure(tree1.symbol, tree1.symbol.tpe).resultType + tpt.tpe = specialErasure(tree1.symbol)(tree1.symbol.tpe).resultType result case _ => super.transform(tree1) setType null @@ -1054,6 +1120,7 @@ abstract class Erasure extends AddInterfaces */ override def transform(tree: Tree): Tree = { val tree1 = preTransformer.transform(tree) + log("tree after pretransform: "+tree1) afterErasure { val tree2 = mixinTransformer.transform(tree1) debuglog("tree after addinterfaces: \n" + tree2) diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala new file mode 100644 index 0000000000..e6ad7cb922 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -0,0 +1,163 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ +package scala.tools.nsc +package transform + +import symtab._ +import Flags._ +import scala.collection.{ mutable, immutable } +import scala.collection.mutable +import scala.tools.nsc.util.FreshNameCreator +import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple } + +/** + * Perform Step 1 in the inline classes SIP: Creates extension methods for all + * methods in a value class, except parameter or super accessors, or constructors. + * + * @author Martin Odersky + * @version 2.10 + */ +abstract class ExtensionMethods extends Transform with TypingTransformers { + + import global._ // the global environment + import definitions._ // standard classes and methods + import typer.{ typed, atOwner } // methods to type trees + + /** the following two members override abstract members in Transform */ + val phaseName: String = "extmethods" + + def newTransformer(unit: CompilationUnit): Transformer = + new Extender(unit) + + /** Generate stream of possible names for the extension version of given instance method `imeth`. + * If the method is not overloaded, this stream consists of just "extension$imeth". + * If the method is overloaded, the stream has as first element "extensionX$imeth", where X is the + * index of imeth in the sequence of overloaded alternatives with the same name. This choice will + * always be picked as the name of the generated extension method. + * After this first choice, all other possible indices in the range of 0 until the number + * of overloaded alternatives are returned. The secondary choices are used to find a matching method + * in `extensionMethod` if the first name has the wrong type. We thereby gain a level of insensitivity + * of how overloaded types are ordered between phases and picklings. + */ + private def extensionNames(imeth: Symbol): Stream[Name] = + imeth.owner.info.decl(imeth.name).tpe match { + case OverloadedType(_, alts) => + val index = alts indexOf imeth + assert(index >= 0, alts+" does not contain "+imeth) + def altName(index: Int) = newTermName("extension"+index+"$"+imeth.name) + altName(index) #:: ((0 until alts.length).toStream filter (index !=) map altName) + case tpe => + assert(tpe != NoType, imeth.name+" not found in "+imeth.owner+"'s decls: "+imeth.owner.info.decls) + Stream(newTermName("extension$"+imeth.name)) + } + + /** Return the extension method that corresponds to given instance method `meth`. + */ + def extensionMethod(imeth: Symbol): Symbol = atPhase(currentRun.refchecksPhase) { + val companionInfo = imeth.owner.companionModule.info + val candidates = extensionNames(imeth) map (companionInfo.decl(_)) + val matching = candidates filter (alt => normalize(alt.tpe, imeth.owner) matches imeth.tpe) + assert(matching.nonEmpty, "no extension method found for "+imeth+" among "+candidates+"/"+extensionNames(imeth)) + matching.head + } + + private def normalize(stpe: Type, clazz: Symbol): Type = stpe match { + case PolyType(tparams, restpe) => + GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe, clazz)) + case MethodType(tparams, restpe) => + restpe + case _ => + stpe + } + + class Extender(unit: CompilationUnit) extends TypingTransformer(unit) { + + private val extensionDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]() + + def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = { + var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) + val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpe)) + val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType + def transform(clonedType: Type): Type = clonedType match { + case MethodType(params, restpe) => + // I assume it was a bug that this was dropping params... [Martin]: No, it wasn't; it's curried. + MethodType(List(thisParam), clonedType) + case NullaryMethodType(restpe) => + MethodType(List(thisParam), restpe) + } + val GenPolyType(tparams, restpe) = origInfo cloneInfo extensionMeth + GenPolyType(tparams ::: newTypeParams, transform(restpe) substSym (clazz.typeParams, newTypeParams)) + } + + private def allParams(tpe: Type): List[Symbol] = tpe match { + case MethodType(params, res) => params ::: allParams(res) + case _ => List() + } + + override def transform(tree: Tree): Tree = { + tree match { + case Template(_, _, _) => + if (currentOwner.isDerivedValueClass) { + extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree] + super.transform(tree) + } else if (currentOwner.isStaticOwner) { + super.transform(tree) + } else tree + case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension => + val companion = currentOwner.companionModule + val origMeth = tree.symbol + val extensionName = extensionNames(origMeth).head + val extensionMeth = companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL) + .setAnnotations(origMeth.annotations) + companion.info.decls.enter(extensionMeth) + val newInfo = extensionMethInfo(extensionMeth, origMeth.info, currentOwner) + extensionMeth setInfo newInfo + log("Value class %s spawns extension method.\n Old: %s\n New: %s".format( + currentOwner, + origMeth.defString, + extensionMeth.defString)) // extensionMeth.defStringSeenAs(origInfo + + def thisParamRef = gen.mkAttributedIdent(extensionMeth.info.params.head setPos extensionMeth.pos) + val GenPolyType(extensionTpeParams, extensionMono) = extensionMeth.info + val origTpeParams = (tparams map (_.symbol)) ::: currentOwner.typeParams + val extensionBody = rhs + .substTreeSyms(origTpeParams, extensionTpeParams) + .substTreeSyms(vparamss.flatten map (_.symbol), allParams(extensionMono).tail) + .substTreeThis(currentOwner, thisParamRef) + .changeOwner((origMeth, extensionMeth)) + extensionDefs(companion) += atPos(tree.pos) { DefDef(extensionMeth, extensionBody) } + val extensionCallPrefix = Apply( + gen.mkTypeApply(gen.mkAttributedRef(companion), extensionMeth, origTpeParams map (_.tpe)), + List(This(currentOwner))) + val extensionCall = atOwner(origMeth) { + localTyper.typed { + atPos(rhs.pos) { + (extensionCallPrefix /: vparamss) { + case (fn, params) => Apply(fn, params map (param => Ident(param.symbol))) + } + } + } + } + treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, extensionCall) + case _ => + super.transform(tree) + } + } + + override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = + super.transformStats(stats, exprOwner) map { + case stat @ ModuleDef(mods, name, tmpl @ Template(parents, self, body)) => + extensionDefs.remove(stat.symbol) match { + case Some(buf) => + val extensionDefs = buf.toList map { mdef => atOwner(stat.symbol) { localTyper.typed(mdef) } } + treeCopy.ModuleDef(stat, mods, name, treeCopy.Template(tmpl, parents, self, body ++ extensionDefs)) + case None => + stat + } + case stat => + stat + } + } +} diff --git a/src/compiler/scala/tools/nsc/transform/InlineErasure.scala b/src/compiler/scala/tools/nsc/transform/InlineErasure.scala new file mode 100644 index 0000000000..0af3cf732f --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/InlineErasure.scala @@ -0,0 +1,9 @@ +package scala.tools.nsc +package transform + +trait InlineErasure { self: Erasure => + + import global._ + import definitions._ + +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 570eaba3a9..13ca8e55bc 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -25,7 +25,7 @@ abstract class LambdaLift extends InfoTransform { if (sym.isCapturedVariable) { val symClass = tpe.typeSymbol def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = - if (isValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe + if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe else if (erasedTypes) objectRefClass.tpe else appliedType(objectRefClass.typeConstructor, List(tpe)) if (sym.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 865c5fa621..dfadd8d60e 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -450,7 +450,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { if ((sym.hasAccessorFlag || (sym.isTerm && !sym.isMethod)) && sym.isPrivate && !(currentOwner.isGetter && currentOwner.accessed == sym) // getter - && !definitions.isValueClass(sym.tpe.resultType.typeSymbol) + && !definitions.isPrimitiveValueClass(sym.tpe.resultType.typeSymbol) && sym.owner == templ.symbol.owner && !sym.isLazy && !tree.isDef) { @@ -522,7 +522,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { localTyper = erasure.newTyper(rootContext.make(tree, currentOwner)) afterMixin(currentOwner.owner.info)//todo: needed? - if (!currentOwner.isTrait && !isValueClass(currentOwner)) + if (!currentOwner.isTrait && !isPrimitiveValueClass(currentOwner)) addMixedinMembers(currentOwner, unit) else if (currentOwner hasFlag lateINTERFACE) addLateInterfaceMembers(currentOwner) diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala new file mode 100644 index 0000000000..ef158a71f6 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -0,0 +1,68 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Martin odersky + */ +package scala.tools.nsc +package transform + +/** This phase maps ErasedValueTypes to the underlying unboxed representation and + * performs peephole optimizations. + */ +trait PostErasure extends InfoTransform with TypingTransformers { + + val global: Global + import global._ + import definitions._ + + val phaseName: String = "posterasure" + + def newTransformer(unit: CompilationUnit): Transformer = new PostErasureTransformer(unit) + override def changesBaseClasses = false + + object elimErasedValueType extends TypeMap { + def apply(tp: Type) = tp match { + case ErasedValueType(clazz) => erasure.underlyingOfValueClass(clazz) + case _ => mapOver(tp) + } + } + + def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp) + + class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + + override def transform(tree: Tree) = + super.transform(tree) setType elimErasedValueType(tree.tpe) match { + case // new C(arg).underlying ==> arg + Apply(sel @ Select( + Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)), + acc), List()) + if atPhase(currentRun.erasurePhase) { + tpt.tpe.typeSymbol.isDerivedValueClass && + sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor + } => + if (settings.debug.value) log("Removing "+tree+" -> "+arg) + arg + case // new C(arg1) == new C(arg2) ==> arg1 == arg2 + Apply(sel @ Select( + Apply(Select(New(tpt1), nme.CONSTRUCTOR), List(arg1)), + cmp), + List(Apply(Select(New(tpt2), nme.CONSTRUCTOR), List(arg2)))) + if atPhase(currentRun.erasurePhase) { + tpt1.tpe.typeSymbol.isDerivedValueClass && + (cmp == nme.EQ || cmp == nme.NE) && + tpt2.tpe.typeSymbol == tpt1.tpe.typeSymbol + } => + val result = Apply(Select(arg1, cmp) setPos sel.pos, List(arg2)) setPos tree.pos + log("shortcircuiting equality "+tree+" -> "+result) + localTyper.typed(result) + + case // arg.asInstanceOf[T] ==> arg if arg.tpe == T + Apply(TypeApply(cast @ Select(arg, asinstanceof), List(tpt)), List()) + if cast.symbol == Object_asInstanceOf && arg.tpe =:= tpt.tpe => // !!! <:< ? + if (settings.debug.value) log("Shortening "+tree+" -> "+arg) + arg + case tree1 => + tree1 + } + } +} diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 88ad458748..7b0f5254b6 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -66,7 +66,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, - ScalaValueClasses, isValueClass, isScalaValueType, + ScalaValueClasses, isPrimitiveValueClass, isScalaValueType, SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass, AnyRefClass, ObjectClass, AnyRefModule, GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass @@ -123,14 +123,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // then pos/spec-List.scala fails - why? Does this kind of check fail // for similar reasons? Does `sym.isAbstractType` make a difference? private def isSpecializedAnyRefSubtype(tp: Type, sym: Symbol) = { - specializedOn(sym).exists(s => !isValueClass(s)) && - !isValueClass(tp.typeSymbol) && + specializedOn(sym).exists(s => !isPrimitiveValueClass(s)) && + !isPrimitiveValueClass(tp.typeSymbol) && isBoundedGeneric(tp) //(tp <:< AnyRefClass.tpe) } private def isBoundedGeneric(tp: Type) = tp match { case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe) - case TypeRef(_, sym, _) => !isValueClass(sym) + case TypeRef(_, sym, _) => !isPrimitiveValueClass(sym) case _ => false } @@ -348,7 +348,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ def specializesClass(sym: Symbol): Symbol = { val c = sym.companionClass - if (isValueClass(c)) c else AnyRefClass + if (isPrimitiveValueClass(c)) c else AnyRefClass } /** Return the types `sym` should be specialized at. This may be some of the primitive types @@ -587,7 +587,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { " => " + sClass.defStringSeenAs(sClass.typeOfThis) ) } - polyType(newClassTParams, ClassInfoType(parents ::: extraSpecializedMixins, decls1, sClass)) + GenPolyType(newClassTParams, ClassInfoType(parents ::: extraSpecializedMixins, decls1, sClass)) } afterSpecialize(sClass setInfo specializedInfoType) @@ -818,7 +818,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // the cloneInfo is necessary so that method parameter symbols are cloned at the new owner val methodType = sym.info.resultType.instantiateTypeParams(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember) - specMember setInfo polyType(tps1, methodType) + specMember setInfo GenPolyType(tps1, methodType) debuglog("expanded member: " + sym + ": " + sym.info + " -> " + specMember + @@ -994,7 +994,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean): TypeEnv = (tp1, tp2) match { case (TypeRef(_, sym1, _), _) if isSpecialized(sym1) => debuglog("Unify - basic case: " + tp1 + ", " + tp2) - if (isValueClass(tp2.typeSymbol)) + if (isPrimitiveValueClass(tp2.typeSymbol) || isSpecializedAnyRefSubtype(tp2, sym1)) env + ((sym1, tp2)) else if (isSpecializedAnyRefSubtype(tp2, sym1)) env + ((sym1, tp2)) // env + ((sym1, AnyRefClass.tpe)) @@ -1130,7 +1130,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { ) val newScope = newScopeWith(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz): _*) // If tparams.isEmpty, this is just the ClassInfoType. - polyType(tparams, ClassInfoType(parents1, newScope, clazz)) + GenPolyType(tparams, ClassInfoType(parents1, newScope, clazz)) case _ => tpe } @@ -1342,7 +1342,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val env = typeEnv(specMember) val residualTargs = symbol.info.typeParams zip targs collect { - case (tvar, targ) if !env.contains(tvar) || !isValueClass(env(tvar).typeSymbol) => targ + case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ } ifDebug(assert(residualTargs.length == specMember.info.typeParams.length, diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index e511653cca..ed9fee986f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -531,7 +531,7 @@ trait ContextErrors { NormalTypeError(parent, "illegal inheritance from final "+mixin) def ParentSealedInheritanceError(parent: Tree, psym: Symbol) = - NormalTypeError(parent, "illegal inheritance from sealed " + psym + ": " + context.unit.source.file.canonicalPath + " != " + psym.sourceFile.canonicalPath) + NormalTypeError(parent, "illegal inheritance from sealed " + psym ) def ParentSelfTypeConformanceError(parent: Tree, selfType: Type) = NormalTypeError(parent, @@ -770,7 +770,7 @@ trait ContextErrors { def PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], pt: Type) = issueNormalTypeError(tree, "polymorphic expression cannot be instantiated to expected type" + - foundReqMsg(polyType(undetparams, skipImplicit(tree.tpe)), pt)) + foundReqMsg(GenPolyType(undetparams, skipImplicit(tree.tpe)), pt)) //checkCheckable def TypePatternOrIsInstanceTestError(tree: Tree, tp: Type) = diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 2c564c097f..a1ba8a2982 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -43,8 +43,7 @@ trait Contexts { self: Analyzer => * - if option `-Yno-imports` is given, nothing is imported * - if the unit is java defined, only `java.lang` is imported * - if option `-Yno-predef` is given, if the unit body has an import of Predef - * among its leading imports, or if the tree is [[scala.ScalaObject]] - * or [[scala.Predef]], `Predef` is not imported. + * among its leading imports, or if the tree is [[scala.Predef]], `Predef` is not imported. */ protected def rootImports(unit: CompilationUnit): List[Symbol] = { import definitions._ diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 0ddacf7d36..7d1198a4a2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1094,7 +1094,11 @@ trait Implicits { /** Creates a tree that calls the factory method called constructor in object reflect.Manifest */ def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree = if (args contains EmptyTree) EmptyTree - else typedPos(tree.pos.focus)(gen.mkManifestFactoryCall(full, constructor, tparg, args.toList)) + else typedPos(tree.pos.focus) { + val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList) + if (settings.debug.value) println("generated manifest: "+mani) // DEBUG + mani + } /** Creates a tree representing one of the singleton manifests.*/ def findSingletonManifest(name: String) = typedPos(tree.pos.focus) { @@ -1119,7 +1123,7 @@ trait Implicits { case ConstantType(value) => manifestOfType(tp1.deconst, full) case TypeRef(pre, sym, args) => - if (isValueClass(sym) || isPhantomClass(sym)) { + if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) { findSingletonManifest(sym.name.toString) } else if (sym == ObjectClass || sym == AnyRefClass) { findSingletonManifest("Object") diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index c0c801910c..8b3bc253fd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -196,6 +196,10 @@ trait Infer { /* -- Error Messages --------------------------------------------------- */ def setError[T <: Tree](tree: T): T = { + if (settings.debug.value) { // DEBUG + println("set error: "+tree); + throw new Error() + } def name = newTermName("<error: " + tree.symbol + ">") def errorClass = if (context.reportErrors) context.owner.newErrorClass(name.toTypeName) else stdErrorClass def errorValue = if (context.reportErrors) context.owner.newErrorValue(name) else stdErrorValue diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 82bcb93965..955d51bf8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -73,7 +73,7 @@ trait Namers extends MethodSynthesis { classAndNamerOfModule.clear() } - abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors { + abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors { thisNamer => import NamerErrorGen._ val typer = newTyper(context) @@ -99,6 +99,13 @@ trait Namers extends MethodSynthesis { owner.unsafeTypeParams foreach (paramContext.scope enter _) newNamer(paramContext) } + + def enclosingNamerWithScope(scope: Scope) = { + var cx = context + while (cx != NoContext && cx.scope != scope) cx = cx.outer + if (cx == NoContext || cx == context) thisNamer + else newNamer(cx) + } def enterValueParams(vparamss: List[List[ValDef]]): List[List[Symbol]] = { mmap(vparamss) { param => @@ -709,6 +716,17 @@ trait Namers extends MethodSynthesis { if (needsCycleCheck && !typer.checkNonCyclic(tree.pos, tp)) sym setInfo ErrorType } + // tree match { + // case ClassDef(_, _, _, impl) => + // val parentsOK = ( + // treeInfo.isInterface(sym, impl.body) + // || (sym eq ArrayClass) + // || (sym isSubClass AnyValClass) + // ) + // if (!parentsOK) + // ensureParent(sym, AnyRefClass) + // case _ => () + // } } def moduleClassTypeCompleter(tree: Tree) = { @@ -840,6 +858,7 @@ trait Namers extends MethodSynthesis { } val parents = typer.parentTypes(templ) map checkParent + enterSelf(templ.self) val decls = newScope @@ -890,7 +909,7 @@ trait Namers extends MethodSynthesis { val tparams0 = typer.reenterTypeParams(tparams) val resultType = templateSig(impl) - polyType(tparams0, resultType) + GenPolyType(tparams0, resultType) } private def methodSig(ddef: DefDef, mods: Modifiers, tparams: List[TypeDef], @@ -933,7 +952,7 @@ trait Namers extends MethodSynthesis { // DEPMETTODO: check not needed when they become on by default checkDependencies(restpe) - polyType( + GenPolyType( tparamSyms, // deSkolemized symbols -- TODO: check that their infos don't refer to method args? if (vparamSymss.isEmpty) NullaryMethodType(restpe) // vparamss refer (if they do) to skolemized tparams @@ -1187,7 +1206,7 @@ trait Namers extends MethodSynthesis { // However, separate compilation requires the symbol info to be // loaded to do this check, but loading the info will probably // lead to spurious cyclic errors. So omit the check. - polyType(tparamSyms, tp) + GenPolyType(tparamSyms, tp) } /** Given a case class @@ -1251,8 +1270,15 @@ trait Namers extends MethodSynthesis { if (sym.isModule) annotate(sym.moduleClass) def getSig = tree match { - case ClassDef(_, _, tparams, impl) => - createNamer(tree).classSig(tparams, impl) + case cdef @ ClassDef(_, _, tparams, impl) => + val clazz = tree.symbol + val result = createNamer(tree).classSig(tparams, impl) + clazz setInfo result + if (clazz.isDerivedValueClass) { + clazz setFlag FINAL + enclosingNamerWithScope(clazz.owner.info.decls).ensureCompanionObject(cdef) + } + result case ModuleDef(_, _, impl) => val clazz = sym.moduleClass @@ -1308,6 +1334,22 @@ trait Namers extends MethodSynthesis { } } + def includeParent(tpe: Type, parent: Symbol): Type = tpe match { + case PolyType(tparams, restpe) => + PolyType(tparams, includeParent(restpe, parent)) + case ClassInfoType(parents, decls, clazz) => + if (parents exists (_.typeSymbol == parent)) tpe + else ClassInfoType(parents :+ parent.tpe, decls, clazz) + case _ => + tpe + } + + def ensureParent(clazz: Symbol, parent: Symbol) = { + val info0 = clazz.info + val info1 = includeParent(info0, parent) + if (info0 ne info1) clazz setInfo info1 + } + class LogTransitions[S](onEnter: S => String, onExit: S => String) { val enabled = settings.debug.value @inline final def apply[T](entity: S)(body: => T): T = { @@ -1411,7 +1453,7 @@ trait Namers extends MethodSynthesis { checkNoConflict(PRIVATE, PROTECTED) // checkNoConflict(PRIVATE, OVERRIDE) // this one leads to bad error messages like #4174, so catch in refchecks // checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant - checkNoConflict(ABSTRACT, FINAL) + // checkNoConflict(ABSTRACT, FINAL) // this one gives a bad error for non-@inline classes which extend AnyVal // @PP: I added this as a sanity check because these flags are supposed to be // converted to ABSOVERRIDE before arriving here. checkNoConflict(ABSTRACT, OVERRIDE) diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index e8d3b7a7de..c621497618 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -224,7 +224,7 @@ trait NamesDefaults { self: Analyzer => case Select(sp @ Super(_, _), _) if isConstr => // 'moduleQual' fixes #3207. selection of the companion module of the // superclass needs to have the same prefix as the superclass. - blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.parents.head)) + blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.firstParent)) // self constructor calls (in secondary constructors) case Select(tp, name) if isConstr => diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 507ffd55d7..1e17cb2e3f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -525,7 +525,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R !other.isDeferred && other.isJavaDefined && { // #3622: erasure operates on uncurried types -- // note on passing sym in both cases: only sym.isType is relevant for uncurry.transformInfo - def uncurryAndErase(tp: Type) = erasure.erasure(sym, uncurry.transformInfo(sym, tp)) + // !!! erasure.erasure(sym, uncurry.transformInfo(sym, tp)) gives erreneous of inaccessible type - check whether that's still the case! + def uncurryAndErase(tp: Type) = erasure.erasure(sym)(uncurry.transformInfo(sym, tp)) val tp1 = uncurryAndErase(clazz.thisType.memberType(sym)) val tp2 = uncurryAndErase(clazz.thisType.memberType(other)) afterErasure(tp1 matches tp2) @@ -693,8 +694,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R if (abstractErrors.nonEmpty) unit.error(clazz.pos, abstractErrorMessage) - } else if (clazz.isTrait) { - // prevent abstract methods in interfaces that override final members in Object; see #4431 + } + else if (clazz.isTrait && !(clazz isSubClass AnyValClass)) { + // For non-AnyVal classes, prevent abstract methods in interfaces that override + // final members in Object; see #4431 for (decl <- clazz.info.decls.iterator) { val overridden = decl.overriddenSymbol(ObjectClass) if (overridden.isFinal) @@ -1061,7 +1064,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) - def isSpecial(s: Symbol) = isValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s) + def isSpecial(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s) def possibleNumericCount = onSyms(_ filter (x => isNumeric(x) || isMaybeValue(x)) size) val nullCount = onSyms(_ filter (_ == NullClass) size) @@ -1082,7 +1085,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R if (nullCount == 2) nonSensible("", true) // null == null else if (nullCount == 1) { - if (onSyms(_ exists isValueClass)) // null == 5 + if (onSyms(_ exists isPrimitiveValueClass)) // null == 5 nonSensible("", false) else if (onTrees( _ exists isNew)) // null == new AnyRef nonSensibleWarning("a fresh object", false) @@ -1122,7 +1125,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R // warn only if they have no common supertype below Object else { val common = global.lub(List(actual.tpe, receiver.tpe)) - if (common.typeSymbol == ScalaObjectClass || (ObjectClass.tpe <:< common)) + if (ObjectClass.tpe <:< common) unrelatedTypes() } } @@ -1470,7 +1473,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R if (settings.Xmigration28.value) checkMigration(sym, tree.pos) - if (currentClass != sym.owner && sym.hasLocalFlag) { + if (sym eq NoSymbol) { + unit.warning(tree.pos, "Select node has NoSymbol! " + tree + " / " + tree.tpe) + } + else if (currentClass != sym.owner && sym.hasLocalFlag) { var o = currentClass var hidden = false while (!hidden && o != sym.owner && o != sym.owner.moduleClass && !o.isPackage) { @@ -1517,6 +1523,19 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R case _ => () } + // verify classes extending AnyVal meet the requirements + // (whatever those are to be, but at least: @inline annotation) + private def checkAnyValSubclass(clazz: Symbol) = { + if ((clazz isSubClass AnyValClass) && (clazz ne AnyValClass) && !isPrimitiveValueClass(clazz)) { + if (clazz.isTrait) + unit.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal") + /* [Martin] That one is already taken care of by Typers + if (clazz.tpe <:< AnyRefClass.tpe) + unit.error(clazz.pos, "Classes which extend AnyVal may not have an ancestor which inherits AnyRef") + */ + } + } + override def transform(tree: Tree): Tree = { val savedLocalTyper = localTyper val savedCurrentApplication = currentApplication @@ -1548,6 +1567,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R checkOverloadedRestrictions(currentOwner) val bridges = addVarargBridges(currentOwner) checkAllOverrides(currentOwner) + checkAnyValSubclass(currentOwner) if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree case dc@TypeTreeWithDeferredRefCheck() => assert(false, "adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc"); dc diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 243e685b13..4248b6f024 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -266,6 +266,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT } transformSuperSelect(sel) + case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension => + treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, withInvalidOwner(transform(rhs))) + case TypeApply(sel @ Select(qual, name), args) => mayNeedProtectedAccessor(sel, args, true) diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 7559b78db3..f9d41bcc5e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -39,6 +39,7 @@ trait SyntheticMethods extends ast.TreeDSL { /** Add the synthetic methods to case classes. */ def addSyntheticMethods(templ: Template, clazz0: Symbol, context: Context): Template = { + if (phase.erasedTypes) return templ @@ -48,6 +49,17 @@ trait SyntheticMethods extends ast.TreeDSL { ) import synthesizer._ + if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return { + if (clazz0.info member nme.getClass_ isDeferred) { + val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe)) { sym => + // XXX dummy implementation for now + NULL + } + treeCopy.Template(templ, templ.parents, templ.self, templ.body :+ getClassMethod) + } + else templ + } + val originalAccessors = clazz.caseFieldAccessors // private ones will have been renamed -- make sure they are entered // in the original order. @@ -85,8 +97,8 @@ trait SyntheticMethods extends ast.TreeDSL { def hasOverridingImplementation(meth: Symbol) = { val sym = clazz.info nonPrivateMember meth.name - sym.alternatives filterNot (_ eq meth) exists { m0 => - !m0.isDeferred && !m0.isSynthetic && (typeInClazz(m0) matches typeInClazz(meth)) + sym.alternatives exists { m0 => + (m0 ne meth) && !m0.isDeferred && !m0.isSynthetic && (m0.owner != AnyValClass) && (typeInClazz(m0) matches typeInClazz(meth)) } } def readConstantValue[T](name: String, default: T = null.asInstanceOf[T]): T = { @@ -111,13 +123,49 @@ trait SyntheticMethods extends ast.TreeDSL { // def productElementNameMethod = perElementMethod(nme.productElementName, StringClass.tpe)(x => LIT(x.name.toString)) + var syntheticCanEqual = false + /** The canEqual method for case classes. * def canEqual(that: Any) = that.isInstanceOf[This] */ - def canEqualMethod: Tree = ( + def canEqualMethod: Tree = { + syntheticCanEqual = true createMethod(nme.canEqual_, List(AnyClass.tpe), BooleanClass.tpe)(m => Ident(m.firstParam) IS_OBJ classExistentialType(clazz)) - ) + } + + /** (that.isInstanceOf[this.C]) + * where that is the given methods first parameter. + */ + def thatTest(eqmeth: Symbol): Tree = + gen.mkIsInstanceOf(Ident(eqmeth.firstParam), typeCaseType(clazz), true, false) + + /** (that.asInstanceOf[this.C]) + * where that is the given methods first parameter. + */ + def thatCast(eqmeth: Symbol): Tree = + gen.mkCast(Ident(eqmeth.firstParam), clazz.tpe) + + /** The equality method core for case classes and inline clases. + * 1+ args: + * (that.isInstanceOf[this.C]) && { + * val x$1 = that.asInstanceOf[this.C] + * (this.arg_1 == x$1.arg_1) && (this.arg_2 == x$1.arg_2) && ... && (x$1 canEqual this) + * } + * Drop canBuildFrom part if class is final and canBuildFrom is synthesized + */ + def equalsCore(eqmeth: Symbol, accessors: List[Symbol]) = { + val otherName = context.unit.freshTermName(clazz.name + "$") + val otherSym = eqmeth.newValue(otherName, eqmeth.pos, SYNTHETIC) setInfo clazz.tpe + val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc))) + val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz))) + val tests = if (clazz.isDerivedValueClass || clazz.isFinal && syntheticCanEqual) pairwise else pairwise :+ canEq + + thatTest(eqmeth) AND Block( + ValDef(otherSym, thatCast(eqmeth)), + AND(tests: _*) + ) + } /** The equality method for case classes. * 0 args: @@ -130,34 +178,36 @@ trait SyntheticMethods extends ast.TreeDSL { * } * } */ - def equalsClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m => - val arg0 = Ident(m.firstParam) - val thatTest = gen.mkIsInstanceOf(arg0, classExistentialType(clazz), true, false) - val thatCast = gen.mkCast(arg0, clazz.tpe) - - def argsBody: Tree = { - val otherName = context.unit.freshTermName(clazz.name + "$") - val otherSym = m.newValue(otherName, m.pos, SYNTHETIC) setInfo clazz.tpe - val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc))) - val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz))) - def block = Block(ValDef(otherSym, thatCast), AND(pairwise :+ canEq: _*)) - - (This(clazz) ANY_EQ arg0) OR { - thatTest AND Block( - ValDef(otherSym, thatCast), - AND(pairwise :+ canEq: _*) - ) - } - } + def equalsCaseClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m => if (accessors.isEmpty) - thatTest AND ((thatCast DOT nme.canEqual_)(This(clazz))) + if (clazz.isFinal) thatTest(m) + else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(This(clazz))) else - argsBody + (This(clazz) ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors) + } + + /** The equality method for value classes + * def equals(that: Any) = (this.asInstanceOf[AnyRef]) eq that.asInstanceOf[AnyRef]) || { + * (that.isInstanceOf[this.C]) && { + * val x$1 = that.asInstanceOf[this.C] + * (this.underlying == that.underlying + */ + def equalsDerivedValueClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m => + equalsCore(m, List(clazz.firstParamAccessor)) + } + + /** The hashcode method for value classes + * def hashCode(): Int = this.underlying.hashCode + */ + def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntClass.tpe) { m => + Select( + Select(This(clazz), clazz.firstParamAccessor), + nme.hashCode_) } /** The _1, _2, etc. methods to implement ProductN. */ - def productNMethods = { + def productNMethods = { val accs = accessors.toIndexedSeq 1 to arity map (num => productProj(arity, num) -> (() => projectionMethod(accs(num - 1), num))) } @@ -167,7 +217,7 @@ trait SyntheticMethods extends ast.TreeDSL { List( Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)), Product_productArity -> (() => constantNullary(nme.productArity, arity)), - Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(Ident)), + Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(Select(This(clazz), _))), Product_iterator -> (() => productIteratorMethod), Product_canEqual -> (() => canEqualMethod) // This is disabled pending a reimplementation which doesn't add any @@ -176,10 +226,19 @@ trait SyntheticMethods extends ast.TreeDSL { ) } + def valueClassMethods = List( + Any_hashCode -> (() => hashCodeDerivedValueClassMethod), + Any_equals -> (() => equalsDerivedValueClassMethod) + ) + def caseClassMethods = productMethods ++ productNMethods ++ Seq( Object_hashCode -> (() => forwardToRuntime(Object_hashCode)), Object_toString -> (() => forwardToRuntime(Object_toString)), - Object_equals -> (() => equalsClassMethod) + Object_equals -> (() => equalsCaseClassMethod) + ) + + def valueCaseClassMethods = productMethods ++ productNMethods ++ valueClassMethods ++ Seq( + Any_toString -> (() => forwardToRuntime(Object_toString)) ) def caseObjectMethods = productMethods ++ Seq( @@ -203,10 +262,14 @@ trait SyntheticMethods extends ast.TreeDSL { def synthesize(): List[Tree] = { val methods = ( - if (!clazz.isCase) Nil - else if (clazz.isModuleClass) caseObjectMethods - else caseClassMethods + if (clazz.isCase) + if (clazz.isDerivedValueClass) valueCaseClassMethods + else if (clazz.isModuleClass) caseObjectMethods + else caseClassMethods + else if (clazz.isDerivedValueClass) valueClassMethods + else Nil ) + def impls = for ((m, impl) <- methods ; if !hasOverridingImplementation(m)) yield impl() def extras = ( if (needsReadResolve) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 9ff86e69eb..9a2ef88821 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -637,7 +637,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this // so for now it requires the type symbol be public. && pre.typeSymbol.isPublic) - tree setType MethodType(Nil, erasure.getClassReturnType(pre)) + tree setType MethodType(Nil, getClassReturnType(pre)) else tree } @@ -1266,8 +1266,36 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } + private def validateDerivedValueClass(clazz: Symbol, body: List[Tree]) = { + if (clazz.isTrait) + unit.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal") + if (!clazz.isStatic) + unit.error(clazz.pos, "value class may not be a "+ + (if (clazz.owner.isTerm) "local class" else "member of another class")) + val constr = clazz.primaryConstructor + if ((constr hasFlag (PRIVATE | PROTECTED)) || constr.privateWithin != NoSymbol) + unit.error(constr.pos, "value class must have public primary constructor") + clazz.info.decls.toList.filter(acc => acc.isMethod && (acc hasFlag PARAMACCESSOR)) match { + case List(acc) => + def isUnderlyingAcc(sym: Symbol) = + sym == acc || acc.hasAccessorFlag && sym == acc.accessed + if (acc.accessBoundary(clazz) != RootClass) + unit.error(acc.pos, "value class needs to have a publicly accessible val parameter") + for (stat <- body) + if (!treeInfo.isAllowedInUniversalTrait(stat) && !isUnderlyingAcc(stat.symbol)) + unit.error(stat.pos, + if (stat.symbol hasFlag PARAMACCESSOR) "illegal parameter for value class" + else "this statement is not allowed in value class: "+stat) + case x => + unit.error(clazz.pos, "value class needs to have exactly one public val parameter") + } + for (tparam <- clazz.typeParams) + if (tparam hasAnnotation definitions.SpecializedClass) + unit.error(tparam.pos, "type parameter of value class may not be specialized") + } + def parentTypes(templ: Template): List[Tree] = - if (templ.parents.isEmpty) List() + if (templ.parents.isEmpty) List(TypeTree(AnyRefClass.tpe)) else try { val clazz = context.owner // Normalize supertype and mixins so that supertype is always a class, not a trait. @@ -1279,9 +1307,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val supertpt1 = typedType(supertpt) if (!supertpt1.isErrorTyped) { mixins = supertpt1 :: mixins - supertpt = TypeTree(supertpt1.tpe.parents.head) setPos supertpt.pos.focus + supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus } } + if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait) + supertpt.tpe = AnyRefClass.tpe // Determine // - supertparams: Missing type parameters from supertype @@ -1371,12 +1401,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else xs ) } + fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt)) } catch { case ex: TypeError => // fallback in case of cyclic errors // @H none of the tests enter here but I couldn't rule it out + log("Type error calculating parents in template " + templ) + log("Error: " + ex) ParentTypesError(templ, ex) List(TypeTree(AnyRefClass.tpe)) } @@ -1413,13 +1446,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (psym.isFinal) pending += ParentFinalInheritanceError(parent, psym) - if (psym.isSealed && !phase.erasedTypes) { - // AnyVal is sealed, but we have to let the value classes through manually - if (context.unit.source.file == psym.sourceFile || isValueClass(context.owner)) + if (psym.isSealed && !phase.erasedTypes) + if (context.unit.source.file == psym.sourceFile) psym addChild context.owner else pending += ParentSealedInheritanceError(parent, psym) - } + if (!(selfType <:< parent.tpe.typeOfThis) && !phase.erasedTypes && !context.owner.isSynthetic && // don't check synthetic concrete classes for virtuals (part of DEVIRTUALIZE) @@ -1485,6 +1517,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { _.typedTemplate(cdef.impl, parentTypes(cdef.impl)) } val impl2 = finishMethodSynthesis(impl1, clazz, context) + if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.normalize.typeSymbol == AnyClass) + for (stat <- impl2.body) + if (!treeInfo.isAllowedInUniversalTrait(stat)) + unit.error(stat.pos, "this statement is not allowed in universal trait extending from class Any: "+stat) if ((clazz != ClassfileAnnotationClass) && (clazz isNonBottomSubClass ClassfileAnnotationClass)) restrictionWarning(cdef.pos, unit, @@ -1601,6 +1637,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass) unit.error(clazz.pos, "inner classes cannot be classfile annotations") + if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType]) @@ -1609,6 +1646,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else templ.body flatMap rewrappingWrapperTrees(namer.finishGetterSetter(Typer.this, _)) val body1 = typedStats(body, templ.symbol) + + if (clazz.isDerivedValueClass) + validateDerivedValueClass(clazz, body1) + treeCopy.Template(templ, parents1, self1, body1) setType clazz.tpe } @@ -1861,8 +1902,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe) } - if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors) + if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) { + // At this point in AnyVal there is no supercall, which will blow up + // in computeParamAliases; there's nothing to be computed for Anyval anyway. computeParamAliases(meth.owner, vparamss1, rhs1) + } if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass) rhs1 = checkDead(rhs1) @@ -2615,8 +2659,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { /** This is translating uses of List() into Nil. This is less * than ideal from a consistency standpoint, but it shouldn't be * altered without due caution. + * ... this also causes bootstrapping cycles if List_apply is + * forced during kind-arity checking, so it is guarded by additional + * tests to ensure we're sufficiently far along. */ - if (fun.symbol == List_apply && args.isEmpty && !forInteractive) + if (args.isEmpty && !forInteractive && fun.symbol.isInitialized && ListModule.hasCompleteInfo && (fun.symbol == List_apply)) atPos(tree.pos)(gen.mkNil setType restpe) else constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe)) @@ -3154,7 +3201,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // as we don't know which alternative to choose... here we do map2Conserve(args, tparams) { //@M! the polytype denotes the expected kind - (arg, tparam) => typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe)) + (arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe)) } } else // @M: there's probably something wrong when args.length != tparams.length... (triggered by bug #320) // Martin, I'm using fake trees, because, if you use args or arg.map(typedType), @@ -3756,16 +3803,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - val owntype = - if (mix.isEmpty) { - if ((mode & SUPERCONSTRmode) != 0) - if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036 - else clazz.info.parents.head - else intersectionType(clazz.info.parents) - } else { - findMixinSuper(clazz.tpe) - } - + val owntype = ( + if (!mix.isEmpty) findMixinSuper(clazz.tpe) + else if ((mode & SUPERCONSTRmode) != 0) clazz.info.firstParent + else intersectionType(clazz.info.parents) + ) treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype) } @@ -4149,7 +4191,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // if symbol hasn't been fully loaded, can't check kind-arity else map2Conserve(args, tparams) { (arg, tparam) => //@M! the polytype denotes the expected kind - typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe)) + typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe)) } val argtypes = args1 map (_.tpe) @@ -4317,7 +4359,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) => val expr = typed(expr0, onlyStickyModes(mode), WildcardType) def subArrayType(pt: Type) = - if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt) + if (isPrimitiveValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt) else { val tparam = context.owner freshExistential "" setInfo TypeBounds.upper(pt) newExistentialType(List(tparam), arrayType(tparam.tpe)) @@ -4362,7 +4404,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // @M maybe the well-kindedness check should be done when checking the type arguments conform to the type parameters' bounds? val args1 = if (sameLength(args, tparams)) map2Conserve(args, tparams) { //@M! the polytype denotes the expected kind - (arg, tparam) => typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe)) + (arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe)) } else { //@M this branch is correctly hit for an overloaded polymorphic type. It also has to handle erroneous cases. // Until the right alternative for an overloaded method is known, be very liberal, @@ -4682,6 +4724,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // AnyRef, but the AnyRef type alias is entered after the scala package is // loaded and completed, so that ScalaObject is unpickled while AnyRef is not // yet defined ) + // !!! TODO - revisit now that ScalaObject is gone. result setType(restpe) } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208 // during uncurry (after refchecks), all types are normalized diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 312958feca..cc272b7b8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -151,11 +151,10 @@ trait Unapplies extends ast.TreeDSL } def companionModuleDef(cdef: ClassDef, parents: List[Tree] = Nil, body: List[Tree] = Nil): ModuleDef = atPos(cdef.pos.focus) { - val allParents = parents :+ gen.scalaScalaObjectConstr ModuleDef( Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin), cdef.name.toTermName, - Template(allParents, emptyValDef, NoMods, Nil, List(Nil), body, cdef.impl.pos.focus)) + Template(parents, emptyValDef, NoMods, Nil, List(Nil), body, cdef.impl.pos.focus)) } private val caseMods = Modifiers(SYNTHETIC | CASE) diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 622b4db2a2..ce10ee34a2 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -23,7 +23,7 @@ import java.net.MalformedURLException * @author Stepan Koltsov */ object ClassPath { - def scalaLibrary = locate[ScalaObject] + def scalaLibrary = locate[Option[_]] def scalaCompiler = locate[Global] def infoFor[T](value: T) = info(value.getClass) diff --git a/src/detach/plugin/scala/tools/detach/Detach.scala b/src/detach/plugin/scala/tools/detach/Detach.scala index fee2c5a273..41a3795a49 100644 --- a/src/detach/plugin/scala/tools/detach/Detach.scala +++ b/src/detach/plugin/scala/tools/detach/Detach.scala @@ -734,7 +734,7 @@ abstract class Detach extends PluginComponent proxyOwner.newClass(clazz.pos, encode(clazz.name.decode + PROXY_SUFFIX)) iface.sourceFile = clazz.sourceFile iface setFlag (ABSTRACT | TRAIT | INTERFACE) // Java interface - val iparents = List(ObjectClass.tpe, RemoteClass.tpe, ScalaObjectClass.tpe) + val iparents = List(ObjectClass.tpe, RemoteClass.tpe) iface setInfo ClassInfoType(iparents, newScope, iface) // methods must throw RemoteException iface addAnnotation remoteAnnotationInfo @@ -744,11 +744,9 @@ abstract class Detach extends PluginComponent iclaz.sourceFile = clazz.sourceFile iclaz setFlag (SYNTHETIC | FINAL) // Variant 1: rebind/unbind - val cparents = List(UnicastRemoteObjectClass.tpe, iface.tpe, - UnreferencedClass.tpe, ScalaObjectClass.tpe) + val cparents = List(UnicastRemoteObjectClass.tpe, iface.tpe, UnreferencedClass.tpe) // Variant 2: un-/exportObject - //val cparents = List(ObjectClass.tpe, iface.tpe, - // UnreferencedClass.tpe, ScalaObjectClass.tpe) + //val cparents = List(ObjectClass.tpe, iface.tpe, UnreferencedClass.tpe) iclaz setInfo ClassInfoType(cparents, newScope, iclaz) val proxy = (iface, iclaz, new mutable.HashMap[Symbol, Symbol]) proxies(clazz) = proxy diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala index cd2c04dbd8..393f0899f4 100644 --- a/src/library/scala/AnyVal.scala +++ b/src/library/scala/AnyVal.scala @@ -25,4 +25,8 @@ package scala * The ''integer types'' include the subrange types as well as [[scala.Int]] and [[scala.Long]]. * The ''floating point types'' are [[scala.Float]] and [[scala.Double]]. */ -sealed trait AnyVal +abstract class AnyVal extends Any with NotNull { + // disabled for now to make the standard build go through. + // Once we have a new strap we can uncomment this and delete the AnyVal_getClass entry in Definitions. + def getClass(): Class[_ <: AnyVal] = ??? +} diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala index 0adcde3aba..5078e59d28 100644 --- a/src/library/scala/Boolean.scala +++ b/src/library/scala/Boolean.scala @@ -107,7 +107,7 @@ final class Boolean extends AnyVal { */ def ^(x: Boolean): Boolean = sys.error("stub") - def getClass(): Class[Boolean] = sys.error("stub") + override def getClass(): Class[Boolean] = sys.error("stub") } object Boolean extends AnyValCompanion { diff --git a/src/library/scala/BoxingConversions.scala b/src/library/scala/BoxingConversions.scala new file mode 100644 index 0000000000..fd1bd6c121 --- /dev/null +++ b/src/library/scala/BoxingConversions.scala @@ -0,0 +1,5 @@ +package scala +abstract class BoxingConversions[Boxed, Unboxed] { + def box(x: Unboxed): Boxed + def unbox(x: Boxed): Unboxed +} diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index 4923cc9786..f9c5f6003e 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -590,7 +590,7 @@ final class Byte extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Byte] = sys.error("stub") + override def getClass(): Class[Byte] = sys.error("stub") } object Byte extends AnyValCompanion { diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index b4e6445899..3d459782cd 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -590,7 +590,7 @@ final class Char extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Char] = sys.error("stub") + override def getClass(): Class[Char] = sys.error("stub") } object Char extends AnyValCompanion { diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index 68a1a01299..01414265c4 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -356,7 +356,7 @@ final class Double extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Double] = sys.error("stub") + override def getClass(): Class[Double] = sys.error("stub") } object Double extends AnyValCompanion { diff --git a/src/library/scala/Equals.scala b/src/library/scala/Equals.scala index 8aff7af175..4545c21e45 100644 --- a/src/library/scala/Equals.scala +++ b/src/library/scala/Equals.scala @@ -11,7 +11,7 @@ package scala /** An interface containing operations for equality. * The only method not already present in class `AnyRef` is `canEqual`. */ -trait Equals { +trait Equals extends Any { /** A method that should be called from every well-designed equals method * that is open to be overridden in a subclass. See Programming in Scala, * Chapter 28 for discussion and design. diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index 709d73d408..ff5b3cb112 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -356,7 +356,7 @@ final class Float extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Float] = sys.error("stub") + override def getClass(): Class[Float] = sys.error("stub") } object Float extends AnyValCompanion { diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 519a0486ac..316bbced2d 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -590,7 +590,7 @@ final class Int extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Int] = sys.error("stub") + override def getClass(): Class[Int] = sys.error("stub") } object Int extends AnyValCompanion { diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index 9c7a803f08..ce8618c22a 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -590,7 +590,7 @@ final class Long extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Long] = sys.error("stub") + override def getClass(): Class[Long] = sys.error("stub") } object Long extends AnyValCompanion { diff --git a/src/library/scala/NotNull.scala b/src/library/scala/NotNull.scala index d47d47a83e..64f999a932 100644 --- a/src/library/scala/NotNull.scala +++ b/src/library/scala/NotNull.scala @@ -6,12 +6,10 @@ ** |/ ** \* */ - - package scala /** * A marker trait for things that are not allowed to be null * @since 2.5 */ -trait NotNull {} +trait NotNull extends Any {} diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index a2ee76500c..b5006e7948 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -215,7 +215,7 @@ object Predef extends LowPriorityImplicits { throw new IllegalArgumentException("requirement failed: "+ message) } - final class Ensuring[A](val __resultOfEnsuring: A) { + final class Ensuring[A](val __resultOfEnsuring: A) extends AnyVal { // `__resultOfEnsuring` must be a public val to allow inlining. // See comments in ArrowAssoc for more. @deprecated("Use __resultOfEnsuring instead", "2.10.0") @@ -226,7 +226,7 @@ object Predef extends LowPriorityImplicits { def ensuring(cond: A => Boolean): A = { assert(cond(__resultOfEnsuring)); __resultOfEnsuring } def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(__resultOfEnsuring), msg); __resultOfEnsuring } } - implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x) + @inline implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x) /** `???` can be used for marking methods that remain to be implemented. * @throws A `NotImplementedError` @@ -247,7 +247,7 @@ object Predef extends LowPriorityImplicits { def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x) } - final class ArrowAssoc[A](val __leftOfArrow: A) { + final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal { // `__leftOfArrow` must be a public val to allow inlining. The val // used to be called `x`, but now goes by `__leftOfArrow`, as that // reduces the chances of a user's writing `foo.__leftOfArrow` and @@ -260,7 +260,7 @@ object Predef extends LowPriorityImplicits { @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) def →[B](y: B): Tuple2[A, B] = ->(y) } - implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) + @inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) // printing and reading ----------------------------------------------- @@ -386,7 +386,8 @@ object Predef extends LowPriorityImplicits { // Strings and CharSequences -------------------------------------------------------------- implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) - implicit def augmentString(x: String): StringOps = new StringOps(x) + @inline implicit def any2stringfmt(x: Any) = new runtime.StringFormat(x) + @inline implicit def augmentString(x: String): StringOps = new StringOps(x) implicit def unaugmentString(x: StringOps): String = x.repr implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] = diff --git a/src/library/scala/Product.scala b/src/library/scala/Product.scala index 90ae82b6d0..1459ab9ea5 100644 --- a/src/library/scala/Product.scala +++ b/src/library/scala/Product.scala @@ -17,7 +17,7 @@ package scala * @version 1.0 * @since 2.3 */ -trait Product extends Equals { +trait Product extends Any with Equals { /** The n^th^ element of this product, 0-based. In other words, for a * product `A(x,,1,,, ..., x,,k,,)`, returns `x,,(n+1),, where `0 < n < k`. * diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala index ab8b0a4505..d268b35f60 100644 --- a/src/library/scala/Product1.scala +++ b/src/library/scala/Product1.scala @@ -17,13 +17,13 @@ object Product1 { /** Product1 is a cartesian product of 1 component. * @since 2.3 */ -trait Product1[@specialized(Int, Long, Double) +T1] extends Product { +trait Product1[@specialized(Int, Long, Double) +T1] extends Any with Product { /** The arity of this product. * @return 1 */ override def productArity = 1 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product1[@specialized(Int, Long, Double) +T1] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case _ => throw new IndexOutOfBoundsException(n.toString()) } diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala index 536fb2fed9..cae9e5a664 100644 --- a/src/library/scala/Product10.scala +++ b/src/library/scala/Product10.scala @@ -17,13 +17,13 @@ object Product10 { /** Product10 is a cartesian product of 10 components. * @since 2.3 */ -trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Product { +trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Any with Product { /** The arity of this product. * @return 10 */ override def productArity = 10 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Produ */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala index 7d49eccc5e..0647b28414 100644 --- a/src/library/scala/Product11.scala +++ b/src/library/scala/Product11.scala @@ -17,13 +17,13 @@ object Product11 { /** Product11 is a cartesian product of 11 components. * @since 2.3 */ -trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Product { +trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Any with Product { /** The arity of this product. * @return 11 */ override def productArity = 11 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala index 0e9c4a01a2..a080aafa7a 100644 --- a/src/library/scala/Product12.scala +++ b/src/library/scala/Product12.scala @@ -17,13 +17,13 @@ object Product12 { /** Product12 is a cartesian product of 12 components. * @since 2.3 */ -trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Product { +trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Any with Product { /** The arity of this product. * @return 12 */ override def productArity = 12 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] e */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala index a0629201d0..425aebf3e7 100644 --- a/src/library/scala/Product13.scala +++ b/src/library/scala/Product13.scala @@ -17,13 +17,13 @@ object Product13 { /** Product13 is a cartesian product of 13 components. * @since 2.3 */ -trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Product { +trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Any with Product { /** The arity of this product. * @return 13 */ override def productArity = 13 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala index 32dda81c3e..3d7e4896ef 100644 --- a/src/library/scala/Product14.scala +++ b/src/library/scala/Product14.scala @@ -17,13 +17,13 @@ object Product14 { /** Product14 is a cartesian product of 14 components. * @since 2.3 */ -trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Product { +trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Any with Product { /** The arity of this product. * @return 14 */ override def productArity = 14 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala index 57851f9870..7bca7a2a1b 100644 --- a/src/library/scala/Product15.scala +++ b/src/library/scala/Product15.scala @@ -17,13 +17,13 @@ object Product15 { /** Product15 is a cartesian product of 15 components. * @since 2.3 */ -trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Product { +trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Any with Product { /** The arity of this product. * @return 15 */ override def productArity = 15 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala index 75076f3b3c..c5042cbc90 100644 --- a/src/library/scala/Product16.scala +++ b/src/library/scala/Product16.scala @@ -17,13 +17,13 @@ object Product16 { /** Product16 is a cartesian product of 16 components. * @since 2.3 */ -trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Product { +trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Any with Product { /** The arity of this product. * @return 16 */ override def productArity = 16 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala index 9ee6072ffe..b5651ec712 100644 --- a/src/library/scala/Product17.scala +++ b/src/library/scala/Product17.scala @@ -17,13 +17,13 @@ object Product17 { /** Product17 is a cartesian product of 17 components. * @since 2.3 */ -trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Product { +trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Any with Product { /** The arity of this product. * @return 17 */ override def productArity = 17 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala index 25d0839af1..088a48ae32 100644 --- a/src/library/scala/Product18.scala +++ b/src/library/scala/Product18.scala @@ -17,13 +17,13 @@ object Product18 { /** Product18 is a cartesian product of 18 components. * @since 2.3 */ -trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Product { +trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Any with Product { /** The arity of this product. * @return 18 */ override def productArity = 18 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala index 5464de7264..4f4a98c6a0 100644 --- a/src/library/scala/Product19.scala +++ b/src/library/scala/Product19.scala @@ -17,13 +17,13 @@ object Product19 { /** Product19 is a cartesian product of 19 components. * @since 2.3 */ -trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Product { +trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Any with Product { /** The arity of this product. * @return 19 */ override def productArity = 19 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala index 8097245926..eb67e5d46e 100644 --- a/src/library/scala/Product2.scala +++ b/src/library/scala/Product2.scala @@ -17,13 +17,13 @@ object Product2 { /** Product2 is a cartesian product of 2 components. * @since 2.3 */ -trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Product { +trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product { /** The arity of this product. * @return 2 */ override def productArity = 2 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Doub */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case _ => throw new IndexOutOfBoundsException(n.toString()) diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala index b094e09aca..80f63f1bb4 100644 --- a/src/library/scala/Product20.scala +++ b/src/library/scala/Product20.scala @@ -17,13 +17,13 @@ object Product20 { /** Product20 is a cartesian product of 20 components. * @since 2.3 */ -trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Product { +trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Any with Product { /** The arity of this product. * @return 20 */ override def productArity = 20 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala index fa06cfb438..7056844271 100644 --- a/src/library/scala/Product21.scala +++ b/src/library/scala/Product21.scala @@ -17,13 +17,13 @@ object Product21 { /** Product21 is a cartesian product of 21 components. * @since 2.3 */ -trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Product { +trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Any with Product { /** The arity of this product. * @return 21 */ override def productArity = 21 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala index 46038bf1a2..05e95f92dd 100644 --- a/src/library/scala/Product22.scala +++ b/src/library/scala/Product22.scala @@ -17,13 +17,13 @@ object Product22 { /** Product22 is a cartesian product of 22 components. * @since 2.3 */ -trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Product { +trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Any with Product { /** The arity of this product. * @return 22 */ override def productArity = 22 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala index 3a4cd8fc5e..91556bb962 100644 --- a/src/library/scala/Product3.scala +++ b/src/library/scala/Product3.scala @@ -17,13 +17,13 @@ object Product3 { /** Product3 is a cartesian product of 3 components. * @since 2.3 */ -trait Product3[+T1, +T2, +T3] extends Product { +trait Product3[+T1, +T2, +T3] extends Any with Product { /** The arity of this product. * @return 3 */ override def productArity = 3 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product3[+T1, +T2, +T3] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala index a4d47457fa..1f9070c155 100644 --- a/src/library/scala/Product4.scala +++ b/src/library/scala/Product4.scala @@ -17,13 +17,13 @@ object Product4 { /** Product4 is a cartesian product of 4 components. * @since 2.3 */ -trait Product4[+T1, +T2, +T3, +T4] extends Product { +trait Product4[+T1, +T2, +T3, +T4] extends Any with Product { /** The arity of this product. * @return 4 */ override def productArity = 4 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product4[+T1, +T2, +T3, +T4] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala index 9f25e70af0..52dd284f55 100644 --- a/src/library/scala/Product5.scala +++ b/src/library/scala/Product5.scala @@ -17,13 +17,13 @@ object Product5 { /** Product5 is a cartesian product of 5 components. * @since 2.3 */ -trait Product5[+T1, +T2, +T3, +T4, +T5] extends Product { +trait Product5[+T1, +T2, +T3, +T4, +T5] extends Any with Product { /** The arity of this product. * @return 5 */ override def productArity = 5 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product5[+T1, +T2, +T3, +T4, +T5] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala index 87fd318c68..9624bdbe3e 100644 --- a/src/library/scala/Product6.scala +++ b/src/library/scala/Product6.scala @@ -17,13 +17,13 @@ object Product6 { /** Product6 is a cartesian product of 6 components. * @since 2.3 */ -trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Product { +trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Any with Product { /** The arity of this product. * @return 6 */ override def productArity = 6 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala index d074503315..36d4b149db 100644 --- a/src/library/scala/Product7.scala +++ b/src/library/scala/Product7.scala @@ -17,13 +17,13 @@ object Product7 { /** Product7 is a cartesian product of 7 components. * @since 2.3 */ -trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Product { +trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Any with Product { /** The arity of this product. * @return 7 */ override def productArity = 7 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala index bd6150c235..28c78f9c89 100644 --- a/src/library/scala/Product8.scala +++ b/src/library/scala/Product8.scala @@ -17,13 +17,13 @@ object Product8 { /** Product8 is a cartesian product of 8 components. * @since 2.3 */ -trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Product { +trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Any with Product { /** The arity of this product. * @return 8 */ override def productArity = 8 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala index 1f042944cc..d69c550abe 100644 --- a/src/library/scala/Product9.scala +++ b/src/library/scala/Product9.scala @@ -17,13 +17,13 @@ object Product9 { /** Product9 is a cartesian product of 9 components. * @since 2.3 */ -trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Product { +trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Any with Product { /** The arity of this product. * @return 9 */ override def productArity = 9 - + /** Returns the n-th projection of this product if 0 < n <= productArity, * otherwise throws an `IndexOutOfBoundsException`. * @@ -33,7 +33,7 @@ trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Product { */ @throws(classOf[IndexOutOfBoundsException]) - override def productElement(n: Int) = n match { + override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala index 383ff5b3bb..604b2a299f 100644 --- a/src/library/scala/Proxy.scala +++ b/src/library/scala/Proxy.scala @@ -22,13 +22,15 @@ package scala * @author Matthias Zenger * @version 1.0, 26/04/2004 */ -trait Proxy { +trait Proxy extends Any { def self: Any override def hashCode: Int = self.hashCode override def equals(that: Any): Boolean = that match { - case null => false - case x: AnyRef => (x eq this) || (x eq self.asInstanceOf[AnyRef]) || (x equals self) + case null => false + case _ => + val x = that.asInstanceOf[AnyRef] + (x eq this.asInstanceOf[AnyRef]) || (x eq self.asInstanceOf[AnyRef]) || (x equals self) } override def toString = "" + self } @@ -36,7 +38,7 @@ trait Proxy { object Proxy { /** A proxy which exposes the type it is proxying for via a type parameter. */ - trait Typed[T] extends Proxy { + trait Typed[T] extends Any with Proxy { def self: T } } diff --git a/src/library/scala/ScalaObject.scala b/src/library/scala/ScalaObject.scala deleted file mode 100644 index 8da0ab2cba..0000000000 --- a/src/library/scala/ScalaObject.scala +++ /dev/null @@ -1,13 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala - -trait ScalaObject extends java.lang.Object diff --git a/src/library/scala/Serializable.scala b/src/library/scala/Serializable.scala index 9be258bb83..9b9456e0a0 100644 --- a/src/library/scala/Serializable.scala +++ b/src/library/scala/Serializable.scala @@ -11,4 +11,4 @@ package scala /** * Classes extending this trait are serializable across platforms (Java, .NET). */ -trait Serializable extends java.io.Serializable +trait Serializable extends Any with java.io.Serializable diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index a9210d3555..5664c3b44c 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -590,7 +590,7 @@ final class Short extends AnyVal { */ def %(x: Double): Double = sys.error("stub") - def getClass(): Class[Short] = sys.error("stub") + override def getClass(): Class[Short] = sys.error("stub") } object Short extends AnyValCompanion { diff --git a/src/library/scala/Tuple1.scala b/src/library/scala/Tuple1.scala index 6d31d35e51..02fdd0cba5 100644 --- a/src/library/scala/Tuple1.scala +++ b/src/library/scala/Tuple1.scala @@ -19,5 +19,5 @@ case class Tuple1[@specialized(Int, Long, Double) +T1](_1: T1) extends Product1[T1] { override def toString() = "(" + _1 + ")" - + } diff --git a/src/library/scala/Tuple10.scala b/src/library/scala/Tuple10.scala index 10d554d467..ba2a02a8b2 100644 --- a/src/library/scala/Tuple10.scala +++ b/src/library/scala/Tuple10.scala @@ -28,5 +28,5 @@ case class Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10](_1: T1, _2 extends Product10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + ")" - + } diff --git a/src/library/scala/Tuple11.scala b/src/library/scala/Tuple11.scala index 2065e4f017..7f51d172d4 100644 --- a/src/library/scala/Tuple11.scala +++ b/src/library/scala/Tuple11.scala @@ -29,5 +29,5 @@ case class Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11](_1: extends Product11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + ")" - + } diff --git a/src/library/scala/Tuple12.scala b/src/library/scala/Tuple12.scala index a463986752..4bbc6a0eab 100644 --- a/src/library/scala/Tuple12.scala +++ b/src/library/scala/Tuple12.scala @@ -31,5 +31,5 @@ case class Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + ")" - + } diff --git a/src/library/scala/Tuple13.scala b/src/library/scala/Tuple13.scala index 2bee0d69ad..77bd59bf2e 100644 --- a/src/library/scala/Tuple13.scala +++ b/src/library/scala/Tuple13.scala @@ -32,5 +32,5 @@ case class Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + ")" - + } diff --git a/src/library/scala/Tuple14.scala b/src/library/scala/Tuple14.scala index 60f7c51e64..bf7a4ce016 100644 --- a/src/library/scala/Tuple14.scala +++ b/src/library/scala/Tuple14.scala @@ -33,5 +33,5 @@ case class Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + ")" - + } diff --git a/src/library/scala/Tuple15.scala b/src/library/scala/Tuple15.scala index fc8e30580b..582c359bc6 100644 --- a/src/library/scala/Tuple15.scala +++ b/src/library/scala/Tuple15.scala @@ -34,5 +34,5 @@ case class Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + ")" - + } diff --git a/src/library/scala/Tuple16.scala b/src/library/scala/Tuple16.scala index 80181f6648..a1e9a790ff 100644 --- a/src/library/scala/Tuple16.scala +++ b/src/library/scala/Tuple16.scala @@ -35,5 +35,5 @@ case class Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + ")" - + } diff --git a/src/library/scala/Tuple17.scala b/src/library/scala/Tuple17.scala index 6236122be2..f531766c18 100644 --- a/src/library/scala/Tuple17.scala +++ b/src/library/scala/Tuple17.scala @@ -36,5 +36,5 @@ case class Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + ")" - + } diff --git a/src/library/scala/Tuple18.scala b/src/library/scala/Tuple18.scala index dd6a819ac5..a96db25e4b 100644 --- a/src/library/scala/Tuple18.scala +++ b/src/library/scala/Tuple18.scala @@ -37,5 +37,5 @@ case class Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + ")" - + } diff --git a/src/library/scala/Tuple19.scala b/src/library/scala/Tuple19.scala index 65f0fd22cf..718280d68a 100644 --- a/src/library/scala/Tuple19.scala +++ b/src/library/scala/Tuple19.scala @@ -38,5 +38,5 @@ case class Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + ")" - + } diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 684d2266e8..b1befca4fa 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -23,7 +23,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s extends Product2[T1, T2] { override def toString() = "(" + _1 + "," + _2 + ")" - + /** Swaps the elements of this `Tuple`. * @return a new Tuple where the first element is the second element of this Tuple and the * second element is the first element of this Tuple. diff --git a/src/library/scala/Tuple20.scala b/src/library/scala/Tuple20.scala index cf3626909d..4a44c0bb89 100644 --- a/src/library/scala/Tuple20.scala +++ b/src/library/scala/Tuple20.scala @@ -39,5 +39,5 @@ case class Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + ")" - + } diff --git a/src/library/scala/Tuple21.scala b/src/library/scala/Tuple21.scala index 78b9c585c6..580a169e39 100644 --- a/src/library/scala/Tuple21.scala +++ b/src/library/scala/Tuple21.scala @@ -40,5 +40,5 @@ case class Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + ")" - + } diff --git a/src/library/scala/Tuple22.scala b/src/library/scala/Tuple22.scala index 0993dfbbc3..fd3392ddea 100644 --- a/src/library/scala/Tuple22.scala +++ b/src/library/scala/Tuple22.scala @@ -41,5 +41,5 @@ case class Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12 { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + "," + _22 + ")" - + } diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index dfa0c962a2..0d5399308b 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")" - + @deprecated("Use `zipped` instead.", "2.9.0") def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1], diff --git a/src/library/scala/Tuple4.scala b/src/library/scala/Tuple4.scala index a919072c88..a859078bcf 100644 --- a/src/library/scala/Tuple4.scala +++ b/src/library/scala/Tuple4.scala @@ -22,5 +22,5 @@ case class Tuple4[+T1, +T2, +T3, +T4](_1: T1, _2: T2, _3: T3, _4: T4) extends Product4[T1, T2, T3, T4] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + ")" - + } diff --git a/src/library/scala/Tuple5.scala b/src/library/scala/Tuple5.scala index 6a94f48ab4..1edfb673ee 100644 --- a/src/library/scala/Tuple5.scala +++ b/src/library/scala/Tuple5.scala @@ -23,5 +23,5 @@ case class Tuple5[+T1, +T2, +T3, +T4, +T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T extends Product5[T1, T2, T3, T4, T5] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")" - + } diff --git a/src/library/scala/Tuple6.scala b/src/library/scala/Tuple6.scala index 34f8224627..5b74937e58 100644 --- a/src/library/scala/Tuple6.scala +++ b/src/library/scala/Tuple6.scala @@ -24,5 +24,5 @@ case class Tuple6[+T1, +T2, +T3, +T4, +T5, +T6](_1: T1, _2: T2, _3: T3, _4: T4, extends Product6[T1, T2, T3, T4, T5, T6] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + ")" - + } diff --git a/src/library/scala/Tuple7.scala b/src/library/scala/Tuple7.scala index 6fc3477ba2..a7f572e9f0 100644 --- a/src/library/scala/Tuple7.scala +++ b/src/library/scala/Tuple7.scala @@ -25,5 +25,5 @@ case class Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7](_1: T1, _2: T2, _3: T3, _4: extends Product7[T1, T2, T3, T4, T5, T6, T7] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + ")" - + } diff --git a/src/library/scala/Tuple8.scala b/src/library/scala/Tuple8.scala index 1e21b684fc..9bb427d689 100644 --- a/src/library/scala/Tuple8.scala +++ b/src/library/scala/Tuple8.scala @@ -26,5 +26,5 @@ case class Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8](_1: T1, _2: T2, _3: T3 extends Product8[T1, T2, T3, T4, T5, T6, T7, T8] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + ")" - + } diff --git a/src/library/scala/Tuple9.scala b/src/library/scala/Tuple9.scala index 453cea31a1..4d50539e0c 100644 --- a/src/library/scala/Tuple9.scala +++ b/src/library/scala/Tuple9.scala @@ -27,5 +27,5 @@ case class Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9](_1: T1, _2: T2, _ extends Product9[T1, T2, T3, T4, T5, T6, T7, T8, T9] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + ")" - + } diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala index 57970b021b..f6ed0121ab 100644 --- a/src/library/scala/Unit.scala +++ b/src/library/scala/Unit.scala @@ -17,7 +17,7 @@ package scala * method which is declared `void`. */ final class Unit extends AnyVal { - def getClass(): Class[Unit] = sys.error("stub") + override def getClass(): Class[Unit] = sys.error("stub") } object Unit extends AnyValCompanion { diff --git a/src/library/scala/collection/GenIterableLike.scala b/src/library/scala/collection/GenIterableLike.scala index 18132f0a7b..7e68733afd 100644 --- a/src/library/scala/collection/GenIterableLike.scala +++ b/src/library/scala/collection/GenIterableLike.scala @@ -34,7 +34,7 @@ import generic.{ CanBuildFrom => CBF, _ } * This is a base trait for all Scala collections that define an `iterator` * method to step through one-by-one the collection's elements. */ -trait GenIterableLike[+A, +Repr] extends GenTraversableLike[A, Repr] { +trait GenIterableLike[+A, +Repr] extends Any with GenTraversableLike[A, Repr] { def iterator: Iterator[A] diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 63e9543711..cb0e96fcbb 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -30,7 +30,7 @@ import annotation.bridge * Sequences are special cases of iterable collections of class `Iterable`. * Unlike iterables, sequences always have a defined order of elements. */ -trait GenSeqLike[+A, +Repr] extends GenIterableLike[A, Repr] with Equals with Parallelizable[A, parallel.ParSeq[A]] { +trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equals with Parallelizable[A, parallel.ParSeq[A]] { def seq: Seq[A] /** Selects an element by its index in the $coll. diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index 1dcc0bdac7..dd5f602c41 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -53,7 +53,7 @@ import annotation.migration * @author Aleksandar Prokopec * @since 2.9 */ -trait GenTraversableLike[+A, +Repr] extends GenTraversableOnce[A] with Parallelizable[A, parallel.ParIterable[A]] { +trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with Parallelizable[A, parallel.ParIterable[A]] { def repr: Repr diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index 305f8d768d..67ea4cdb00 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -41,7 +41,7 @@ package scala.collection * @author Aleksandar Prokopec * @since 2.9 */ -trait GenTraversableOnce[+A] { +trait GenTraversableOnce[+A] extends Any { def foreach[U](f: A => U): Unit @@ -124,6 +124,7 @@ trait GenTraversableOnce[+A] { * scala> val b = (a /:\ 5)(_+_) * b: Int = 15 * }}}*/ + @deprecated("use fold instead") def /:\[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = fold(z)(op) /** Applies a binary operator to a start value and all elements of this $coll, diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index baf5606ab5..d1f7d1cb36 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -37,7 +37,7 @@ import scala.annotation.tailrec * @define willNotTerminateInf * @define mayNotTerminateInf */ -trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { +trait IndexedSeqLike[+A, +Repr] extends Any with SeqLike[A, Repr] { self => def seq: IndexedSeq[A] diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala index 196e77c91b..9d03a11db9 100755 --- a/src/library/scala/collection/IndexedSeqOptimized.scala +++ b/src/library/scala/collection/IndexedSeqOptimized.scala @@ -22,7 +22,7 @@ import scala.annotation.tailrec * @define willNotTerminateInf * @define mayNotTerminateInf */ -trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self => +trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] { self => override /*IterableLike*/ def isEmpty: Boolean = { length == 0 } diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index 4b0c5662d8..73d4efe125 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -49,7 +49,7 @@ import annotation.bridge * @define Coll Iterable * @define coll iterable collection */ -trait IterableLike[+A, +Repr] extends Equals with TraversableLike[A, Repr] with GenIterableLike[A, Repr] { +trait IterableLike[+A, +Repr] extends Any with Equals with TraversableLike[A, Repr] with GenIterableLike[A, Repr] { self => override protected[this] def thisCollection: Iterable[A] = this.asInstanceOf[Iterable[A]] diff --git a/src/library/scala/collection/Parallelizable.scala b/src/library/scala/collection/Parallelizable.scala index 59b37aff96..5bcefb81b2 100644 --- a/src/library/scala/collection/Parallelizable.scala +++ b/src/library/scala/collection/Parallelizable.scala @@ -17,7 +17,7 @@ import parallel.Combiner * @tparam A the type of the elements in the collection * @tparam ParRepr the actual type of the collection, which has to be parallel */ -trait Parallelizable[+A, +ParRepr <: Parallel] { +trait Parallelizable[+A, +ParRepr <: Parallel] extends Any { def seq: TraversableOnce[A] diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index b51a37cf9e..526ea7e240 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -59,7 +59,7 @@ import scala.math.Ordering * @define orderDependent * @define orderDependentFold */ -trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr] with Parallelizable[A, ParSeq[A]] { self => +trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[A, Repr] with Parallelizable[A, ParSeq[A]] { self => override protected[this] def thisCollection: Seq[A] = this.asInstanceOf[Seq[A]] override protected[this] def toCollection(repr: Repr): Seq[A] = repr.asInstanceOf[Seq[A]] diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 36d45c0c8a..0da1cfb913 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -64,7 +64,8 @@ import parallel.ParIterable * @define Coll Traversable * @define coll traversable collection */ -trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] +trait TraversableLike[+A, +Repr] extends Any + with HasNewBuilder[A, Repr] with FilterMonadic[A, Repr] with TraversableOnce[A] with GenTraversableLike[A, Repr] diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 5bb2e563f6..62ea692b90 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -56,7 +56,7 @@ import annotation.unchecked.{ uncheckedVariance => uV } * * Note: will not terminate for infinite-sized collections. */ -trait TraversableOnce[+A] extends GenTraversableOnce[A] { +trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { self => /** Self-documenting abstract methods. */ @@ -360,6 +360,7 @@ trait TraversableOnce[+A] extends GenTraversableOnce[A] { object TraversableOnce { implicit def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) + implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) = new FlattenOps[A](travs map ev) @@ -391,6 +392,8 @@ object TraversableOnce { } } + class ForceImplicitAmbiguity + class MonadOps[+A](trav: TraversableOnce[A]) { def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f def flatMap[B](f: A => GenTraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f diff --git a/src/library/scala/collection/generic/FilterMonadic.scala b/src/library/scala/collection/generic/FilterMonadic.scala index 4d6d9ec6a3..d79112d616 100755 --- a/src/library/scala/collection/generic/FilterMonadic.scala +++ b/src/library/scala/collection/generic/FilterMonadic.scala @@ -12,7 +12,7 @@ package scala.collection.generic /** A template trait that contains just the `map`, `flatMap`, `foreach` and `withFilter` methods * of trait `TraversableLike`. */ -trait FilterMonadic[+A, +Repr] { +trait FilterMonadic[+A, +Repr] extends Any { def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That def flatMap[B, That](f: A => collection.GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That def foreach[U](f: A => U): Unit diff --git a/src/library/scala/collection/generic/HasNewBuilder.scala b/src/library/scala/collection/generic/HasNewBuilder.scala index 6154a56441..8f0ce01911 100755 --- a/src/library/scala/collection/generic/HasNewBuilder.scala +++ b/src/library/scala/collection/generic/HasNewBuilder.scala @@ -10,7 +10,7 @@ package generic import mutable.Builder -trait HasNewBuilder[+A, +Repr] { +trait HasNewBuilder[+A, +Repr] extends Any { /** The builder that builds instances of Repr */ protected[this] def newBuilder: Builder[A, Repr] } diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 9b52c8805c..f9697565de 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -40,7 +40,7 @@ import StringLike._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -trait StringLike[+Repr] extends collection.IndexedSeqOptimized[Char, Repr] with Ordered[String] { +trait StringLike[+Repr] extends Any with collection.IndexedSeqOptimized[Char, Repr] with Ordered[String] { self => /** Creates a string builder buffer as builder for this class */ diff --git a/src/library/scala/collection/immutable/StringOps.scala b/src/library/scala/collection/immutable/StringOps.scala index 8612357db9..97609b4c4d 100644 --- a/src/library/scala/collection/immutable/StringOps.scala +++ b/src/library/scala/collection/immutable/StringOps.scala @@ -28,7 +28,7 @@ import mutable.StringBuilder * @define Coll StringOps * @define coll string */ -final class StringOps(override val repr: String) extends StringLike[String] { +final class StringOps(override val repr: String) extends AnyVal with StringLike[String] { override protected[this] def thisCollection: WrappedString = new WrappedString(repr) override protected[this] def toCollection(repr: String): WrappedString = new WrappedString(repr) diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index f72ba78446..f0e4c79abf 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -76,7 +76,7 @@ object ArrayBuilder { this } - override def ++=(xs: TraversableOnce[T]): this.type = (xs: AnyRef) match { + override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match { case xs: WrappedArray.ofRef[_] => ensureSize(this.size + xs.length) Array.copy(xs.array, 0, elems, this.size, xs.length) diff --git a/src/library/scala/collection/mutable/FlatArray.scala b/src/library/scala/collection/mutable/FlatArray.scala new file mode 100644 index 0000000000..a7f994bf74 --- /dev/null +++ b/src/library/scala/collection/mutable/FlatArray.scala @@ -0,0 +1,150 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.collection +package mutable + +import scala.reflect.ClassManifest +import generic.CanBuildFrom + +/** + * A class representing `Array[T]`. + * + * @tparam T type of the elements in this wrapped array. + * + * @author Martin Odersky, Stephane Micheloud + * @version 1.0 + * @since 2.8 + * @define Coll WrappedArray + * @define coll wrapped array + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ +abstract sealed class FlatArray[T] +extends AbstractSeq[T] + with IndexedSeq[T] + with IndexedSeqOptimized[T, FlatArray[T]] +{ + + override protected[this] def thisCollection: FlatArray[T] = this + override protected[this] def toCollection(repr: FlatArray[T]): FlatArray[T] = repr + + /** The length of the array */ + def length: Int + + /** The element at given index */ + def apply(index: Int): T + + /** Update element at given index */ + def update(index: Int, elem: T): Unit + + override def stringPrefix = "FlatArray" + + override protected[this] def newBuilder: Builder[T, FlatArray[T]] = ??? // implemented in FlatArray.Impl + + /** Clones this object, including the underlying Array. */ + override def clone: FlatArray[T] = ??? // implemented in FlatArray.Impl +} + + +/** A companion object used to create instances of `WrappedArray`. + */ +object FlatArray { + + def empty[Boxed, Unboxed](elems: Boxed*) + (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = apply() + + def apply[Boxed, Unboxed](elems: Boxed*) + (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = { + val b = newBuilder[Boxed, Unboxed] + b.sizeHint(elems.length) + b ++= elems + b.result + } + + def newBuilder[Boxed, Unboxed] + (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): Builder[Boxed, FlatArray[Boxed]] = + new Bldr[Boxed, Unboxed](boxings, elemManifest) + + implicit def canBuildFrom[Boxed, Unboxed]( + implicit + boxings: BoxingConversions[Boxed, Unboxed], + elemManifest: ClassManifest[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] = + new CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] { + def apply(from: FlatArray[_]): Builder[Boxed, FlatArray[Boxed]] = + newBuilder[Boxed, Unboxed] + def apply: Builder[Boxed, FlatArray[Boxed]] = + newBuilder[Boxed, Unboxed] + } + + private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], manifest: ClassManifest[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] { + + private var elems: Array[Unboxed] = _ + private var capacity: Int = 0 + private var size: Int = 0 + + private def resize(size: Int) { + val newelems = manifest.newArray(size) + if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + elems = newelems + capacity = size + } + + override def sizeHint(size: Int) { + if (capacity < size) resize(size) + } + + private def ensureSize(size: Int) { + if (capacity < size) { + var newsize = if (capacity == 0) 16 else capacity * 2 + while (newsize < size) newsize *= 2 + resize(newsize) + } + } + + def +=(elem: Boxed): this.type = { + ensureSize(size + 1) + elems(size) = boxings.unbox(elem) + size += 1 + this + } + + def clear() { + size = 0 + } + + def result(): FlatArray[Boxed] = { + if (capacity == 0 || capacity != size) resize(size) + new FlatArray.Impl(elems, boxings, manifest) + } + } + + private class Impl[Boxed, Unboxed]( + elems: Array[Unboxed], + boxings: BoxingConversions[Boxed, Unboxed], + elemManifest: ClassManifest[Unboxed]) extends FlatArray[Boxed] { + + def length = elems.length + + def apply(idx: Int): Boxed = boxings.box(elems(idx)) + + def update(idx: Int, elem: Boxed) = elems(idx) = boxings.unbox(elem) + + /** Creates new builder for this collection ==> move to subclasses + */ + override protected[this] def newBuilder: Builder[Boxed, FlatArray[Boxed]] = + new Bldr[Boxed, Unboxed](boxings, elemManifest) + + /** Clones this object, including the underlying Array. */ + override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemManifest) + } +} diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index 037f3b2939..96e73522b6 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -175,10 +175,10 @@ final class ListBuffer[A] } override def ++=(xs: TraversableOnce[A]): this.type = - if (xs eq this) ++= (this take size) else super.++=(xs) + if (xs.asInstanceOf[AnyRef] eq this) ++= (this take size) else super.++=(xs) override def ++=:(xs: TraversableOnce[A]): this.type = - if (xs eq this) ++=: (this take size) else super.++=:(xs) + if (xs.asInstanceOf[AnyRef] eq this) ++=: (this take size) else super.++=:(xs) /** Clears the buffer contents. */ diff --git a/src/library/scala/math/Equiv.scala b/src/library/scala/math/Equiv.scala index 92a794578e..bd8414a18d 100644 --- a/src/library/scala/math/Equiv.scala +++ b/src/library/scala/math/Equiv.scala @@ -29,7 +29,7 @@ import java.util.Comparator * @since 2.7 */ -trait Equiv[T] { +trait Equiv[T] extends Any { /** Returns `true` iff `x` is equivalent to `y`. */ def equiv(x: T, y: T): Boolean diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala index 53d618db63..b76030718f 100644 --- a/src/library/scala/math/Ordered.scala +++ b/src/library/scala/math/Ordered.scala @@ -50,7 +50,7 @@ package scala.math * @author Martin Odersky * @version 1.1, 2006-07-24 */ -trait Ordered[A] extends java.lang.Comparable[A] { +trait Ordered[A] extends Any with java.lang.Comparable[A] { /** Result of comparing `this` with operand `that`. * diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index d393ac47fa..37be067614 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -207,18 +207,18 @@ object ClassManifest { * pass varargs as arrays into this, we get an infinitely recursive call * to boxArray. (Besides, having a separate case is more efficient) */ - def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] = + def classType[T](clazz: jClass[_]): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, Nil) /** ClassManifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class and `args` are its type arguments */ - def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) /** ClassManifest for the class type `clazz[args]`, where `clazz` is * a class with non-package prefix type `prefix` and type arguments `args`. */ - def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { @@ -251,7 +251,7 @@ object ClassManifest { /** Manifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class: todo: we should try to merge this with Manifest's class */ -private class ClassTypeManifest[T <: AnyRef]( +private class ClassTypeManifest[T]( prefix: Option[OptManifest[_]], val erasure: jClass[_], override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index e737b0ea4f..c3d989f971 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -61,7 +61,7 @@ trait StandardDefinitions { self: Universe => def vmSignature(sym: Symbol, info: Type): String /** Is symbol one of the value classes? */ - def isValueClass(sym: Symbol): Boolean // !!! better name? + def isPrimitiveValueClass(sym: Symbol): Boolean // !!! better name? /** Is symbol one of the numeric value classes? */ def isNumericValueClass(sym: Symbol): Boolean // !!! better name? diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index cc8e85b9c8..0371e2c5df 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -46,7 +46,7 @@ trait Types { self: Universe => /** Substitute types in `to` for corresponding occurrences of references to * symbols `from` in this type. */ - def substituteTypes(from: List[Symbol], to: List[Type]): Type // !!! Too many things with names like "subst" + def substituteTypes(from: List[Symbol], to: List[Type]): Type /** If this is a parameterized types, the type arguments. * Otherwise the empty list diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala index 09e1611dcd..d9b9a7843f 100644 --- a/src/library/scala/runtime/ScalaNumberProxy.scala +++ b/src/library/scala/runtime/ScalaNumberProxy.scala @@ -64,12 +64,12 @@ abstract class FractionalProxy[T : Fractional] extends ScalaNumberProxy[T] with def to(end: T, step: T): NumericRange.Inclusive[T] = NumericRange.inclusive(self, end, step) } -trait OrderedProxy[T] extends Typed[T] with Ordered[T] { +trait OrderedProxy[T] extends Any with Ordered[T] with Typed[T] { protected def ord: Ordering[T] def compare(y: T) = ord.compare(self, y) } -trait RangedProxy[T] extends Typed[T] { +trait RangedProxy[T] extends Any with Typed[T] { type ResultWithoutStep def until(end: T): ResultWithoutStep diff --git a/src/library/scala/runtime/StringAdd.scala b/src/library/scala/runtime/StringAdd.scala index ae1975cb4c..a7e78ea9a3 100644 --- a/src/library/scala/runtime/StringAdd.scala +++ b/src/library/scala/runtime/StringAdd.scala @@ -8,13 +8,15 @@ package scala.runtime -final class StringAdd(self: Any) { +/** A wrapper class that adds string concatenation `+` to any value */ +final class StringAdd(val self: Any) { + + // Note: The implicit conversion from Any to StringAdd is one of two + // implicit conversions from Any to AnyRef in Predef. It is important to have at least + // two such conversions, so that silent conversions from value types to AnyRef + // are avoided. If StringFormat should become a value class, another + // implicit conversion from Any to AnyRef has to be introduced in Predef def +(other: String) = String.valueOf(self) + other - /** Returns string formatted according to given `format` string. - * Format strings are as for `String.format` - * (@see java.lang.String.format). - */ - def formatted(fmtstr: String): String = fmtstr format self } diff --git a/src/library/scala/runtime/StringFormat.scala b/src/library/scala/runtime/StringFormat.scala new file mode 100644 index 0000000000..c120cbb14d --- /dev/null +++ b/src/library/scala/runtime/StringFormat.scala @@ -0,0 +1,27 @@ +/* *\ +** ________ ___ __ ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ |_| ** +** ** +\* */ + +package scala.runtime + +/** A wrapper class that adds a `formatted` operation to any value + */ +final class StringFormat(val self: Any) { + + // Note: The implicit conversion from Any to StringFormat is one of two + // implicit conversions from Any to AnyRef in Predef. It is important to have at least + // two such conversions, so that silent conversions from value types to AnyRef + // are avoided. If StringFormat should become a value class, another + // implicit conversion from Any to AnyRef has to be introduced in Predef + + /** Returns string formatted according to given `format` string. + * Format strings are as for `String.format` + * (@see java.lang.String.format). + */ + @inline def formatted(fmtstr: String): String = fmtstr format self + +} diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index a62d74b1f6..0c7772cd07 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -15,7 +15,7 @@ import java.util.jar.Attributes.{ Name => AttributeName } /** Loads `library.properties` from the jar. */ object Properties extends PropertiesTrait { protected def propCategory = "library" - protected def pickJarBasedOn = classOf[ScalaObject] + protected def pickJarBasedOn = classOf[Option[_]] /** Scala manifest attributes. */ diff --git a/test/files/buildmanager/t2556_3/t2556_3.check b/test/files/buildmanager/t2556_3/t2556_3.check index bf26602494..37808d2b31 100644 --- a/test/files/buildmanager/t2556_3/t2556_3.check +++ b/test/files/buildmanager/t2556_3/t2556_3.check @@ -3,8 +3,8 @@ compiling Set(A.scala, B.scala, C.scala) Changes: Map() builder > A.scala compiling Set(A.scala) -Changes: Map(class A -> List(), class B -> List(Changed(Class(B))[List((A,Object), (ScalaObject,ScalaObject))])) -invalidate C.scala because parents have changed [Changed(Class(B))[List((A,Object), (ScalaObject,ScalaObject))]] +Changes: Map(class A -> List(), class B -> List(Changed(Class(B))[List((A,Object))])) +invalidate C.scala because parents have changed [Changed(Class(B))[List((A,Object))]] invalidate B.scala because it references invalid (no longer inherited) definition [ParentChanged(Class(C))] compiling Set(B.scala, C.scala) B.scala:3: error: type mismatch; diff --git a/test/files/codelib/code.jar.desired.sha1 b/test/files/codelib/code.jar.desired.sha1 index dbf19cafd7..8dabf404b9 100644 --- a/test/files/codelib/code.jar.desired.sha1 +++ b/test/files/codelib/code.jar.desired.sha1 @@ -1 +1 @@ -e25f1daf9010b9dc6038ae7069fc9d0f7d48a53b ?code.jar +e76a8883d275ca4870f745b505fb0a1cb9cbe446 ?code.jar diff --git a/test/files/lib/scalacheck.jar.desired.sha1 b/test/files/lib/scalacheck.jar.desired.sha1 index b104f58897..2be7479415 100644 --- a/test/files/lib/scalacheck.jar.desired.sha1 +++ b/test/files/lib/scalacheck.jar.desired.sha1 @@ -1 +1 @@ -2a3e19c3d8d93be661e66f941f19e7d49c667c2b ?scalacheck.jar +f8cd51e0f78e30b3ac444b741b0b2249ac8248bb ?scalacheck.jar diff --git a/test/files/neg/anytrait.check b/test/files/neg/anytrait.check new file mode 100644 index 0000000000..9dd970b58c --- /dev/null +++ b/test/files/neg/anytrait.check @@ -0,0 +1,7 @@ +anytrait.scala:3: error: this statement is not allowed in universal trait extending from class Any: private[this] var x: Int = 1 + var x = 1 + ^ +anytrait.scala:5: error: this statement is not allowed in universal trait extending from class Any: T.this.x_=(T.this.x.+(1)) + { x += 1 } + ^ +two errors found diff --git a/test/files/neg/anytrait.scala b/test/files/neg/anytrait.scala new file mode 100644 index 0000000000..1501486105 --- /dev/null +++ b/test/files/neg/anytrait.scala @@ -0,0 +1,10 @@ +trait T extends Any { + + var x = 1 + + { x += 1 } + + type T = Int + + val y: T +} diff --git a/test/files/neg/anyval-anyref-parent.check b/test/files/neg/anyval-anyref-parent.check new file mode 100644 index 0000000000..fe20e5de81 --- /dev/null +++ b/test/files/neg/anyval-anyref-parent.check @@ -0,0 +1,23 @@ +anyval-anyref-parent.scala:2: error: only classes (not traits) are allowed to extend AnyVal +trait Foo2 extends AnyVal // fail + ^ +anyval-anyref-parent.scala:5: error: Any does not have a constructor +class Bar1 extends Any // fail + ^ +anyval-anyref-parent.scala:6: error: value class needs to have exactly one public val parameter +class Bar2(x: Int) extends AnyVal // fail + ^ +anyval-anyref-parent.scala:10: error: illegal inheritance; superclass Any + is not a subclass of the superclass Object + of the mixin trait Immutable +trait Foo4 extends Any with Immutable // fail + ^ +anyval-anyref-parent.scala:11: error: illegal inheritance; superclass AnyVal + is not a subclass of the superclass Object + of the mixin trait Immutable +trait Foo5 extends AnyVal with Immutable // fail + ^ +anyval-anyref-parent.scala:11: error: only classes (not traits) are allowed to extend AnyVal +trait Foo5 extends AnyVal with Immutable // fail + ^ +6 errors found diff --git a/test/files/neg/anyval-anyref-parent.scala b/test/files/neg/anyval-anyref-parent.scala new file mode 100644 index 0000000000..f927992e59 --- /dev/null +++ b/test/files/neg/anyval-anyref-parent.scala @@ -0,0 +1,12 @@ +trait Foo1 extends Any +trait Foo2 extends AnyVal // fail +trait Foo3 extends AnyRef + +class Bar1 extends Any // fail +class Bar2(x: Int) extends AnyVal // fail +class Bar3(val x: Int) extends AnyVal // fail +class Bar4 extends AnyRef + +trait Foo4 extends Any with Immutable // fail +trait Foo5 extends AnyVal with Immutable // fail +trait Foo6 extends AnyRef with Immutable diff --git a/test/files/neg/anyval-sealed.check b/test/files/neg/anyval-sealed.check deleted file mode 100644 index 48a457b496..0000000000 --- a/test/files/neg/anyval-sealed.check +++ /dev/null @@ -1,12 +0,0 @@ -anyval-sealed.scala:2: error: match is not exhaustive! -missing combination Byte -missing combination Char -missing combination Double -missing combination Float -missing combination Long -missing combination Short -missing combination Unit - - def f(x: AnyVal) = x match { - ^ -one error found diff --git a/test/files/neg/anyval-sealed.flags b/test/files/neg/anyval-sealed.flags deleted file mode 100644 index 85d8eb2ba2..0000000000 --- a/test/files/neg/anyval-sealed.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings diff --git a/test/files/neg/anyval-sealed.scala b/test/files/neg/anyval-sealed.scala deleted file mode 100644 index 232a183479..0000000000 --- a/test/files/neg/anyval-sealed.scala +++ /dev/null @@ -1,6 +0,0 @@ -class A { - def f(x: AnyVal) = x match { - case _: Boolean => 1 - case _: Int => 2 - } -}
\ No newline at end of file diff --git a/test/files/neg/override-object-no.check b/test/files/neg/override-object-no.check index 6e028d0add..f9fb37381b 100644 --- a/test/files/neg/override-object-no.check +++ b/test/files/neg/override-object-no.check @@ -1,13 +1,13 @@ override-object-no.scala:14: error: overriding object Bar in trait Foo with object Bar in trait Foo2: an overriding object must conform to the overridden object's class bound; - found : case1.Bippy with ScalaObject - required: case1.Bippy with case1.Bippo with ScalaObject + found : case1.Bippy + required: case1.Bippy with case1.Bippo override object Bar extends Bippy { // err ^ override-object-no.scala:21: error: overriding object Bar in trait Quux1 with object Bar in trait Quux2: an overriding object must conform to the overridden object's class bound; - found : Object with ScalaObject{def g: String} - required: Object with ScalaObject{def g: Int} + found : Object{def g: String} + required: Object{def g: Int} trait Quux2 extends Quux1 { override object Bar { def g = "abc" } } // err ^ override-object-no.scala:25: error: overriding object Bar in trait Quux3 of type object Quux4.this.Bar; @@ -16,8 +16,8 @@ override-object-no.scala:25: error: overriding object Bar in trait Quux3 of type ^ override-object-no.scala:43: error: overriding object A in class Foo with object A in class P2: an overriding object must conform to the overridden object's class bound; - found : case2.Bar[List[String]] with ScalaObject - required: case2.Bar[Traversable[String]] with ScalaObject + found : case2.Bar[List[String]] + required: case2.Bar[Traversable[String]] override object A extends Bar[List[String]] // err ^ four errors found diff --git a/test/files/neg/t0699.check b/test/files/neg/t0699.check index 45d3e849cc..c944da8c10 100644 --- a/test/files/neg/t0699.check +++ b/test/files/neg/t0699.check @@ -1,10 +1,10 @@ -B.scala:2: error: illegal inheritance from sealed trait T: t0699/B.scala != t0699/A.scala +B.scala:2: error: illegal inheritance from sealed trait T trait T1 extends A.T ^ -B.scala:3: error: illegal inheritance from sealed class C: t0699/B.scala != t0699/A.scala +B.scala:3: error: illegal inheritance from sealed class C trait T2 extends A.C ^ -B.scala:4: error: illegal inheritance from sealed class C: t0699/B.scala != t0699/A.scala +B.scala:4: error: illegal inheritance from sealed class C class C1 extends A.C ^ three errors found diff --git a/test/files/neg/t0764.check b/test/files/neg/t0764.check index 0788db7f6e..e14c7705b8 100644 --- a/test/files/neg/t0764.check +++ b/test/files/neg/t0764.check @@ -1,5 +1,5 @@ t0764.scala:13: error: type mismatch; - found : Object with Node{type T = _1.type} where val _1: Node{type T = NextType} + found : Node{type T = _1.type} where val _1: Node{type T = NextType} required: Node{type T = Main.this.AType} new Main[AType]( (value: AType).prepend ) ^ diff --git a/test/files/neg/t2641.check b/test/files/neg/t2641.check index 9e2f02ac47..909f4f0cf3 100644 --- a/test/files/neg/t2641.check +++ b/test/files/neg/t2641.check @@ -9,11 +9,7 @@ t2641.scala:17: error: illegal inheritance; self-type ManagedSeq does not conform to scala.collection.TraversableView[A,ManagedSeqStrict[A]]'s selftype scala.collection.TraversableView[A,ManagedSeqStrict[A]] with TraversableView[A, ManagedSeqStrict[A]] ^ -t2641.scala:16: error: illegal inheritance; - self-type ManagedSeq does not conform to ScalaObject's selftype ScalaObject - extends ManagedSeqStrict[A] - ^ t2641.scala:27: error: value managedIterator is not a member of ManagedSeq override def managedIterator = self.managedIterator slice (from, until) ^ -5 errors found +four errors found diff --git a/test/files/neg/t3691.check b/test/files/neg/t3691.check index cd7b440dce..bdf6c268b2 100644 --- a/test/files/neg/t3691.check +++ b/test/files/neg/t3691.check @@ -1,10 +1,10 @@ t3691.scala:4: error: type mismatch; - found : Object with Test.A[String] + found : Test.A[String] required: AnyRef{type A[x]} val b = (new A[String]{}): { type A[x] } // not ok ^ t3691.scala:5: error: type mismatch; - found : Object with Test.A[String] + found : Test.A[String] required: AnyRef{type A} val c = (new A[String]{}): { type A } // not ok ^ diff --git a/test/files/neg/t464-neg.check b/test/files/neg/t464-neg.check index aea1987b2e..e822e7fb6b 100644 --- a/test/files/neg/t464-neg.check +++ b/test/files/neg/t464-neg.check @@ -1,7 +1,7 @@ t464-neg.scala:7: error: not found: value f1 f1() ^ -t464-neg.scala:8: error: method f1 in class A cannot be accessed in A with ScalaObject +t464-neg.scala:8: error: method f1 in class A cannot be accessed in A super.f1() ^ t464-neg.scala:9: error: value f2 is not a member of B @@ -10,7 +10,7 @@ t464-neg.scala:9: error: value f2 is not a member of B t464-neg.scala:10: error: method f3 in class A cannot be accessed in B f3() ^ -t464-neg.scala:11: error: method f3 in class A cannot be accessed in A with ScalaObject +t464-neg.scala:11: error: method f3 in class A cannot be accessed in A super.f3() ^ 5 errors found diff --git a/test/files/neg/t4877.check b/test/files/neg/t4877.check index 0f72300bb4..a4b1e6a50d 100644 --- a/test/files/neg/t4877.check +++ b/test/files/neg/t4877.check @@ -9,7 +9,7 @@ t4877.scala:6: error: type mismatch; def foo3: AnyRef { def bar(x: Int): Int } = new AnyRef { def bar(x: Int) = "abc" } ^ t4877.scala:7: error: type mismatch; - found : Object with C{def bar(x: Int): Int} + found : C{def bar(x: Int): Int} required: C{def bar(x: Int): Int; def quux(x: Int): Int} def foo4: C { def bar(x: Int): Int ; def quux(x: Int): Int } = new C { def bar(x: Int) = 5 } ^ diff --git a/test/files/neg/t5060.check b/test/files/neg/t5060.check index ab860c9d5b..e71f30ccdb 100644 --- a/test/files/neg/t5060.check +++ b/test/files/neg/t5060.check @@ -1,7 +1,7 @@ -t5060.scala:2: error: covariant type T occurs in contravariant position in type => Object with ScalaObject{def contains(x: T): Unit} of value foo0 +t5060.scala:2: error: covariant type T occurs in contravariant position in type => Object{def contains(x: T): Unit} of value foo0 val foo0 = { ^ -t5060.scala:6: error: covariant type T occurs in contravariant position in type => Object with ScalaObject{def contains(x: T): Unit} of method foo1 +t5060.scala:6: error: covariant type T occurs in contravariant position in type => Object{def contains(x: T): Unit} of method foo1 def foo1 = { ^ two errors found diff --git a/test/files/neg/t5529.check b/test/files/neg/t5529.check index 78a26aeb50..5d2175fa79 100644 --- a/test/files/neg/t5529.check +++ b/test/files/neg/t5529.check @@ -4,9 +4,7 @@ t5529.scala:12: error: File is already defined as class File t5529.scala:10: error: class type required but test.Test.File found sealed class Dir extends File { } ^ -t5529.scala:10: error: illegal inheritance; super<none> - is not a subclass of the superclass Object - of the mixin trait ScalaObject +t5529.scala:10: error: test.Test.File does not have a constructor sealed class Dir extends File { } ^ three errors found diff --git a/test/files/neg/t664.check b/test/files/neg/t664.check index 43a6bea074..cbdf53daea 100644 --- a/test/files/neg/t664.check +++ b/test/files/neg/t664.check @@ -1,7 +1,7 @@ -t664.scala:4: error: type Foo is not a member of test.Test with ScalaObject +t664.scala:4: error: type Foo is not a member of test.Test trait Foo extends super.Foo { ^ -t664.scala:5: error: type Bar is not a member of AnyRef with ScalaObject +t664.scala:5: error: type Bar is not a member of AnyRef trait Bar extends super.Bar; ^ two errors found diff --git a/test/files/neg/t900.check b/test/files/neg/t900.check index cede26258b..047094ad6e 100644 --- a/test/files/neg/t900.check +++ b/test/files/neg/t900.check @@ -2,8 +2,8 @@ t900.scala:4: error: type mismatch; found : Foo.this.x.type (with underlying type Foo.this.bar) required: AnyRef Note that implicit conversions are not applicable because they are ambiguous: - both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] - and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] + both method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd + and method any2stringfmt in object Predef of type (x: Any)scala.runtime.StringFormat are possible conversion functions from Foo.this.x.type to AnyRef def break(): x.type ^ diff --git a/test/files/neg/valueclasses-doubledefs.check b/test/files/neg/valueclasses-doubledefs.check new file mode 100644 index 0000000000..556d7a0900 --- /dev/null +++ b/test/files/neg/valueclasses-doubledefs.check @@ -0,0 +1,7 @@ +valueclasses-doubledefs.scala:5: error: double definition: +method apply:(x: Meter)String and +method apply:(x: Double)String at line 4 +have same type after erasure: (x: Double)String + def apply(x: Meter) = x.toString + ^ +one error found diff --git a/test/files/neg/valueclasses-doubledefs.scala b/test/files/neg/valueclasses-doubledefs.scala new file mode 100644 index 0000000000..87bcf8fee3 --- /dev/null +++ b/test/files/neg/valueclasses-doubledefs.scala @@ -0,0 +1,6 @@ +class Meter(val x: Double) extends AnyVal + +class Foo { + def apply(x: Double) = x.toString + def apply(x: Meter) = x.toString +} diff --git a/test/files/neg/valueclasses.check b/test/files/neg/valueclasses.check new file mode 100644 index 0000000000..756a0474fa --- /dev/null +++ b/test/files/neg/valueclasses.check @@ -0,0 +1,46 @@ +valueclasses.scala:3: error: only classes (not traits) are allowed to extend AnyVal +trait T extends AnyVal // fail + ^ +valueclasses.scala:6: error: value class may not be a member of another class + class Bar(x: Int) extends AnyVal // fail + ^ +valueclasses.scala:8: error: value class may not be a local class + class Baz(x: Int) extends AnyVal // fail + ^ +valueclasses.scala:12: error: value class needs to have exactly one public val parameter +class V1 extends AnyVal // fail + ^ +valueclasses.scala:14: error: value class needs to have a publicly accessible val parameter +class V2(private[test] val x: Int) extends AnyVal // fail + ^ +valueclasses.scala:15: error: value class needs to have a publicly accessible val parameter +class V3(protected[test] val x: Int) extends AnyVal // fail + ^ +valueclasses.scala:16: error: value class needs to have a publicly accessible val parameter +class V4(protected val x: Int) extends AnyVal // fail + ^ +valueclasses.scala:17: error: value class needs to have a publicly accessible val parameter +class V5(private val x: Int) extends AnyVal // fail + ^ +valueclasses.scala:19: error: value class needs to have exactly one public val parameter +class V6(val x: Int, val y: String) extends AnyVal // fail + ^ +valueclasses.scala:20: error: illegal parameter for value class +class V7(val x: Int, private[this] val y: String) extends AnyVal // fail + ^ +valueclasses.scala:21: error: value class needs to have exactly one public val parameter +class V8(var x: Int) extends AnyVal // fail + ^ +valueclasses.scala:24: error: this statement is not allowed in value class: private[this] val y: Int = V9.this.x + val y = x // fail + ^ +valueclasses.scala:29: error: type parameter of value class may not be specialized +class V12[@specialized T, U](val x: (T, U)) extends AnyVal // fail + ^ +valueclasses.scala:31: error: value class needs to have exactly one public val parameter +class V13(x: Int) extends AnyVal // fail + ^ +valueclasses.scala:45: error: value class must have public primary constructor +final class TOD private (val secondsOfDay: Int) extends AnyVal { // should fail with private constructor + ^ +15 errors found diff --git a/test/files/neg/valueclasses.scala b/test/files/neg/valueclasses.scala new file mode 100644 index 0000000000..e405d95489 --- /dev/null +++ b/test/files/neg/valueclasses.scala @@ -0,0 +1,54 @@ +package test + +trait T extends AnyVal // fail + +class Foo { + class Bar(x: Int) extends AnyVal // fail + def foo() { + class Baz(x: Int) extends AnyVal // fail + } +} + +class V1 extends AnyVal // fail + +class V2(private[test] val x: Int) extends AnyVal // fail +class V3(protected[test] val x: Int) extends AnyVal // fail +class V4(protected val x: Int) extends AnyVal // fail +class V5(private val x: Int) extends AnyVal // fail + +class V6(val x: Int, val y: String) extends AnyVal // fail +class V7(val x: Int, private[this] val y: String) extends AnyVal // fail +class V8(var x: Int) extends AnyVal // fail + +class V9(val x: Int) extends AnyVal { + val y = x // fail +} + +class V10[T](val x: T) extends AnyVal // ok +class V11[T](val x: List[T]) extends AnyVal // ok +class V12[@specialized T, U](val x: (T, U)) extends AnyVal // fail + +class V13(x: Int) extends AnyVal // fail + + +package time { + +object TOD { + final val SecondsPerDay = 86400 + + def apply(seconds: Int) = { + val n = seconds % SecondsPerDay + new TOD(if (n >= 0) n else n + SecondsPerDay) + } +} + +final class TOD private (val secondsOfDay: Int) extends AnyVal { // should fail with private constructor + def hours = secondsOfDay / 3600 + def minutes = (secondsOfDay / 60) % 60 + def seconds = secondsOfDay % 60 + + override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds) +} +} + + diff --git a/test/files/neg/variances.check b/test/files/neg/variances.check index 4eaab56cef..dc72b05e1e 100644 --- a/test/files/neg/variances.check +++ b/test/files/neg/variances.check @@ -4,7 +4,7 @@ variances.scala:4: error: covariant type A occurs in contravariant position in t variances.scala:14: error: covariant type A occurs in contravariant position in type A of value a private[this] def setA(a : A) = this.a = a ^ -variances.scala:16: error: covariant type A occurs in invariant position in supertype test.C[A] with ScalaObject of object Baz +variances.scala:16: error: covariant type A occurs in invariant position in supertype test.C[A] of object Baz object Baz extends C[A] ^ variances.scala:63: error: covariant type A occurs in contravariant position in type => test.Covariant.T[A]{val m: A => A} of value x diff --git a/test/files/pos/anyval-children.flags b/test/files/pos/anyval-children.flags new file mode 100644 index 0000000000..80fce051e6 --- /dev/null +++ b/test/files/pos/anyval-children.flags @@ -0,0 +1 @@ +-Ystop-after:erasure
\ No newline at end of file diff --git a/test/files/pos/t1050.scala b/test/files/pos/t1050.scala index e017e30713..d34b0cff16 100644 --- a/test/files/pos/t1050.scala +++ b/test/files/pos/t1050.scala @@ -1,7 +1,7 @@ package t1050 abstract class A { - type T <: scala.ScalaObject + type T <: scala.AnyRef class A { this: T => def b = 3 def c = b diff --git a/test/files/pos/t715/meredith_1.scala b/test/files/pos/t715/meredith_1.scala index 3ed2e57d7a..8261b9881a 100644 --- a/test/files/pos/t715/meredith_1.scala +++ b/test/files/pos/t715/meredith_1.scala @@ -3,7 +3,7 @@ package com.sap.dspace.model.othello; import scala.xml._ trait XMLRenderer { - type T <: {def getClass() : java.lang.Class[_]} + type T <: Any {def getClass() : java.lang.Class[_]} val valueTypes = List( classOf[java.lang.Boolean], diff --git a/test/files/pos/trait-parents.scala b/test/files/pos/trait-parents.scala new file mode 100644 index 0000000000..f6a2688751 --- /dev/null +++ b/test/files/pos/trait-parents.scala @@ -0,0 +1,16 @@ +trait Bip extends Any +trait Foo extends Any +trait Bar extends AnyRef +trait Quux + +object Test { + def f(x: Bip) = 1 + def g1(x: Foo with Bip) = f(x) + + def main(args: Array[String]): Unit = { + f(new Bip with Foo { }) + f(new Foo with Bip { }) + g1(new Bip with Foo { }) + g1(new Foo with Bip { }) + } +} diff --git a/test/files/run/Meter.check b/test/files/run/Meter.check new file mode 100644 index 0000000000..7562f9a1bf --- /dev/null +++ b/test/files/run/Meter.check @@ -0,0 +1,21 @@ +2.0 +4.0m +false +x.isInstanceOf[Meter]: true +x.hashCode: 1072693248 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(1.0m, 2.0m) +1.0m +>>>1.0m<<< 1.0m +>>>2.0m<<< 2.0m +testing wrapped arrays +FlatArray(1.0m, 2.0m) +1.0m +>>>1.0m<<< 1.0m +>>>2.0m<<< 2.0m +FlatArray(2.0m, 3.0m) +ArrayBuffer(1.0, 2.0) +FlatArray(0.3048ft, 0.6096ft) diff --git a/test/files/run/Meter.scala b/test/files/run/Meter.scala new file mode 100644 index 0000000000..515e46de24 --- /dev/null +++ b/test/files/run/Meter.scala @@ -0,0 +1,102 @@ +package a { + class Meter(val underlying: Double) extends AnyVal with _root_.b.Printable { + def + (other: Meter): Meter = + new Meter(this.underlying + other.underlying) + def / (other: Meter): Double = this.underlying / other.underlying + def / (factor: Double): Meter = new Meter(this.underlying / factor) + def < (other: Meter): Boolean = this.underlying < other.underlying + def toFoot: Foot = new Foot(this.underlying * 0.3048) + override def print = { Console.print(">>>"); super.print; proprint } + override def toString: String = underlying.toString+"m" + } + + object Meter extends (Double => Meter) { + + def apply(x: Double): Meter = new Meter(x) + + implicit val boxings = new BoxingConversions[Meter, Double] { + def box(x: Double) = new Meter(x) + def unbox(m: Meter) = m.underlying + } + } + + class Foot(val unbox: Double) extends AnyVal { + def + (other: Foot): Foot = + new Foot(this.unbox + other.unbox) + override def toString = unbox.toString+"ft" + } + object Foot { + implicit val boxings = new BoxingConversions[Foot, Double] { + def box(x: Double) = new Foot(x) + def unbox(m: Foot) = m.unbox + } + } + +} +package b { + trait Printable extends Any { + def print: Unit = Console.print(this) + protected def proprint = Console.print("<<<") + } +} +import a._ +import _root_.b._ +object Test extends App { + + { + val x: Meter = new Meter(1) + val a: Object = x.asInstanceOf[Object] + val y: Meter = a.asInstanceOf[Meter] + + val u: Double = 1 + val b: Object = u.asInstanceOf[Object] + val v: Double = b.asInstanceOf[Double] + } + + val x = new Meter(1) + val y = x + println((x + x) / x) + println((x + x) / 0.5) + println((x < x).toString) + println("x.isInstanceOf[Meter]: "+x.isInstanceOf[Meter]) + + + println("x.hashCode: "+x.hashCode) + println("x == 1: "+(x == 1)) + println("x == y: "+(x == y)) + assert(x.hashCode == (1.0).hashCode) + + val a: Any = x + val b: Any = y + println("a == b: "+(a == b)) + + { println("testing native arrays") + val arr = Array(x, y + x) + println(arr.deep) + def foo[T <: Printable](x: Array[T]) { + for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + } + val m = arr(0) + println(m) + foo(arr) + } + + { println("testing wrapped arrays") + import collection.mutable.FlatArray + val arr = FlatArray(x, y + x) + println(arr) + def foo(x: FlatArray[Meter]) { + for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + } + val m = arr(0) + println(m) + foo(arr) + val ys: Seq[Meter] = arr map (_ + new Meter(1)) + println(ys) + val zs = arr map (_ / Meter(1)) + println(zs) + val fs = arr map (_.toFoot) + println(fs) + } + +} diff --git a/test/files/run/MeterCaseClass.check b/test/files/run/MeterCaseClass.check new file mode 100644 index 0000000000..08370d2097 --- /dev/null +++ b/test/files/run/MeterCaseClass.check @@ -0,0 +1,21 @@ +2.0 +Meter(4.0) +false +x.isInstanceOf[Meter]: true +x.hashCode: 1072693248 +x == 1: false +x == y: true +a == b: true +testing native arrays +Array(Meter(1.0), Meter(2.0)) +Meter(1.0) +>>>Meter(1.0)<<< Meter(1.0) +>>>Meter(2.0)<<< Meter(2.0) +testing wrapped arrays +FlatArray(Meter(1.0), Meter(2.0)) +Meter(1.0) +>>>Meter(1.0)<<< Meter(1.0) +>>>Meter(2.0)<<< Meter(2.0) +FlatArray(Meter(2.0), Meter(3.0)) +ArrayBuffer(1.0, 2.0) +FlatArray(0.3048ft, 0.6096ft) diff --git a/test/files/run/MeterCaseClass.scala b/test/files/run/MeterCaseClass.scala new file mode 100644 index 0000000000..8459163f31 --- /dev/null +++ b/test/files/run/MeterCaseClass.scala @@ -0,0 +1,99 @@ +package a { + case class Meter(underlying: Double) extends AnyVal with _root_.b.Printable { + def + (other: Meter): Meter = + new Meter(this.underlying + other.underlying) + def / (other: Meter): Double = this.underlying / other.underlying + def / (factor: Double): Meter = new Meter(this.underlying / factor) + def < (other: Meter): Boolean = this.underlying < other.underlying + def toFoot: Foot = new Foot(this.underlying * 0.3048) + override def print = { Console.print(">>>"); super.print; proprint } + } + + object Meter extends (Double => Meter) { + + implicit val boxings = new BoxingConversions[Meter, Double] { + def box(x: Double) = new Meter(x) + def unbox(m: Meter) = m.underlying + } + } + + class Foot(val unbox: Double) extends AnyVal { + def + (other: Foot): Foot = + new Foot(this.unbox + other.unbox) + override def toString = unbox.toString+"ft" + } + object Foot { + implicit val boxings = new BoxingConversions[Foot, Double] { + def box(x: Double) = new Foot(x) + def unbox(m: Foot) = m.unbox + } + } + +} +package b { + trait Printable extends Any { + def print: Unit = Console.print(this) + protected def proprint = Console.print("<<<") + } +} +import a._ +import _root_.b._ +object Test extends App { + + { + val x: Meter = new Meter(1) + val a: Object = x.asInstanceOf[Object] + val y: Meter = a.asInstanceOf[Meter] + + val u: Double = 1 + val b: Object = u.asInstanceOf[Object] + val v: Double = b.asInstanceOf[Double] + } + + val x = new Meter(1) + val y = x + println((x + x) / x) + println((x + x) / 0.5) + println((x < x).toString) + println("x.isInstanceOf[Meter]: "+x.isInstanceOf[Meter]) + + + println("x.hashCode: "+x.hashCode) + println("x == 1: "+(x == 1)) + println("x == y: "+(x == y)) + assert(x.hashCode == (1.0).hashCode) + + val a: Any = x + val b: Any = y + println("a == b: "+(a == b)) + + { println("testing native arrays") + val arr = Array(x, y + x) + println(arr.deep) + def foo[T <: Printable](x: Array[T]) { + for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + } + val m = arr(0) + println(m) + foo(arr) + } + + { println("testing wrapped arrays") + import collection.mutable.FlatArray + val arr = FlatArray(x, y + x) + println(arr) + def foo(x: FlatArray[Meter]) { + for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + } + val m = arr(0) + println(m) + foo(arr) + val ys: Seq[Meter] = arr map (_ + new Meter(1)) + println(ys) + val zs = arr map (_ / Meter(1)) + println(zs) + val fs = arr map (_.toFoot) + println(fs) + } + +} diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check index 41dc1f767c..36a458dacc 100644 --- a/test/files/run/existentials3.check +++ b/test/files/run/existentials3.check @@ -1,22 +1,22 @@ -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.ScalaObject with scala.Product with scala.Serializable] with scala.ScalaObject with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.ScalaObject with scala.Product with scala.Serializable -Object with Test$ToS with scala.ScalaObject -Object with Test$ToS with scala.ScalaObject -Object with Test$ToS with scala.ScalaObject -scala.Function0[Object with Test$ToS with scala.ScalaObject] -scala.Function0[Object with Test$ToS with scala.ScalaObject] -_ <: Object with _ <: Object with Object with Test$ToS with scala.ScalaObject -_ <: Object with _ <: Object with _ <: Object with Test$ToS with scala.ScalaObject -scala.collection.immutable.List[Object with scala.collection.Seq[Int] with scala.ScalaObject] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int] with scala.ScalaObject] -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.ScalaObject with scala.Product with scala.Serializable] with scala.ScalaObject with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.ScalaObject with scala.Product with scala.Serializable -Object with Test$ToS with scala.ScalaObject -Object with Test$ToS with scala.ScalaObject -Object with Test$ToS with scala.ScalaObject -scala.Function0[Object with Test$ToS with scala.ScalaObject] -scala.Function0[Object with Test$ToS with scala.ScalaObject] -_ <: Object with _ <: Object with Object with Test$ToS with scala.ScalaObject -_ <: Object with _ <: Object with _ <: Object with Test$ToS with scala.ScalaObject -scala.collection.immutable.List[Object with scala.collection.Seq[Int] with scala.ScalaObject] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int] with scala.ScalaObject] +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/genericValueClass.check b/test/files/run/genericValueClass.check new file mode 100644 index 0000000000..ec3a41a6a9 --- /dev/null +++ b/test/files/run/genericValueClass.check @@ -0,0 +1,2 @@ +(1,abc) +(2,def) diff --git a/test/files/run/genericValueClass.scala b/test/files/run/genericValueClass.scala new file mode 100644 index 0000000000..68162bb685 --- /dev/null +++ b/test/files/run/genericValueClass.scala @@ -0,0 +1,17 @@ +final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal { + @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) + def →[B](y: B): Tuple2[A, B] = ->(y) +} + +object Test extends App { + { + @inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) + val x = 1 -> "abc" + println(x) + } + + { + val y = 2 -> "def" + println(y) + } +} diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index c69d1b54a6..feb0619525 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,4 +1,4 @@ -T<java.lang.Object> interface scala.ScalaObject +T<java.lang.Object> List(A, char, class java.lang.Object) a public <T> java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest<T>) diff --git a/test/files/run/programmatic-main.check b/test/files/run/programmatic-main.check index 6f253f5de1..d16e2c5178 100644 --- a/test/files/run/programmatic-main.check +++ b/test/files/run/programmatic-main.check @@ -5,24 +5,26 @@ packageobjects 3 load package objects typer 4 the meat and potatoes: type the trees superaccessors 5 add super accessors in traits and nested classes - pickler 6 serialize symbol tables - refchecks 7 reference/override checking, translate nested objects - uncurry 8 uncurry, translate function values to anonymous classes - tailcalls 9 replace tail calls by jumps - specialize 10 @specialized-driven class and method specialization - explicitouter 11 this refs to outer pointers, translate patterns - erasure 12 erase types, add interfaces for traits - lazyvals 13 allocate bitmaps, translate lazy vals into lazified defs - lambdalift 14 move nested functions to top level - constructors 15 move field definitions into constructors - flatten 16 eliminate inner classes - mixin 17 mixin composition - cleanup 18 platform-specific cleanups, generate reflective calls - icode 19 generate portable intermediate code - inliner 20 optimization: do inlining -inlineExceptionHandlers 21 optimization: inline exception handlers - closelim 22 optimization: eliminate uncalled closures - dce 23 optimization: eliminate dead code - jvm 24 generate JVM bytecode - terminal 25 The last phase in the compiler chain + extmethods 6 add extension methods for inline classes + pickler 7 serialize symbol tables + refchecks 8 reference/override checking, translate nested objects + uncurry 9 uncurry, translate function values to anonymous classes + tailcalls 10 replace tail calls by jumps + specialize 11 @specialized-driven class and method specialization + explicitouter 12 this refs to outer pointers, translate patterns + erasure 13 erase types, add interfaces for traits + posterasure 14 clean up erased inline classes + lazyvals 15 allocate bitmaps, translate lazy vals into lazified defs + lambdalift 16 move nested functions to top level + constructors 17 move field definitions into constructors + flatten 18 eliminate inner classes + mixin 19 mixin composition + cleanup 20 platform-specific cleanups, generate reflective calls + icode 21 generate portable intermediate code + inliner 22 optimization: do inlining +inlineExceptionHandlers 23 optimization: inline exception handlers + closelim 24 optimization: eliminate uncalled closures + dce 25 optimization: eliminate dead code + jvm 26 generate JVM bytecode + terminal 27 The last phase in the compiler chain diff --git a/test/files/run/reify_ann1a.check b/test/files/run/reify_ann1a.check index 2822238706..97d4848a49 100644 --- a/test/files/run/reify_ann1a.check +++ b/test/files/run/reify_ann1a.check @@ -1,5 +1,5 @@ { - @new ann(immutable.this.List.apply[String]("1a")) @new ann(immutable.this.List.apply[String]("1b")) class C[@new ann(immutable.this.List.apply[String]("2a")) @new ann(immutable.this.List.apply[String]("2b")) T>: Nothing <: Any] extends Object with ScalaObject { + @new ann(immutable.this.List.apply[String]("1a")) @new ann(immutable.this.List.apply[String]("1b")) class C[@new ann(immutable.this.List.apply[String]("2a")) @new ann(immutable.this.List.apply[String]("2b")) T>: Nothing <: Any] extends scala.AnyRef { @new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b")) = _; def <init>(@new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b"))) = { super.<init>(); @@ -14,7 +14,7 @@ () } { - @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T>: Nothing <: Any] extends Object with ScalaObject { + @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T>: Nothing <: Any] extends scala.AnyRef { @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; def <init>(@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { C.super.<init>(); diff --git a/test/files/run/reify_ann1b.check b/test/files/run/reify_ann1b.check index e240e1e0ce..ceebc0e2ed 100644 --- a/test/files/run/reify_ann1b.check +++ b/test/files/run/reify_ann1b.check @@ -1,5 +1,5 @@ { - @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T>: Nothing <: Any] extends Object with ScalaObject { + @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T>: Nothing <: Any] extends scala.AnyRef { @new ann(bar = "3a") @new ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; def <init>(@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { super.<init>(); @@ -14,7 +14,7 @@ () } { - @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T>: Nothing <: Any] extends Object with ScalaObject { + @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T>: Nothing <: Any] extends scala.AnyRef { @ann(bar = "3a") @ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; def <init>(@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { C.super.<init>(); diff --git a/test/files/run/reify_classfileann_a.check b/test/files/run/reify_classfileann_a.check index 1773263a94..419d916907 100644 --- a/test/files/run/reify_classfileann_a.check +++ b/test/files/run/reify_classfileann_a.check @@ -1,5 +1,5 @@ { - @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends Object with ScalaObject { + @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends scala.AnyRef { def <init>() = { super.<init>(); () @@ -8,7 +8,7 @@ () } { - @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends Object with ScalaObject { + @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends scala.AnyRef { def <init>(): C = { C.super.<init>(); () diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check index 944846541f..69f0a9ce30 100644 --- a/test/files/run/repl-parens.check +++ b/test/files/run/repl-parens.check @@ -66,7 +66,7 @@ scala> 55 ; () => 5 res13: () => Int = <function0> scala> () => { class X ; new X } -res14: () => Object with ScalaObject = <function0> +res14: () => Object = <function0> scala> diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check index dc521fb8ca..d023bc91f7 100644 --- a/test/files/run/t1195.check +++ b/test/files/run/t1195.check @@ -1,6 +1,6 @@ -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.ScalaObject with scala.Product with scala.Serializable] with scala.ScalaObject with scala.Serializable with java.lang.Object -_ <: Object with scala.ScalaObject with scala.Product with scala.Serializable -Object with scala.ScalaObject with scala.Product with scala.Serializable -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.ScalaObject with scala.Product with scala.Serializable] with scala.ScalaObject with scala.Serializable with java.lang.Object -_ <: Object with scala.ScalaObject with scala.Product with scala.Serializable -Object with scala.ScalaObject with scala.Product with scala.Serializable +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable diff --git a/test/files/run/t4172.check b/test/files/run/t4172.check index 95e3eb950d..da467e27ea 100644 --- a/test/files/run/t4172.check +++ b/test/files/run/t4172.check @@ -4,7 +4,7 @@ Type :help for more information. scala> scala> val c = { class C { override def toString = "C" }; ((new C, new C { def f = 2 })) } -c: (C, C{def f: Int}) forSome { type C <: Object with ScalaObject } = (C,C) +c: (C, C{def f: Int}) forSome { type C <: Object } = (C,C) scala> diff --git a/test/files/run/t4891.check b/test/files/run/t4891.check index 072f8df8d4..79fd7f6fbb 100644 --- a/test/files/run/t4891.check +++ b/test/files/run/t4891.check @@ -5,4 +5,3 @@ test.generic.C1 test.generic.C2 (m) public void test.generic.C1.m1() null -interface scala.ScalaObject diff --git a/test/files/run/t5224.check b/test/files/run/t5224.check index 5bead91b36..28bc75d4fd 100644 --- a/test/files/run/t5224.check +++ b/test/files/run/t5224.check @@ -1,5 +1,5 @@ { - @new Foo(bar = "qwe") class C extends Object with ScalaObject { + @new Foo(bar = "qwe") class C extends scala.AnyRef { def <init>() = { super.<init>(); () diff --git a/test/files/run/t5271_1.check b/test/files/run/t5271_1.check index d4fd544e88..9b956da17a 100644 --- a/test/files/run/t5271_1.check +++ b/test/files/run/t5271_1.check @@ -1,5 +1,5 @@ { - case class C extends Object with ScalaObject with Product with Serializable { + case class C extends Object with Product with Serializable { <caseaccessor> <paramaccessor> val foo : Int = _; <caseaccessor> <paramaccessor> val bar : Int = _; def <init>(foo: Int, bar: Int) = { diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check index 5a519f265f..27297febb6 100644 --- a/test/files/run/t5271_2.check +++ b/test/files/run/t5271_2.check @@ -1,5 +1,5 @@ { - case class C extends Object with ScalaObject with Product with Serializable { + case class C extends Object with Product with Serializable { <caseaccessor> <paramaccessor> val foo : Int = _; <caseaccessor> <paramaccessor> val bar : Int = _; def <init>(foo: Int, bar: Int) = { diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check index be87696f02..9331c78959 100644 --- a/test/files/run/t5271_3.check +++ b/test/files/run/t5271_3.check @@ -1,12 +1,12 @@ { - object C extends Object with ScalaObject with Serializable { + object C extends scala.AnyRef with Serializable { def <init>() = { super.<init>(); () }; def qwe: Int = 4 }; - case class C extends Object with ScalaObject with Product with Serializable { + case class C extends Object with Product with Serializable { <caseaccessor> <paramaccessor> val foo : Int = _; <caseaccessor> <paramaccessor> val bar : Int = _; def <init>(foo: Int, bar: Int) = { diff --git a/test/files/run/t5527.check b/test/files/run/t5527.check index 4a8a9ce602..bb13928fd8 100644 --- a/test/files/run/t5527.check +++ b/test/files/run/t5527.check @@ -1,13 +1,13 @@ [[syntax trees at end of parser]]// Scala source: newSource1 package <empty> { - object UselessComments extends scala.ScalaObject { + object UselessComments extends scala.AnyRef { def <init>() = { super.<init>(); () }; var z = 0; def test1 = { - object Maybe extends scala.ScalaObject { + object Maybe extends scala.AnyRef { def <init>() = { super.<init>(); () @@ -42,13 +42,13 @@ package <empty> { } }; /** comments that we should keep */ - object UsefulComments extends scala.ScalaObject { + object UsefulComments extends scala.AnyRef { def <init>() = { super.<init>(); () }; /** class A */ - class A extends scala.ScalaObject { + class A extends scala.AnyRef { def <init>() = { super.<init>(); () @@ -61,7 +61,7 @@ package <empty> { var u = 2 }; /** trait B */ - abstract trait B extends scala.ScalaObject { + abstract trait B extends scala.AnyRef { def $init$() = { () }; @@ -75,7 +75,7 @@ package <empty> { var u = 2 }; /** object C */ - object C extends scala.ScalaObject { + object C extends scala.AnyRef { def <init>() = { super.<init>(); () @@ -88,7 +88,7 @@ package <empty> { var u = 2 }; /** class D */ - @new deprecated("use ... instead", "2.10.0") class D extends scala.ScalaObject { + @new deprecated("use ... instead", "2.10.0") class D extends scala.AnyRef { def <init>() = { super.<init>(); () diff --git a/test/files/run/valueclasses-constr.check b/test/files/run/valueclasses-constr.check new file mode 100644 index 0000000000..df37fbc723 --- /dev/null +++ b/test/files/run/valueclasses-constr.check @@ -0,0 +1,2 @@ +0 +00:16:40 diff --git a/test/files/run/valueclasses-constr.scala b/test/files/run/valueclasses-constr.scala new file mode 100644 index 0000000000..7a10299386 --- /dev/null +++ b/test/files/run/valueclasses-constr.scala @@ -0,0 +1,25 @@ +object TOD { + final val SecondsPerDay = 86400 + + def apply(seconds: Int) = { + val n = seconds % SecondsPerDay + new TOD(if (n >= 0) n else n + SecondsPerDay) + } +} + +final class TOD (val secondsOfDay: Int) extends AnyVal { + def hours = secondsOfDay / 3600 + def minutes = (secondsOfDay / 60) % 60 + def seconds = secondsOfDay % 60 + + override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds) +} + +object Test extends App { + + val y: TOD = new TOD(1000) + val x: TOD = TOD(1000) + println(x.hours) + println(x) +} + diff --git a/test/files/scalap/abstractClass/result.test b/test/files/scalap/abstractClass/result.test index 9b8fc4dd95..9163346fc6 100644 --- a/test/files/scalap/abstractClass/result.test +++ b/test/files/scalap/abstractClass/result.test @@ -1,4 +1,4 @@ -abstract class AbstractClass extends java.lang.Object with scala.ScalaObject { +abstract class AbstractClass extends java.lang.Object { def this() = { /* compiled code */ } def foo : scala.Predef.String } diff --git a/test/files/scalap/abstractMethod/result.test b/test/files/scalap/abstractMethod/result.test index a1bd378c87..90f572f258 100644 --- a/test/files/scalap/abstractMethod/result.test +++ b/test/files/scalap/abstractMethod/result.test @@ -1,4 +1,4 @@ -trait AbstractMethod extends java.lang.Object with scala.ScalaObject { +trait AbstractMethod extends java.lang.Object { def $init$() : scala.Unit = { /* compiled code */ } def arity : scala.Int def isCool : scala.Boolean = { /* compiled code */ } diff --git a/test/files/scalap/caseClass/result.test b/test/files/scalap/caseClass/result.test index a0dbc497fe..7dfe3a0356 100644 --- a/test/files/scalap/caseClass/result.test +++ b/test/files/scalap/caseClass/result.test @@ -1,4 +1,4 @@ -case class CaseClass[A <: scala.Seq[scala.Int]](i : A, s : scala.Predef.String) extends java.lang.Object with scala.ScalaObject with scala.Product with scala.Serializable { +case class CaseClass[A <: scala.Seq[scala.Int]](i : A, s : scala.Predef.String) extends scala.AnyRef with scala.Product with scala.Serializable { val i : A = { /* compiled code */ } val s : scala.Predef.String = { /* compiled code */ } def foo : scala.Int = { /* compiled code */ } diff --git a/test/files/scalap/caseObject/result.test b/test/files/scalap/caseObject/result.test index 55e46eccd7..867a4b2162 100644 --- a/test/files/scalap/caseObject/result.test +++ b/test/files/scalap/caseObject/result.test @@ -1,4 +1,4 @@ -case object CaseObject extends java.lang.Object with scala.ScalaObject with scala.Product with scala.Serializable { +case object CaseObject extends scala.AnyRef with scala.Product with scala.Serializable { def bar : scala.Int = { /* compiled code */ } override def productPrefix : java.lang.String = { /* compiled code */ } def productArity : scala.Int = { /* compiled code */ } diff --git a/test/files/scalap/cbnParam/result.test b/test/files/scalap/cbnParam/result.test index c6b2f4caa8..fbe035d63c 100644 --- a/test/files/scalap/cbnParam/result.test +++ b/test/files/scalap/cbnParam/result.test @@ -1,3 +1,3 @@ -class CbnParam extends java.lang.Object with scala.ScalaObject { +class CbnParam extends java.lang.Object { def this(s : => scala.Predef.String) = { /* compiled code */ } } diff --git a/test/files/scalap/classPrivate/result.test b/test/files/scalap/classPrivate/result.test index 0d12b779c3..5f2e1cc00e 100644 --- a/test/files/scalap/classPrivate/result.test +++ b/test/files/scalap/classPrivate/result.test @@ -1,10 +1,10 @@ -class ClassPrivate extends java.lang.Object with scala.ScalaObject { +class ClassPrivate extends java.lang.Object { def this() = { /* compiled code */ } def baz : scala.Int = { /* compiled code */ } - class Outer extends java.lang.Object with scala.ScalaObject { + class Outer extends java.lang.Object { def this() = { /* compiled code */ } private[ClassPrivate] def qux : scala.Int = { /* compiled code */ } } protected def quux : scala.Int = { /* compiled code */ } private[ClassPrivate] def bar : scala.Int = { /* compiled code */ } -}
\ No newline at end of file +} diff --git a/test/files/scalap/classWithExistential/result.test b/test/files/scalap/classWithExistential/result.test index 91afddaf0e..b8ce005da9 100644 --- a/test/files/scalap/classWithExistential/result.test +++ b/test/files/scalap/classWithExistential/result.test @@ -1,4 +1,4 @@ -class ClassWithExistential extends java.lang.Object with scala.ScalaObject { +class ClassWithExistential extends java.lang.Object { def this() = { /* compiled code */ } def foo[A, B] : scala.Function1[A, B forSome {type A <: scala.Seq[scala.Int]; type B >: scala.Predef.String}] = { /* compiled code */ } -}
\ No newline at end of file +} diff --git a/test/files/scalap/classWithSelfAnnotation/result.test b/test/files/scalap/classWithSelfAnnotation/result.test index 326437c7be..df7bd86643 100644 --- a/test/files/scalap/classWithSelfAnnotation/result.test +++ b/test/files/scalap/classWithSelfAnnotation/result.test @@ -1,4 +1,4 @@ -class ClassWithSelfAnnotation extends java.lang.Object with scala.ScalaObject { +class ClassWithSelfAnnotation extends java.lang.Object { this : ClassWithSelfAnnotation with java.lang.CharSequence => def this() = { /* compiled code */ } def foo : scala.Int = { /* compiled code */ } diff --git a/test/files/scalap/covariantParam/result.test b/test/files/scalap/covariantParam/result.test index 8acd9b497a..2f52f1f28e 100644 --- a/test/files/scalap/covariantParam/result.test +++ b/test/files/scalap/covariantParam/result.test @@ -1,4 +1,4 @@ -class CovariantParam[+A] extends java.lang.Object with scala.ScalaObject { +class CovariantParam[+A] extends java.lang.Object { def this() = { /* compiled code */ } def foo[A](a : A) : scala.Int = { /* compiled code */ } } diff --git a/test/files/scalap/implicitParam/result.test b/test/files/scalap/implicitParam/result.test index 11d678df06..0ea212dda6 100644 --- a/test/files/scalap/implicitParam/result.test +++ b/test/files/scalap/implicitParam/result.test @@ -1,4 +1,4 @@ -class ImplicitParam extends java.lang.Object with scala.ScalaObject { +class ImplicitParam extends java.lang.Object { def this() = { /* compiled code */ } def foo(i : scala.Int)(implicit f : scala.Float, d : scala.Double) : scala.Int = { /* compiled code */ } } diff --git a/test/files/scalap/packageObject/result.test b/test/files/scalap/packageObject/result.test index 6a8d6ae1d5..94c6a01b08 100644 --- a/test/files/scalap/packageObject/result.test +++ b/test/files/scalap/packageObject/result.test @@ -1,4 +1,4 @@ -package object PackageObject extends java.lang.Object with scala.ScalaObject { +package object PackageObject extends java.lang.Object { def this() = { /* compiled code */ } type A = scala.Predef.String def foo(i : scala.Int) : scala.Int = { /* compiled code */ } diff --git a/test/files/scalap/paramClauses/result.test b/test/files/scalap/paramClauses/result.test index 9ef93d2e76..dc4397386c 100644 --- a/test/files/scalap/paramClauses/result.test +++ b/test/files/scalap/paramClauses/result.test @@ -1,4 +1,4 @@ -class ParamClauses extends java.lang.Object with scala.ScalaObject { +class ParamClauses extends java.lang.Object { def this() = { /* compiled code */ } def foo(i : scala.Int)(s : scala.Predef.String)(t : scala.Double) : scala.Int = { /* compiled code */ } } diff --git a/test/files/scalap/paramNames/result.test b/test/files/scalap/paramNames/result.test index f9d98d9647..4d3c7d0c1e 100644 --- a/test/files/scalap/paramNames/result.test +++ b/test/files/scalap/paramNames/result.test @@ -1,4 +1,4 @@ -class ParamNames extends java.lang.Object with scala.ScalaObject { +class ParamNames extends java.lang.Object { def this() = { /* compiled code */ } def foo(s : => scala.Seq[scala.Int], s2 : => scala.Seq[scala.Any]) : scala.Unit = { /* compiled code */ } } diff --git a/test/files/scalap/sequenceParam/result.test b/test/files/scalap/sequenceParam/result.test index 4b9d7844ab..ed47c094fe 100644 --- a/test/files/scalap/sequenceParam/result.test +++ b/test/files/scalap/sequenceParam/result.test @@ -1,3 +1,3 @@ -class SequenceParam extends java.lang.Object with scala.ScalaObject { +class SequenceParam extends java.lang.Object { def this(s : scala.Predef.String, i : scala.Int*) = { /* compiled code */ } } diff --git a/test/files/scalap/simpleClass/result.test b/test/files/scalap/simpleClass/result.test index d10b633bce..905046ce52 100644 --- a/test/files/scalap/simpleClass/result.test +++ b/test/files/scalap/simpleClass/result.test @@ -1,4 +1,4 @@ -class SimpleClass extends java.lang.Object with scala.ScalaObject { +class SimpleClass extends java.lang.Object { def this() = { /* compiled code */ } def foo : scala.Int = { /* compiled code */ } } diff --git a/test/files/scalap/traitObject/result.test b/test/files/scalap/traitObject/result.test index 0d7de1535d..d0521043c8 100644 --- a/test/files/scalap/traitObject/result.test +++ b/test/files/scalap/traitObject/result.test @@ -1,8 +1,8 @@ -trait TraitObject extends java.lang.Object with scala.ScalaObject { +trait TraitObject extends java.lang.Object { def $init$() : scala.Unit = { /* compiled code */ } def foo : scala.Int = { /* compiled code */ } } -object TraitObject extends java.lang.Object with scala.ScalaObject { +object TraitObject extends java.lang.Object { def this() = { /* compiled code */ } def bar : scala.Int = { /* compiled code */ } } diff --git a/test/files/scalap/typeAnnotations/result.test b/test/files/scalap/typeAnnotations/result.test index b565d6185b..d28712f12b 100644 --- a/test/files/scalap/typeAnnotations/result.test +++ b/test/files/scalap/typeAnnotations/result.test @@ -1,8 +1,8 @@ -abstract class TypeAnnotations[@scala.specialized R] extends java.lang.Object with scala.ScalaObject { +abstract class TypeAnnotations[@scala.specialized R] extends java.lang.Object { def this() = { /* compiled code */ } @scala.specialized val x : scala.Int = { /* compiled code */ } @scala.specialized type T def compose[@scala.specialized A](x : A, y : R) : A = { /* compiled code */ } -}
\ No newline at end of file +} diff --git a/test/files/scalap/valAndVar/result.test b/test/files/scalap/valAndVar/result.test index 934ad0a086..90081acade 100644 --- a/test/files/scalap/valAndVar/result.test +++ b/test/files/scalap/valAndVar/result.test @@ -1,4 +1,4 @@ -class ValAndVar extends java.lang.Object with scala.ScalaObject { +class ValAndVar extends java.lang.Object { def this() = { /* compiled code */ } val foo : java.lang.String = { /* compiled code */ } var bar : scala.Int = { /* compiled code */ } diff --git a/test/files/scalap/wildcardType/result.test b/test/files/scalap/wildcardType/result.test index aa3d5d53bc..28147b6605 100644 --- a/test/files/scalap/wildcardType/result.test +++ b/test/files/scalap/wildcardType/result.test @@ -1,3 +1,3 @@ -class WildcardType extends java.lang.Object with scala.ScalaObject { +class WildcardType extends java.lang.Object { def this(f : scala.Function1[scala.Int, _]) = { /* compiled code */ } } diff --git a/test/files/specialized/SI-5005.check b/test/files/specialized/SI-5005.check index d2a97512ae..9fc63a2b1d 100644 --- a/test/files/specialized/SI-5005.check +++ b/test/files/specialized/SI-5005.check @@ -1,6 +1,6 @@ [[syntax trees at end of specialize]]// Scala source: newSource1 package <empty> { - class C2[@specialized(scala.Boolean) U >: Nothing <: Any] extends Object with ScalaObject { + class C2[@specialized(scala.Boolean) U >: Nothing <: Any] extends Object { def <init>(): C2[U] = { C2.super.<init>(); () @@ -8,7 +8,7 @@ package <empty> { def apply(x: U): U = x; <specialized> def apply$mcZ$sp(x: Boolean): Boolean = C2.this.apply(x.asInstanceOf[U]()).asInstanceOf[Boolean]() }; - class B extends Object with ScalaObject { + class B extends Object { def <init>(): B = { B.super.<init>(); () diff --git a/test/files/speclib/instrumented.jar.desired.sha1 b/test/files/speclib/instrumented.jar.desired.sha1 index 27c1e8fc24..2d4cd04a92 100644 --- a/test/files/speclib/instrumented.jar.desired.sha1 +++ b/test/files/speclib/instrumented.jar.desired.sha1 @@ -1 +1 @@ -23b6a7aa89b0a8a210ae9b206dfd0998338798c7 ?instrumented.jar +d83c6bf3765ab1378943020a8d9cda8851604ffa ?instrumented.jar diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scala/html/HtmlFactoryTest.scala index 37aa302ac7..d46a9581b9 100644 --- a/test/scaladoc/scala/html/HtmlFactoryTest.scala +++ b/test/scaladoc/scala/html/HtmlFactoryTest.scala @@ -296,27 +296,27 @@ object Test extends Properties("HtmlFactory") { case _ => false } } - - property("Trac #484 - refinements and existentials") = { - val files = createTemplates("Trac484.scala") - val lines = """ - |type Bar = AnyRef { type Dingus <: T forSome { type T <: String } } - |type Foo = AnyRef { ... /* 3 definitions in type refinement */ } - |def g(x: T forSome { type T <: String }): String - |def h(x: Float): AnyRef { def quux(x: Int,y: Int): Int } - |def hh(x: Float): AnyRef { def quux(x: Int,y: Int): Int } - |def j(x: Int): Bar - |def k(): AnyRef { type Dingus <: T forSome { type T <: String } } - """.stripMargin.trim.lines map (_.trim) - - files("RefinementAndExistentials.html") match { - case node: scala.xml.Node => { - val s = node.text.replaceAll("\\s+", " ") - lines forall (s contains _) - } - case _ => false - } - } + // + // property("Trac #484 - refinements and existentials") = { + // val files = createTemplates("Trac484.scala") + // val lines = """ + // |type Bar = AnyRef { type Dingus <: T forSome { type T <: String } } + // |type Foo = AnyRef { ... /* 3 definitions in type refinement */ } + // |def g(x: T forSome { type T <: String }): String + // |def h(x: Float): AnyRef { def quux(x: Int,y: Int): Int } + // |def hh(x: Float): AnyRef { def quux(x: Int,y: Int): Int } + // |def j(x: Int): Bar + // |def k(): AnyRef { type Dingus <: T forSome { type T <: String } } + // """.stripMargin.trim.lines map (_.trim) + // + // files("RefinementAndExistentials.html") match { + // case node: scala.xml.Node => { + // val s = node.text.replaceAll("\\s+", " ") + // lines forall (s contains _) + // } + // case _ => false + // } + // } property("Trac #4289") = { val files = createTemplates("Trac4289.scala") |