diff options
author | Paul Phillips <paulp@improving.org> | 2012-05-10 12:39:09 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-05-10 16:01:38 -0700 |
commit | 4db08212f63d3a5cd5467b91b25ff5b36e79fd5c (patch) | |
tree | 6fafc157026845c96378ad4d7373562bb4240a27 /src/compiler | |
parent | 1bff5703d28a0232dc772769dd6017862114a4a2 (diff) | |
download | scala-4db08212f63d3a5cd5467b91b25ff5b36e79fd5c.tar.gz scala-4db08212f63d3a5cd5467b91b25ff5b36e79fd5c.tar.bz2 scala-4db08212f63d3a5cd5467b91b25ff5b36e79fd5c.zip |
Be discriminating about custom hashcodes.
If there are no primitives, use the regular boxy one.
Diffstat (limited to 'src/compiler')
6 files changed, 17 insertions, 11 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index edafde1346..0612dcdfd4 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -1207,7 +1207,7 @@ trait Definitions extends reflect.api.StandardDefinitions { def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass) def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass) - def isScalaValueType(tp: Type) = ScalaValueClasses contains tp.typeSymbol + def isPrimitiveValueType(tp: Type) = isPrimitiveValueClass(tp.typeSymbol) /** Is symbol a boxed value class, e.g. java.lang.Integer? */ def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym) diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index a93d9efded..23fcffd657 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -236,7 +236,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { mkMethodCall( PredefModule, wrapArrayMethodName(elemtp), - if (isScalaValueType(elemtp)) Nil else List(elemtp), + if (isPrimitiveValueType(elemtp)) Nil else List(elemtp), List(tree) ) } @@ -261,7 +261,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { * elem type elemtp to expected type pt. */ def mkCastArray(tree: Tree, elemtp: Type, pt: Type) = - if (elemtp.typeSymbol == AnyClass && isScalaValueType(tree.tpe.typeArgs.head)) + if (elemtp.typeSymbol == AnyClass && isPrimitiveValueType(tree.tpe.typeArgs.head)) mkCast(mkRuntimeCall(nme.toObjectArray, List(tree)), pt) else mkCast(tree, pt) diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 61f3670f5f..c3525037cd 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -179,7 +179,7 @@ trait ModelFactoryImplicitSupport { hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName)) // Filter out non-sensical conversions from value types - if (isScalaValueType(sym.tpe)) + if (isPrimitiveValueType(sym.tpe)) conversions = conversions.filter((ic: ImplicitConversion) => hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName)) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 9e7e4b3f4f..3625b19dd4 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -619,7 +619,7 @@ abstract class Erasure extends AddInterfaces tree.duplicate setType pt } else if (tree.tpe != null && tree.tpe.typeSymbol == ArrayClass && pt.typeSymbol == ArrayClass) { // See SI-2386 for one example of when this might be necessary. - val needsExtraCast = isScalaValueType(tree.tpe.typeArgs.head) && !isScalaValueType(pt.typeArgs.head) + val needsExtraCast = isPrimitiveValueType(tree.tpe.typeArgs.head) && !isPrimitiveValueType(pt.typeArgs.head) val tree1 = if (needsExtraCast) gen.mkRuntimeCall(nme.toObjectArray, List(tree)) else tree gen.mkAttributedCast(tree1, pt) } else gen.mkAttributedCast(tree, pt) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index aea29a27dd..7e780304e7 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -67,7 +67,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, - ScalaValueClasses, isPrimitiveValueClass, isScalaValueType, + ScalaValueClasses, isPrimitiveValueClass, isPrimitiveValueType, SpecializedClass, UnspecializedClass, AnyRefClass, ObjectClass, AnyRefModule, GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass } @@ -145,7 +145,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def includes(t1: TypeEnv, t2: TypeEnv) = t1 forall { case (sym, tpe) => t2 get sym exists { t2tp => - (tpe == t2tp) || !(isScalaValueType(tpe) || isScalaValueType(t2tp)) // u.t.b. (t2tp <:< AnyRefClass.tpe) + (tpe == t2tp) || !(isPrimitiveValueType(tpe) || isPrimitiveValueType(t2tp)) // u.t.b. (t2tp <:< AnyRefClass.tpe) } } @@ -266,7 +266,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * specialized type. */ def survivingArgs(sym: Symbol, args: List[Type]): List[Type] = - for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isScalaValueType(tpe)) + for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isPrimitiveValueType(tpe)) yield tpe val specializedType = new TypeMap { @@ -448,7 +448,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { /** Type parameters that survive when specializing in the specified environment. */ def survivingParams(params: List[Symbol], env: TypeEnv) = - params.filter(p => !p.isSpecialized || !isScalaValueType(env(p))) + params.filter(p => !p.isSpecialized || !isPrimitiveValueType(env(p))) /** Produces the symbols from type parameters `syms` of the original owner, * in the given type environment `env`. The new owner is `nowner`. @@ -1588,7 +1588,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // val (_, origtparams) = splitParams(source.typeParams) val env = typeEnv(symbol) val boundTvars = env.keySet - val origtparams = source.typeParams.filter(tparam => !boundTvars(tparam) || !isScalaValueType(env(tparam))) + val origtparams = source.typeParams.filter(tparam => !boundTvars(tparam) || !isPrimitiveValueType(env(tparam))) if (origtparams.nonEmpty || symbol.typeParams.nonEmpty) debuglog("substituting " + origtparams + " for " + symbol.typeParams) diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 484c8beb1b..6faa9a3cb7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -254,6 +254,12 @@ trait SyntheticMethods extends ast.TreeDSL { Block(valdef :: mixes, finish) } } + def chooseHashcode = { + if (accessors exists (x => isPrimitiveValueType(x.tpe.finalResultType))) + specializedHashcode + else + forwardToRuntime(Object_hashCode) + } def valueClassMethods = List( Any_hashCode -> (() => hashCodeDerivedValueClassMethod), @@ -261,7 +267,7 @@ trait SyntheticMethods extends ast.TreeDSL { ) def caseClassMethods = productMethods ++ productNMethods ++ Seq( - Object_hashCode -> (() => specializedHashcode), + Object_hashCode -> (() => chooseHashcode), Object_toString -> (() => forwardToRuntime(Object_toString)), Object_equals -> (() => equalsCaseClassMethod) ) |