Skip to content

Commit 81fa831

Browse files
committed
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.
1 parent 275b341 commit 81fa831

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

src/compiler/scala/tools/nsc/interpreter/IMain.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
262262
protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = {
263263
settings.outputDirs setSingleOutput virtualDirectory
264264
settings.exposeEmptyPackage.value = true
265-
new Global(settings, reporter) with ReplGlobal
265+
new Global(settings, reporter) with ReplGlobal {
266+
override def toString: String = "<global>"
267+
}
266268
}
267269

268270
/** Parent classloader. Overridable. */

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,6 +2867,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
28672867
final override def isNonClassType = false
28682868
final override def isAbstractType = false
28692869
final override def isAliasType = false
2870+
final override def isContravariant = false
28702871

28712872
override def isAbstractClass = this hasFlag ABSTRACT
28722873
override def isCaseClass = this hasFlag CASE
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Type in expressions to have them evaluated.
2+
Type :help for more information.
3+
4+
scala> :power
5+
** Power User mode enabled - BEEP WHIR GYVE **
6+
** :phase has been set to 'typer'. **
7+
** scala.tools.nsc._ has been imported **
8+
** global._, definitions._ also imported **
9+
** Try :help, :vals, power.<tab> **
10+
11+
scala> val u = rootMirror.universe
12+
u: $r.intp.global.type = <global>
13+
14+
scala> import u._, scala.reflect.internal.Flags
15+
import u._
16+
import scala.reflect.internal.Flags
17+
18+
scala> class C
19+
defined class C
20+
21+
scala> val sym = u.typeOf[C].typeSymbol
22+
sym: u.Symbol = class C
23+
24+
scala> sym.isContravariant
25+
res0: Boolean = false
26+
27+
scala> sym setFlag Flags.INCONSTRUCTOR
28+
res1: sym.type = class C
29+
30+
scala> sym.isClassLocalToConstructor
31+
res2: Boolean = true
32+
33+
scala> sym.isContravariant // was true
34+
res3: Boolean = false
35+
36+
scala>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.tools.partest.ReplTest
2+
3+
object Test extends ReplTest {
4+
override def code = """
5+
|:power
6+
|val u = rootMirror.universe
7+
|import u._, scala.reflect.internal.Flags
8+
|class C
9+
|val sym = u.typeOf[C].typeSymbol
10+
|sym.isContravariant
11+
|sym setFlag Flags.INCONSTRUCTOR
12+
|sym.isClassLocalToConstructor
13+
|sym.isContravariant // was true
14+
|""".stripMargin.trim
15+
}

0 commit comments

Comments
 (0)