diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-06 13:11:30 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-06 15:12:45 -0800 |
commit | 7f9c2636cf560b066783e0745a08393ce17531cd (patch) | |
tree | 225407c8dc22bab25301f9916c6c70eaba00d0ae /src | |
parent | 7539c4ee51c25a684399cd5400bf0285e6508fe2 (diff) | |
download | scala-7f9c2636cf560b066783e0745a08393ce17531cd.tar.gz scala-7f9c2636cf560b066783e0745a08393ce17531cd.tar.bz2 scala-7f9c2636cf560b066783e0745a08393ce17531cd.zip |
Removing unnecessary AnyVal code.
...since it works from source. The parser must be forcibly restrained
from adding a bogus constructor, but other than that it's pretty much
smooth sailing. To give an idea how smooth, if I change scala.Short like so:
trait Bippy extends Any
final class Short extends AnyVal with Bippy
Then it just works, at least until the fiction is revealed.
scala> def f(x: Bippy) = x
f: (x: Bippy)Bippy
scala> f(5)
<console>:9: error: type mismatch;
found : Int(5)
required: Bippy
f(5)
^
scala> f(5: Short)
java.lang.ClassCastException: java.lang.Short cannot be cast to scala.Bippy
at .<init>(<console>:9)
at .<clinit>(<console>)
at .<init>(<console>:11)
Diffstat (limited to 'src')
3 files changed, 30 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index c2b4dc32b6..20c35e952f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2722,23 +2722,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,29 +2733,25 @@ 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 (inScalaPackage && name == tpnme.AnyVal) { - // Not a well-formed constructor, has to be finished later - see note - // regarding AnyVal constructor in AddInterfaces. - val constructor = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(), Block(Nil, Literal(Constant()))) - Template(parents0, self, constructor :: body) - } - else if (isPrimitiveType(name)) - Template(List(scalaAnyValConstr), self, body) - else if (parents0 exists isReferenceToAnyVal) { - // @inline and other restrictions enforced in refchecks - Template(parents0, self, body) - } - else { - val casePs = caseParents() - val parents = parents0 match { - case Nil if casePs.isEmpty => List(scalaAnyRefConstr) - case _ => parents0 ++ casePs - } - Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart)) - } + if ((inScalaPackage && name == tpnme.AnyVal) || (parents0 exists isReferenceToAnyVal)) + Template(parents0, self, anyvalConstructor :: body) + else + Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart)) } } diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index e7759f1d7e..531a475bc6 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -302,21 +302,19 @@ abstract class AddInterfaces extends InfoTransform { yield mixinConstructorCall(implClass(mc)) } 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) - stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER)) match { - case (presuper, supercall :: rest) => - stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER)) - treeCopy.Block(tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr) - case (Nil, Nil) => - assert(clazz eq AnyValClass, clazz) - // 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. - val superCall = Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil) - Block(List(superCall), Literal(Constant())) - } + val (presuper, supercall :: rest) = stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER)) + treeCopy.Block(tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 59437dc036..4bb2387439 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1787,11 +1787,10 @@ 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. - if (meth.owner ne AnyValClass) - computeParamAliases(meth.owner, vparamss1, rhs1) + computeParamAliases(meth.owner, vparamss1, rhs1) } if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass) rhs1 = checkDead(rhs1) |