From 81fa8316092e295c1a893b6fcf65568c11fffb58 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 2 Feb 2013 13:18:00 +0100 Subject: 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 / CONTRAVARIANT / LABEL case EXISTENTIAL => "" // EXISTENTIAL / MIXEDIN case IMPLCLASS => "" // IMPLCLASS / PRESUPER case _ => super.resolveOverloadedFlag(flag) } This commit overrides `isContravariant` to reflect the same logic. --- test/files/run/class-symbol-contravariant.check | 36 +++++++++++++++++++++++++ test/files/run/class-symbol-contravariant.scala | 15 +++++++++++ 2 files changed, 51 insertions(+) create mode 100644 test/files/run/class-symbol-contravariant.check create mode 100644 test/files/run/class-symbol-contravariant.scala (limited to 'test/files/run') 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. ** + +scala> val u = rootMirror.universe +u: $r.intp.global.type = + +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 -- cgit v1.2.3