From e61eff23df977eeed19bfe253b01b69cce47dfa3 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 27 Jan 2012 16:30:01 -0800 Subject: Unsealed AnyVal. Hacks here and there to allow them to survive at least to erasure. Since nothing is done with them there yet, they inevitably crash and burn a little ways beyond that. --- test/files/pos/anyval-children.scala | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/files/pos/anyval-children.scala (limited to 'test/files/pos') diff --git a/test/files/pos/anyval-children.scala b/test/files/pos/anyval-children.scala new file mode 100644 index 0000000000..7a2eda8b3f --- /dev/null +++ b/test/files/pos/anyval-children.scala @@ -0,0 +1 @@ +class Bippy extends AnyVal \ No newline at end of file -- cgit v1.2.3 From 6eb066dade3f6541fb33a0b325c67ca98aa413ad Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 30 Jan 2012 15:42:20 +0100 Subject: Resinstantiating anyval-children test. Getting he complete build to run. --- .../scala/reflect/internal/Definitions.scala | 14 +- src/compiler/scala/tools/nsc/Global.scala | 6 +- .../scala/tools/nsc/transform/ClassInliner.scala | 161 --------------------- .../scala/tools/nsc/transform/Erasure.scala | 4 +- .../tools/nsc/transform/ExtensionMethods.scala | 161 +++++++++++++++++++++ src/library/scala/AnyVal.scala | 3 +- test/disabled/pos/anyval-children.scala | 1 - test/files/pos/anyval-children.flags | 1 + test/files/pos/anyval-children.scala | 1 + 9 files changed, 182 insertions(+), 170 deletions(-) delete mode 100644 src/compiler/scala/tools/nsc/transform/ClassInliner.scala create mode 100644 src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala delete mode 100644 test/disabled/pos/anyval-children.scala create mode 100644 test/files/pos/anyval-children.flags create mode 100644 test/files/pos/anyval-children.scala (limited to 'test/files/pos') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index e8fc1c9cc9..715a68cf55 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -659,6 +659,15 @@ trait Definitions extends reflect.api.StandardDefinitions { AnyClass, nme.isInstanceOf_, tparam => NullaryMethodType(booltype)) setFlag FINAL lazy val Any_asInstanceOf = newPolyMethod( AnyClass, nme.asInstanceOf_, tparam => NullaryMethodType(tparam.typeConstructor)) setFlag FINAL + + // AnyVal_getClass is defined here. Once we have a new strap, it could also be + // defined directly in the AnyVal trait. Right now this does not work, because + // strap complains about overriding a final getClass method in Any. + lazy val AnyVal_getClass = { + val m = AnyValClass.newMethod(nme.getClass_) + val tparam = m.newExistential(newTypeName("T")) setInfo TypeBounds(NothingClass.tpe, AnyValClass.tpe) + m setInfoAndEnter MethodType(List(), ExistentialType(List(tparam), appliedType(ClassClass.typeConstructor, List(tparam.tpe)))) + } // members of class java.lang.{ Object, String } lazy val Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL) @@ -859,7 +868,7 @@ trait Definitions extends reflect.api.StandardDefinitions { val msym = owner.info.decls enter owner.newMethod(name.encode) val tparam = newTypeParam(msym, 0) - msym setInfo GenPolyType(List(tparam), tcon(tparam)(msym)) + msym setInfo PolyType(List(tparam), tcon(tparam)(msym)) } private def newTypeParam(owner: Symbol, index: Int): Symbol = @@ -991,7 +1000,8 @@ trait Definitions extends reflect.api.StandardDefinitions { Object_synchronized, Object_isInstanceOf, Object_asInstanceOf, - String_+ + String_+, + AnyVal_getClass ) /** Removing the anyref parent they acquire from having a source file. diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 1092c7bce1..8026e92a21 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -436,11 +436,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb val global: Global.this.type = Global.this } with Analyzer - object classInlining extends { + object extensionMethods extends { val global: Global.this.type = Global.this val runsAfter = List("typer") val runsRightAfter = None - } with ClassInlining + } with ExtensionMethods // phaseName = "superaccessors" object superAccessors extends { @@ -656,7 +656,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", - classInlining -> "add static methods to inline classes", + extensionMethods -> "add extension methods for inline classes", pickler -> "serialize symbol tables", refChecks -> "reference/override checking, translate nested objects", liftcode -> "reify trees", diff --git a/src/compiler/scala/tools/nsc/transform/ClassInliner.scala b/src/compiler/scala/tools/nsc/transform/ClassInliner.scala deleted file mode 100644 index c1104b025c..0000000000 --- a/src/compiler/scala/tools/nsc/transform/ClassInliner.scala +++ /dev/null @@ -1,161 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Gilles Dubochet - * @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 } -import sun.tools.tree.OrExpression - -/** - * Perform Step 1 in the inline classes SIP - * - * @author Martin Odersky - * @version 2.10 - */ -abstract class ClassInlining 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 = "inlineclasses" - - def newTransformer(unit: CompilationUnit): Transformer = - new ClassInliner(unit) - - def hasUnboxedVersion(sym: Symbol) = - !sym.isParamAccessor && !sym.isConstructor - - /** Generate stream of possible names for the unboxed version of given instance method `imeth`. - * If the method is not overloaded, this stream consists of just "unboxed$imeth". - * If the method is overloaded, the stream has as first element "unboxedX$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 unboxed 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 `unboxedMethod` 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 unboxedNames(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("unboxed"+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("unboxed$"+imeth.name)) - } - - /** Return the unboxed method that corresponds to given instance method `meth`. - */ - def unboxedMethod(imeth: Symbol): Symbol = atPhase(currentRun.refchecksPhase) { - val companionInfo = imeth.owner.companionModule.info - val candidates = unboxedNames(imeth) map (companionInfo.decl(_)) - val matching = candidates filter (alt => normalize(alt.tpe, imeth.owner) matches imeth.tpe) - assert(matching.nonEmpty, "no unboxed method found for "+imeth+" among "+candidates+"/"+unboxedNames(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 ClassInliner(unit: CompilationUnit) extends TypingTransformer(unit) { - - private val unboxedDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]() - - def unboxedMethInfo(unboxedMeth: Symbol, origInfo: Type, clazz: Symbol): Type = { - var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, unboxedMeth) - val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpe)) - val thisParam = unboxedMeth.newValueParameter(nme.SELF, unboxedMeth.pos) setInfo thisParamType - def transform(clonedType: Type): Type = clonedType match { - case MethodType(params, restpe) => - MethodType(List(thisParam), clonedType) - case NullaryMethodType(restpe) => - MethodType(List(thisParam), restpe) - } - val GenPolyType(tparams, restpe) = origInfo cloneInfo unboxedMeth - GenPolyType(tparams ::: newTypeParams, transform(restpe)) - } - - 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.isInlineClass) { - unboxedDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree] - super.transform(tree) - } - else tree - case DefDef(mods, name, tparams, vparamss, tpt, rhs) - if currentOwner.isInlineClass && hasUnboxedVersion(tree.symbol) => - val companion = currentOwner.companionModule - val origMeth = tree.symbol - val unboxedName = unboxedNames(origMeth).head - val unboxedMeth = companion.moduleClass.newMethod(unboxedName, origMeth.pos, origMeth.flags & ~OVERRIDE | FINAL) - .setAnnotations(origMeth.annotations) - companion.info.decls.enter(unboxedMeth) - unboxedMeth.setInfo(unboxedMethInfo(unboxedMeth, origMeth.info, currentOwner)) - def thisParamRef = gen.mkAttributedIdent(unboxedMeth.info.params.head setPos unboxedMeth.pos) - val GenPolyType(unboxedTpeParams, unboxedMono) = unboxedMeth.info - val origTpeParams = origMeth.typeParams ::: currentOwner.typeParams - val unboxedBody = rhs - .substTreeSyms(origTpeParams, unboxedTpeParams) - .substTreeSyms(vparamss.flatten map (_.symbol), allParams(unboxedMono).tail) - .substTreeThis(currentOwner, thisParamRef) - .changeOwner((origMeth, unboxedMeth)) - unboxedDefs(companion) += atPos(tree.pos) { DefDef(unboxedMeth, unboxedBody) } - val unboxedCallPrefix = Apply( - gen.mkTypeApply(gen.mkAttributedRef(companion), unboxedMeth, origTpeParams map (_.tpe)), - List(This(currentOwner))) - val unboxedCall = atOwner(origMeth) { - localTyper.typed { - atPos(rhs.pos) { - (unboxedCallPrefix /: vparamss) { - case (fn, params) => Apply(fn, params map (param => Ident(param.symbol))) - } - } - } - } - treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, unboxedCall) - 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)) => - unboxedDefs.remove(stat.symbol) match { - case Some(buf) => - val unboxedDefs = buf.toList map { mdef => atOwner(stat.symbol) { localTyper.typed(mdef) }} - treeCopy.ModuleDef(stat, mods, name, treeCopy.Template(tmpl, parents, self, body ++ buf)) - case None => - stat - } - case stat => - stat - } - } -} diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 51941408a2..5b1555bfb7 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -986,8 +986,8 @@ abstract class Erasure extends AddInterfaces } } else if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) { ApplyDynamic(qualifier, args) setSymbol fn.symbol setPos tree.pos - } else if (fn.symbol.owner.isInlineClass && classInlining.hasUnboxedVersion(fn.symbol)) { - Apply(gen.mkAttributedRef(classInlining.unboxedMethod(fn.symbol)), qualifier :: args) + } else if (fn.symbol.owner.isInlineClass && extensionMethods.hasExtension(fn.symbol)) { + Apply(gen.mkAttributedRef(extensionMethods.extensionMethod(fn.symbol)), qualifier :: args) } else { tree } 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..5f62dfab39 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -0,0 +1,161 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Gilles Dubochet + * @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 } +import sun.tools.tree.OrExpression + +/** + * Perform Step 1 in the inline classes SIP + * + * @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) + + def hasExtension(sym: Symbol) = + !sym.isParamAccessor && !sym.isConstructor + + /** 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) => + MethodType(List(thisParam), clonedType) + case NullaryMethodType(restpe) => + MethodType(List(thisParam), restpe) + } + val GenPolyType(tparams, restpe) = origInfo cloneInfo extensionMeth + GenPolyType(tparams ::: newTypeParams, transform(restpe)) + } + + 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.isInlineClass) { + extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree] + super.transform(tree) + } + else tree + case DefDef(mods, name, tparams, vparamss, tpt, rhs) + if currentOwner.isInlineClass && hasExtension(tree.symbol) => + val companion = currentOwner.companionModule + val origMeth = tree.symbol + val extensionName = extensionNames(origMeth).head + val extensionMeth = companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE | FINAL) + .setAnnotations(origMeth.annotations) + companion.info.decls.enter(extensionMeth) + extensionMeth.setInfo(extensionMethInfo(extensionMeth, origMeth.info, currentOwner)) + def thisParamRef = gen.mkAttributedIdent(extensionMeth.info.params.head setPos extensionMeth.pos) + val GenPolyType(extensionTpeParams, extensionMono) = extensionMeth.info + val origTpeParams = origMeth.typeParams ::: 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 ++ buf)) + case None => + stat + } + case stat => + stat + } + } +} diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala index ed4c5f5948..fb36d61c57 100644 --- a/src/library/scala/AnyVal.scala +++ b/src/library/scala/AnyVal.scala @@ -26,6 +26,7 @@ package scala * The ''floating point types'' are [[scala.Float]] and [[scala.Double]]. */ trait AnyVal { -// disabled for now to make the standard build go through +// 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/test/disabled/pos/anyval-children.scala b/test/disabled/pos/anyval-children.scala deleted file mode 100644 index 7a2eda8b3f..0000000000 --- a/test/disabled/pos/anyval-children.scala +++ /dev/null @@ -1 +0,0 @@ -class Bippy extends AnyVal \ No newline at end of file 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/anyval-children.scala b/test/files/pos/anyval-children.scala new file mode 100644 index 0000000000..7a2eda8b3f --- /dev/null +++ b/test/files/pos/anyval-children.scala @@ -0,0 +1 @@ +class Bippy extends AnyVal \ No newline at end of file -- cgit v1.2.3 From a9eb9c5b69071a944d2a5225aa320babdf33ad42 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 30 Jan 2012 12:42:26 -0800 Subject: More work on inline classes. Fail compile if AnyVal is inherited by a trait, a non-@inline class, or a class with an AnyRef parent somewhere. Added tests. Added logging, like [log extmethods] Inline class class Bippy spawns extension method. Old: def getClass: Class[_ <: Bippy] New: final def extension$getClass($this: Bippy): Class[_ <: Bippy] Fixed what I hope was a bug in ExtensionMethods where the original method params were dropped. Since adding a NonNull parent was also inflicting an AnyRef on AnyVal subclasses, suppressed that for those. Had the bright idea that AnyVal could extend NotNull. It doesn't seem to accomplish much, but then, I don't think NotNull accomplishes much. Still, maybe it's time to restrict the ways one can use AnyVal so one can't do this: scala> var x: AnyVal = _ x: AnyVal = null --- .../scala/reflect/internal/Definitions.scala | 8 ++++++- .../scala/tools/nsc/ast/parser/Parsers.scala | 2 +- .../tools/nsc/transform/ExtensionMethods.scala | 13 ++++++++--- .../scala/tools/nsc/typechecker/Namers.scala | 6 +++-- .../scala/tools/nsc/typechecker/RefChecks.scala | 23 +++++++++++++++---- src/library/scala/AnyVal.scala | 2 +- src/library/scala/NotNull.scala | 2 -- test/files/neg/anyval-children-2.check | 4 ++++ test/files/neg/anyval-children-2.scala | 1 + test/files/neg/anyval-children.check | 26 ++++++++++++++++++++++ test/files/neg/anyval-children.scala | 14 ++++++++++++ test/files/pos/anyval-children.scala | 2 +- 12 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 test/files/neg/anyval-children-2.check create mode 100644 test/files/neg/anyval-children-2.scala create mode 100644 test/files/neg/anyval-children.check create mode 100644 test/files/neg/anyval-children.scala (limited to 'test/files/pos') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index f8342444c8..ce0505bf44 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -910,6 +910,12 @@ trait Definitions extends reflect.api.StandardDefinitions { private lazy val scalaValueClassesSet = ScalaValueClasses.toSet private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass + /** Now that AnyVal is unsealing we need less ambiguous names + * for when we need to distinguish the Nine Original AnyVals + * from the heathen masses. + */ + def isPrimitiveValueClass(sym: Symbol) = scalaValueClassesSet(sym) + /** Is symbol a value class? */ def isValueClass(sym: Symbol) = scalaValueClassesSet(sym) def isNonUnitValueClass(sym: Symbol) = (sym != UnitClass) && isValueClass(sym) @@ -1029,7 +1035,7 @@ trait Definitions extends reflect.api.StandardDefinitions { /** Removing the anyref parent they acquire from having a source file. */ - setParents(AnyValClass, anyparam) + setParents(AnyValClass, List(NotNullClass.tpe, AnyClass.tpe)) ScalaValueClasses foreach { sym => setParents(sym, anyvalparam) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index eb7c5a6699..3ee8b62bc6 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2757,7 +2757,7 @@ self => Template(List(scalaDot(tpnme.AnyVal)), self, body) } else if (parents0 exists isReferenceToAnyVal) { - // TODO - enforce @inline annotation, and no other parents + // @inline and other restrictions enforced in refchecks Template(parents0, self, body) } else if (name == tpnme.AnyVal) { diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 5f62dfab39..c308a3633e 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -84,10 +84,11 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { 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 + val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType def transform(clonedType: Type): Type = clonedType match { case MethodType(params, restpe) => - MethodType(List(thisParam), clonedType) + // I assume it was a bug that this was dropping params... + MethodType(thisParam :: params, clonedType) case NullaryMethodType(restpe) => MethodType(List(thisParam), restpe) } @@ -116,7 +117,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val extensionMeth = companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE | FINAL) .setAnnotations(origMeth.annotations) companion.info.decls.enter(extensionMeth) - extensionMeth.setInfo(extensionMethInfo(extensionMeth, origMeth.info, currentOwner)) + val newInfo = extensionMethInfo(extensionMeth, origMeth.info, currentOwner) + extensionMeth setInfo newInfo + log("Inline 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 = origMeth.typeParams ::: currentOwner.typeParams diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index b9f3adec75..2f31347829 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1407,7 +1407,9 @@ trait Namers extends MethodSynthesis { } if (sym.isClass && sym.hasAnnotation(ScalaInlineClass) && !phase.erasedTypes) { - ensureParent(NotNullClass) + if (!sym.isSubClass(AnyValClass)) + ensureParent(NotNullClass) + sym setFlag FINAL } @@ -1437,7 +1439,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/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4449116fd1..f7a6815905 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -683,16 +683,16 @@ 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 - if (!(clazz isSubClass AnyValClass)) { + } + 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) unit.error(decl.pos, "trait cannot redefine final method from class AnyRef") } } - } /** Returns whether there is a symbol declared in class `inclazz` * (which must be different from `clazz`) whose name and type @@ -1527,6 +1527,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.hasAnnotation(ScalaInlineClass)) + unit.error(clazz.pos, "Only @inline classes are allowed to extend AnyVal") + if (clazz.isTrait) + unit.error(clazz.pos, "Only @inline classes (not traits) are allowed to extend AnyVal") + 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 @@ -1562,6 +1575,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R checkOverloadedRestrictions(currentOwner) val bridges = addVarargBridges(currentOwner) checkAllOverrides(currentOwner) + checkAnyValSubclass(currentOwner) + if (bridges.nonEmpty) treeCopy.Template(tree, parents, self, body ::: bridges) else tree diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala index fb36d61c57..ed32fb7302 100644 --- a/src/library/scala/AnyVal.scala +++ b/src/library/scala/AnyVal.scala @@ -25,7 +25,7 @@ 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]]. */ -trait AnyVal { +trait AnyVal extends 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/NotNull.scala b/src/library/scala/NotNull.scala index d47d47a83e..f90b95c789 100644 --- a/src/library/scala/NotNull.scala +++ b/src/library/scala/NotNull.scala @@ -6,8 +6,6 @@ ** |/ ** \* */ - - package scala /** diff --git a/test/files/neg/anyval-children-2.check b/test/files/neg/anyval-children-2.check new file mode 100644 index 0000000000..cb327faeeb --- /dev/null +++ b/test/files/neg/anyval-children-2.check @@ -0,0 +1,4 @@ +anyval-children-2.scala:1: error: Only @inline classes (not traits) are allowed to extend AnyVal +@inline trait NotOkDingus1 extends AnyVal // fail + ^ +one error found diff --git a/test/files/neg/anyval-children-2.scala b/test/files/neg/anyval-children-2.scala new file mode 100644 index 0000000000..4034eb22dd --- /dev/null +++ b/test/files/neg/anyval-children-2.scala @@ -0,0 +1 @@ +@inline trait NotOkDingus1 extends AnyVal // fail diff --git a/test/files/neg/anyval-children.check b/test/files/neg/anyval-children.check new file mode 100644 index 0000000000..cbb5a2b1d1 --- /dev/null +++ b/test/files/neg/anyval-children.check @@ -0,0 +1,26 @@ +anyval-children.scala:7: error: illegal inheritance; superclass Bippy + is not a subclass of the superclass Object + of the mixin trait ScalaObject +class NotOkBippy1 extends Bippy // fail + ^ +anyval-children.scala:9: error: illegal inheritance; superclass Bippy + is not a subclass of the superclass Object + of the mixin trait Immutable +class NotOkBippy2 extends Bippy with Immutable //fail + ^ +anyval-children.scala:9: error: illegal inheritance; superclass Bippy + is not a subclass of the superclass Object + of the mixin trait ScalaObject +class NotOkBippy2 extends Bippy with Immutable //fail + ^ +anyval-children.scala:11: error: illegal inheritance; superclass Bippy + is not a subclass of the superclass Object + of the mixin trait Immutable +@inline class NotOkBippy3 extends Bippy with Immutable //fail + ^ +anyval-children.scala:11: error: illegal inheritance; superclass Bippy + is not a subclass of the superclass Object + of the mixin trait ScalaObject +@inline class NotOkBippy3 extends Bippy with Immutable //fail + ^ +5 errors found diff --git a/test/files/neg/anyval-children.scala b/test/files/neg/anyval-children.scala new file mode 100644 index 0000000000..5a6109f786 --- /dev/null +++ b/test/files/neg/anyval-children.scala @@ -0,0 +1,14 @@ +class Bippy extends AnyVal // fail + +@inline class NotOkDingus2 extends Immutable with AnyVal // fail + +@inline object NotOkDingus3 extends AnyVal // fail + +class NotOkBippy1 extends Bippy // fail + +class NotOkBippy2 extends Bippy with Immutable //fail + +@inline class NotOkBippy3 extends Bippy with Immutable //fail + + +@inline class OkBippy extends AnyVal // ok diff --git a/test/files/pos/anyval-children.scala b/test/files/pos/anyval-children.scala index 7a2eda8b3f..4ef10a094f 100644 --- a/test/files/pos/anyval-children.scala +++ b/test/files/pos/anyval-children.scala @@ -1 +1 @@ -class Bippy extends AnyVal \ No newline at end of file +@inline class Bippy extends AnyVal \ No newline at end of file -- cgit v1.2.3 From 2b7fb460dd1e666ed37ccba49a82aab959413c22 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 4 Feb 2012 11:22:49 -0800 Subject: Updated checkfiles to subtract ScalaObject. --- test/files/buildmanager/t2556_3/t2556_3.check | 4 ++-- test/files/jvm/manifests.check | 2 +- test/files/neg/anyval-children.check | 12 +++--------- test/files/neg/t0764.check | 2 +- test/files/neg/t2641.check | 6 +----- test/files/neg/t3691.check | 4 ++-- test/files/neg/t464-neg.check | 4 ++-- test/files/neg/t4877.check | 2 +- test/files/neg/t5060.check | 4 ++-- test/files/neg/t664.check | 4 ++-- test/files/neg/variances.check | 2 +- test/files/pos/t1050.scala | 2 +- test/files/presentation/callcc-interpreter.check | 4 ++-- test/files/run/primitive-sigs-2.check | 2 +- test/files/run/repl-parens.check | 2 +- test/files/run/t4110.check | 4 ++-- test/files/run/t4172.check | 2 +- test/files/run/t4891.check | 1 - 18 files changed, 26 insertions(+), 37 deletions(-) (limited to 'test/files/pos') 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/jvm/manifests.check b/test/files/jvm/manifests.check index 54f504b929..453db81a3b 100644 --- a/test/files/jvm/manifests.check +++ b/test/files/jvm/manifests.check @@ -29,7 +29,7 @@ x=Foo, m=Foo[scala.collection.immutable.List[Int]] x=Foo, m=Foo[Foo[Int]] x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] -x=Test1$$anon$1, m=Object with Bar[java.lang.String] +x=Test1$$anon$1, m=Object with Bar[java.lang.String] with Object ()=() true=true diff --git a/test/files/neg/anyval-children.check b/test/files/neg/anyval-children.check index cbb5a2b1d1..f1149a5ce3 100644 --- a/test/files/neg/anyval-children.check +++ b/test/files/neg/anyval-children.check @@ -1,6 +1,4 @@ -anyval-children.scala:7: error: illegal inheritance; superclass Bippy - is not a subclass of the superclass Object - of the mixin trait ScalaObject +anyval-children.scala:7: error: Bippy does not have a constructor class NotOkBippy1 extends Bippy // fail ^ anyval-children.scala:9: error: illegal inheritance; superclass Bippy @@ -8,9 +6,7 @@ anyval-children.scala:9: error: illegal inheritance; superclass Bippy of the mixin trait Immutable class NotOkBippy2 extends Bippy with Immutable //fail ^ -anyval-children.scala:9: error: illegal inheritance; superclass Bippy - is not a subclass of the superclass Object - of the mixin trait ScalaObject +anyval-children.scala:9: error: Bippy does not have a constructor class NotOkBippy2 extends Bippy with Immutable //fail ^ anyval-children.scala:11: error: illegal inheritance; superclass Bippy @@ -18,9 +14,7 @@ anyval-children.scala:11: error: illegal inheritance; superclass Bippy of the mixin trait Immutable @inline class NotOkBippy3 extends Bippy with Immutable //fail ^ -anyval-children.scala:11: error: illegal inheritance; superclass Bippy - is not a subclass of the superclass Object - of the mixin trait ScalaObject +anyval-children.scala:11: error: Bippy does not have a constructor @inline class NotOkBippy3 extends Bippy with Immutable //fail ^ 5 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/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/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/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/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check index 3385ef12b7..41b07b07dc 100644 --- a/test/files/presentation/callcc-interpreter.check +++ b/test/files/presentation/callcc-interpreter.check @@ -20,7 +20,7 @@ retrieved 64 members `method ->[B](y: B)(callccInterpreter.type, B)` `method ==(x$1: Any)Boolean` `method ==(x$1: AnyRef)Boolean` -`method add(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Product with Serializable with callccInterpreter.Value]` +`method add(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Serializable with Product with callccInterpreter.Value]` `method apply(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[callccInterpreter.Value]` `method asInstanceOf[T0]=> T0` `method callCC[A](h: (A => callccInterpreter.M[A]) => callccInterpreter.M[A])callccInterpreter.M[A]` @@ -87,7 +87,7 @@ def showM(m: callccInterpreter.M[callccInterpreter.Value]): String = m.in.apply( askType at CallccInterpreter.scala(50,30) ================================================================================ [response] askTypeAt at (50,30) -def add(a: callccInterpreter.Value, b: callccInterpreter.Value): callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Product with Serializable with callccInterpreter.Value] = scala.this.Predef.Pair.apply[callccInterpreter.Value, callccInterpreter.Value](a, b) match { +def add(a: callccInterpreter.Value, b: callccInterpreter.Value): callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Serializable with Product with callccInterpreter.Value] = scala.this.Predef.Pair.apply[callccInterpreter.Value, callccInterpreter.Value](a, b) match { case scala.this.Predef.Pair.unapply[callccInterpreter.Value, callccInterpreter.Value]() ((n: Int)callccInterpreter.Num((m @ _)), (n: Int)callccInterpreter.Num((n @ _))) => this.unitM[callccInterpreter.Num](callccInterpreter.this.Num.apply(m.+(n))) case _ => callccInterpreter.this.unitM[callccInterpreter.Wrong.type](callccInterpreter.this.Wrong) } diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index c69d1b54a6..0af1434cea 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,4 +1,4 @@ -T interface scala.ScalaObject +T class java.lang.Object List(A, char, class java.lang.Object) a public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) 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 = scala> () => { class X ; new X } -res14: () => Object with ScalaObject = +res14: () => Object = scala> diff --git a/test/files/run/t4110.check b/test/files/run/t4110.check index 8b005989de..dea7e5957c 100644 --- a/test/files/run/t4110.check +++ b/test/files/run/t4110.check @@ -1,2 +1,2 @@ -Object with Test$A with Test$B -Object with Test$A with Test$B +Object with Test$A with Test$B with Object +Object with Test$A with Test$B with Object 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 -- cgit v1.2.3 From 513710c5277ef8870ba3f5c7c9bebe40068ce4af Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 4 Feb 2012 13:16:15 -0800 Subject: Simple test manipulating Any-derived traits. --- test/files/pos/trait-parents.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/files/pos/trait-parents.scala (limited to 'test/files/pos') 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 { }) + } +} -- cgit v1.2.3