diff options
author | Paul Phillips <paulp@improving.org> | 2012-08-31 17:40:58 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-08-31 23:34:16 -0700 |
commit | 34893e5d77b683dfd442162f7a5a28b6901c7080 (patch) | |
tree | 62f68aedf5c9d4f6812ade5ad9589c885baf378e | |
parent | 78401c8220fb56ed077b99a5ffb4205c14fee736 (diff) | |
download | scala-34893e5d77b683dfd442162f7a5a28b6901c7080.tar.gz scala-34893e5d77b683dfd442162f7a5a28b6901c7080.tar.bz2 scala-34893e5d77b683dfd442162f7a5a28b6901c7080.zip |
Fix for SI-6034, covariant value classes.
My summary in the ticket was incorrect. The problem was that the
class type parameters were being cloned for the method and being
allowed to keep their variance. I threw in an assertion for anyone
attempting to create a method type with variant type parameters,
because hey, why should we allow such madness.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 3 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 1 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 9 | ||||
-rw-r--r-- | test/files/pos/t6034.scala | 1 |
4 files changed, 11 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 2831afc48e..0820d3e714 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -111,7 +111,8 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { } def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = { - var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) + // No variance for method type parameters + var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) map (_ resetFlag COVARIANT | CONTRAVARIANT) val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpeHK)) val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType def transform(clonedType: Type): Type = clonedType match { diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 37f41e2868..2e045b08b9 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -516,6 +516,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isTypeParameterOrSkolem = false def isTypeSkolem = false def isTypeMacro = false + def isInvariant = !isCovariant && !isContravariant /** Qualities of Terms, always false for TypeSymbols. */ diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 01f615c5cc..b13b893635 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3712,10 +3712,15 @@ trait Types extends api.Types { self: SymbolTable => * may or may not be poly? (It filched the standard "canonical creator" name.) */ object GenPolyType { - def apply(tparams: List[Symbol], tpe: Type): Type = ( + def apply(tparams: List[Symbol], tpe: Type): Type = { + tpe match { + case MethodType(_, _) => + assert(tparams forall (_.isInvariant), "Trying to create a method with variant type parameters: " + ((tparams, tpe))) + case _ => + } 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((Nil, tpe)) diff --git a/test/files/pos/t6034.scala b/test/files/pos/t6034.scala new file mode 100644 index 0000000000..3558d7ff0b --- /dev/null +++ b/test/files/pos/t6034.scala @@ -0,0 +1 @@ +final class OptPlus[+A](val x: A) extends AnyVal { } |