diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-02-02 13:18:00 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-02-04 01:46:46 +0100 |
commit | 81fa8316092e295c1a893b6fcf65568c11fffb58 (patch) | |
tree | 661be4a54455db15f1f5edc993f936dc312cb3da | |
parent | 275b341545a3c4e633bd735cf45ccc1956a4233e (diff) | |
download | scala-81fa8316092e295c1a893b6fcf65568c11fffb58.tar.gz scala-81fa8316092e295c1a893b6fcf65568c11fffb58.tar.bz2 scala-81fa8316092e295c1a893b6fcf65568c11fffb58.zip |
Class symbols can't be contravariant.
During development of the fix for SI-6666, I encountered:
% test/files/pos/t4842.scala
test/files/pos/t4842.scala:10: error: contravariant class Bar occurs in covariant position in type ()this.Bar of constructor Bar
this(new { class Bar { println(Bar.this); new { println(Bar.this) } }; new Bar } ) // okay
I had incorrectly set the INCONSTRUCTOR flag on the class symbol
`Bar`. (It isn't directly in the self constructor call, as it
is nested an intervening anonymous class.)
But, this flag shares a slot with CONTRAVARIANT, and the variance
validation intepreted it as such.
ClassSymbol already has this code to resolve the ambiguous
flags for display purposes:
override def resolveOverloadedFlag(flag: Long) = flag match {
case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL
case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN
case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER
case _ => super.resolveOverloadedFlag(flag)
}
This commit overrides `isContravariant` to reflect the same logic.
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 1 | ||||
-rw-r--r-- | test/files/run/class-symbol-contravariant.check | 36 | ||||
-rw-r--r-- | test/files/run/class-symbol-contravariant.scala | 15 |
4 files changed, 55 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index b46d28dec3..4b6466c079 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -262,7 +262,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = { settings.outputDirs setSingleOutput virtualDirectory settings.exposeEmptyPackage.value = true - new Global(settings, reporter) with ReplGlobal + new Global(settings, reporter) with ReplGlobal { + override def toString: String = "<global>" + } } /** Parent classloader. Overridable. */ diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index a4287fb181..923dac7498 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2867,6 +2867,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final override def isNonClassType = false final override def isAbstractType = false final override def isAliasType = false + final override def isContravariant = false override def isAbstractClass = this hasFlag ABSTRACT override def isCaseClass = this hasFlag CASE diff --git a/test/files/run/class-symbol-contravariant.check b/test/files/run/class-symbol-contravariant.check new file mode 100644 index 0000000000..987f215bca --- /dev/null +++ b/test/files/run/class-symbol-contravariant.check @@ -0,0 +1,36 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power.<tab> ** + +scala> val u = rootMirror.universe +u: $r.intp.global.type = <global> + +scala> import u._, scala.reflect.internal.Flags +import u._ +import scala.reflect.internal.Flags + +scala> class C +defined class C + +scala> val sym = u.typeOf[C].typeSymbol +sym: u.Symbol = class C + +scala> sym.isContravariant +res0: Boolean = false + +scala> sym setFlag Flags.INCONSTRUCTOR +res1: sym.type = class C + +scala> sym.isClassLocalToConstructor +res2: Boolean = true + +scala> sym.isContravariant // was true +res3: Boolean = false + +scala> diff --git a/test/files/run/class-symbol-contravariant.scala b/test/files/run/class-symbol-contravariant.scala new file mode 100644 index 0000000000..6a84944e3b --- /dev/null +++ b/test/files/run/class-symbol-contravariant.scala @@ -0,0 +1,15 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = """ + |:power + |val u = rootMirror.universe + |import u._, scala.reflect.internal.Flags + |class C + |val sym = u.typeOf[C].typeSymbol + |sym.isContravariant + |sym setFlag Flags.INCONSTRUCTOR + |sym.isClassLocalToConstructor + |sym.isContravariant // was true + |""".stripMargin.trim +}
\ No newline at end of file |