summaryrefslogtreecommitdiff
path: root/src/reflect
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #2292 from retronym/ticket/7285Adriaan Moors2013-03-271-3/+4
|\ | | | | SI-7285 Fix match analysis with nested objects
| * SI-7285 Fix match analysis with nested objects.Jason Zaugg2013-03-231-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The fix for SI-6146 introduced `nestedMemberType` to enumerate sealed subtypes based on the (prefixed) type of the scrutinee and the symbols of its sealed subclasses. That method needed to widen `ThisType(modSym)`s to `ModuleTypeRef(modSym)` before calling `asSeenFrom`. However, this could lead to confused in the match analysis, which sees `ModuleTypeRef` as distinct from singleton types on the same modules (after all, they aren't =:=). Spurious warnings ensued. This commit makes two changes: - conditionally re-narrow the result of `asSeenFrom` in `nestedMemberType`. - present `a.b.SomeModule.type` as `SomeModule` in warnings emitted by the pattern matcher.
* | Merge pull request #2288 from paulp/pr/2273-with-editsPaul Phillips2013-03-271-11/+24
|\ \ | | | | | | SI-6387 Clones accessor before name expansion
| * | SI-6387 Clones accessor before name expansionEugene Vigdorchik2013-03-251-11/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a symbol's name is expanded due to a conflict during composition (e.g. multiple traits with same-named members, but which are not both visible at the language level in the concrete class) the compiler renames some symbols with expanded names which embed the full name of the declaring class to avoid clashes. In the rare cases when the accessor overrides the member in base class, such expansion either results in AbstractMethodError when the base method is abstract, or, even worse, can change the semantics of the program. To avoid such issues, we clone the accessor symbol, clear its ACCESSOR flag and enter the symbol with an unchanged name.
* | | Merge pull request #2257 from JamesIry/2.10.x_classfile_51Paul Phillips2013-03-251-1/+4
|\ \ \ | |_|/ |/| | Read version 51 (JDK 7) class files.
| * | Read version 51 (JDK 7) class files.James Iry2013-03-141-1/+4
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit makes the ClassFileReader/ICodeReader parse class files from JDK 7 (class file version 51). It does that by skipping over the method handle related entries in the constant pool and by doing some dummy processing on invoke dynamic instructions. The inliner is updated to not try to inline a method with an invoke dynamic instruction. A place holder INVOKE_DYNAMIC instruction is added to ICode but it is designed to create an error if there's ever any attempt to analyze it. Because the inliner is the only phase that ever tries to analyze ICode instructions not generated from Scala source and because Scala source will never emit an INVOKE_DYNAMIC, the place holder INVOKE_DYNAMIC should never cause any errors. A test is included that generates a class file with INVOKE_DYNAMIC and then compiles Scala code that depends on it.
* / fixes the craziness in JavaUniverse.logEugene Burmako2013-03-201-1/+1
|/ | | | | | | This long-standing, but trivial to fix nuisance in the implementation of runtime reflection actively avoided being fixed in both 2.10.0 and 2.10.1. It's finally the time to put it to a rest.
* Merge pull request #2234 from scalamacros/ticket/7240Paul Phillips2013-03-122-2/+2
|\ | | | | SI-7240 fixes language feature lookup
| * SI-7240 fixes language feature lookupEugene Burmako2013-03-122-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As I discovered today, Definitions.getMember have a fallback clause, which accounts for the phases which have inner classes flattened. This fallback uses nme.flattenedName to compute a flattened name, but unfortunately nme.flattenedName produces a TermName, not a TypeName, which means that the fallback will commence search in a wrong namespace with predictable results. The commit also changes another usage of nme.flattenedName in a type name context. That one was correctly converting a TermName result to TypeName, so this is not a bugfix, but just a refactoring for the sake of being consistent.
* | SI-7226 Fix inference regression caused by TypeVar equality.Jason Zaugg2013-03-091-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TypeVars, being mutable creatures, mustn't have structural equality/hashing, otherwise TypeRefs that differ only by having distinct TypeVars as components get wrongly uniqued together. The reported bug showed the disaterous consequences: constraints from the `C?[Int]` in the return type applied to the `?C[?A]` in the parameter list. This commit overrides `equals` and `hashCode` in `TypeVar` to use reference equality. An alternative fix would be to drop the `case`-ness of the class, as was the case before 0cde930b when this regressed.
* | Merge pull request #2199 from retronym/ticket/7214Adriaan Moors2013-03-051-1/+3
|\ \ | | | | | | SI-7214 outer check based on dealiased pattern type.
| * | SI-7214 outer check based on dealiased pattern type.Jason Zaugg2013-03-051-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A Typed Pattern (_: T) is more than `.isInstanceOf`: if `T` is a path dependent type, the scrutinee's $outer reference is also compared against the prefix of `T`. The code that synthesises this is split into two places. `needsOuterCheck` determines whether to add this check, based on the type `T`, and the type of the scrutinee. If it gives the go-ahead, `treeCondStrategy.outerCheck` synthesizes the check. The new test case demonstrates the problems caused by the failure to dealias in `needsOuterCheck`: it could either wrongly lead to synthesis of an outer test (which would crash), or wrongly omit the outer test (meaning overly liberal matching.) A simple `dealias` remedies this. `dealiasWiden` is *not* appropriate here; we need to keep hold of singleton types. I'll also note that there is already a little slack between these methods, as commented: > ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` > by `Select(q, > outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` > if there's an outer accessor, otherwise the condition becomes `true` > TODO: can we improve needsOuterTest so there's always an outerAccessor? So this is probably a fragile area that warrants a careful review with a view to design improvements.
* | | Merge pull request #2193 from adriaanm/patmat-refactorAdriaan Moors2013-03-051-4/+11
|\ \ \ | | | | | | | | merge 2.10.1 into 2.10.x
| * \ \ Merge 2.10.1 into 2.10.xAdriaan Moors2013-03-031-4/+11
| |\ \ \ | | |_|/ | |/| | | | | | | | | | | | | | | | | | The fix for SI-7183 in 440bf0a8c2 was forward ported in f73d50f46c. Conflicts: src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
| | * | SI-7126 Eliminate a source of malformed types.Jason Zaugg2013-02-261-4/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The kind-polymorphic nature of Nothing and Any in concert with type argument inference could lead to types like `T[T]` (where `type T=Any`). Compensatory action is taken later on to recover; see the usages of `TypeRef#typeParamsMatchArgs`. But this these types have a nasty property, they can dealias to themselves. Callers recursing through types who fail to account for this hit an infinite recursion, as was reported in SI-7126. This commit simply dealiases `T` when registering the type bound in `unifySimple`. We should try to weed out additional sources of these types.
* | | | Merge pull request #2175 from retronym/ticket/7185Paul Phillips2013-03-051-1/+2
|\ \ \ \ | |/ / / |/| | | SI-7185 Avoid NPE in TreeInfo.isExprSafeToInline
| * | | SI-7185 Avoid NPE in TreeInfo.isExprSafeToInlineJason Zaugg2013-03-021-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We got there typechecking code with a redundant layer of Block. We can't express that in source code, so we test this with manual tree construction and with XML literals, which as reported produce such trees.
* | | | Merge pull request #2184 from adriaanm/revert-pr-2083Adriaan Moors2013-03-0119-1439/+308
|\ \ \ \ | | | | | | | | | | Revert SI-6240 synchronization for runtime reflection
| * | | | Revert SI-6240 synchronization for runtime reflectionAdriaan Moors2013-03-0119-1439/+308
| | |_|/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit reverts #2083: - 387b2590db runtime reflection: death from thousand threads - 73d079fb38 removes the assertion in missingHook - f4dd56ca5d synchronizes names - dd148de5a8 synchronizes pendingVolatiles - 4cbb9357c5 synchronizes toolboxes - 07bcb6176a SI-7045 reflection now auto-initializes selfType - bebd62d566 optimizes Scala reflection GIL - 735634f1d6 initializes lazy vals and inner objects in advance - 5b37cfb19a introduces GIL to Scala reflection - 981da8edfc cleans up initialization of runtime reflection - b2c2493b22 reflection no longer uses atPhase and friends - a9dca512d8 synchronizes symbols - 0262941b3c removes the crazy extraneous log - 21d5d3820b moves Symbol#SymbolKind to Symbols
* | | | Merge pull request #2179 from adriaanm/merge-2.10.1Adriaan Moors2013-03-014-37/+28
|\ \ \ \ | |/ / / |/| | | Merge 2.10.1 into 2.10.x
| * | | Merge 2.10.1 into 2.10.x.Adriaan Moors2013-02-274-37/+28
| |\ \ \ | | |/ / | |/| / | | |/
| | * [nomaster] Revert "SI-6548 reflection now correctly enters jinners"Adriaan Moors2013-02-101-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 54a84a36d5b435a787d93ca48d45399136c7e162. This is necessary to maintain binary compatibility with 2.10.0. run/t6989.check had to be updated as it also (indirectly) tested SI-6548 Conflicts: test/files/lib/javac-artifacts.jar.desired.sha1 test/files/run/t6548.check test/files/run/t6548/Test_2.scala
| | * [nomaster] inline importPrivateWithinFromJavaFlags into SymbolTableAdriaan Moors2013-02-092-24/+15
| | | | | | | | | | | | | | | | | | This reworks 02ed5fb so that we don't change JavaUniverse's super classes. This is necessary to maintain binary compatibility with 2.10.0.
| | * [nomaster] Revert "cosmetic renamings in runtime reflection"Adriaan Moors2013-02-092-6/+6
| | | | | | | | | | | | | | | | | | This reverts commit 0429f0fd9224499cd8b606490d04b1a8dcffbca8. This is necessary to maintain binary compatibility with 2.10.0.
* | | Merge pull request #2083 from scalamacros/ticket/6240Adriaan Moors2013-02-2719-308/+1439
|\ \ \ | |/ / |/| | SI-6240 synchronization for runtime reflection
| * | removes the assertion in missingHookEugene Burmako2013-02-111-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the current synchronization scheme multiple threads can enter the missingHook trying to materialize a package, which hasn't been created. That's fine, because makeScalaPackage, which creates and enters package symbols is synchronized and checks whether the creation is necessary before commencing. Therefore even if makeScalaPackage is called multiple times in rapid succession, the calls will be serialized and all calls except the first one won't do anything.
| * | synchronizes namesEugene Burmako2013-02-112-27/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | Previously we didn't have all possible name creation facilities covered with locks, so some of them silently misbehaved and caused much grief: http://groups.google.com/group/scala-internals/browse_thread/thread/ec1d3e2c4bcb000a. This patch gets all the name factories under control. Unfortunately it comes at a performance cost, which has to be evaluated.
| * | synchronizes pendingVolatilesEugene Burmako2013-02-112-4/+2
| | | | | | | | | | | | | | | Called from isVolatile, which is called from isStable, which is a part of the public reflection API.
| * | SI-7045 reflection now auto-initializes selfTypeEugene Burmako2013-02-111-1/+5
| | | | | | | | | | | | | | | | | | selfType joins the happy family of flags, annotations and privateWithin, which automatically trigger initialization, when used within runtime reflection.
| * | optimizes Scala reflection GILEugene Burmako2013-02-114-64/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | First of all, GIL should only apply to runtime reflection, because noone is going to run toolboxes in multiple threads: a) that's impossible, b/c the compiler isn't thread safe, b) ToolBox api prevents that. Secondly, the only things in symbols which require synchronization are: 1) info/validTo (completers aren't thread-safe), 2) rawInfo and its dependencies (it shares a mutable field with info) 3) non-trivial caches like in typeAsMemberOfLock If you think about it, other things like sourceModule or associatedFile don't need synchronization, because they are either set up when a symbol is created or cloned or when it's completed. The former is obviously safe, while the latter is safe as well, because before acquiring init-dependent state of symbols, the compiler calls `initialize`, which is synchronized. We can say that symbols can be in four possible states: 1) being created, 2) created, but not yet initialized, 3) initializing, 4) initialized. in runtime reflection can undergo is init. #3 is dangerous and needs protection
| * | initializes lazy vals and inner objects in advanceEugene Burmako2013-02-115-5/+1041
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As discussed at http://groups.google.com/group/scala-internals/browse_thread/thread/97840ba4fd37b52e, `synchronized(this)` employed by lazy val and inner object initialization is an excellent way to deadlock yourself in the foot. Imagine a thread, which grabs a reflection GIL and then calls one of those lazy vals / objects that reflection exposes (e.g. a companion module of an innocently looking SingleType case class). Then imagine another thread, which calls something else in SymbolTable, grabbing symbol table's monitor, and then tries to get a reflection GIL to do something non-trivial. Hello, we've just arrived at a deadlock. Since, as discussed in the aforementioned thread, there's no easy way to change lazy vals / inner objects in reflection to use GIL instead of synchronizing on this, I bit the bullet and manually initialized all things with deferred initialization defined in reflect.runtime.SymbolTable. The list of all things `$lzycompute` has been mined by a simple Python script, then I copy/pasted that list into `JavaUniverse.scala` and went ahead forcing objects and lazy vals mentioned there. Notably, I've been able to force all lazy vals in Definitions.scala. There are some todos left, but I suggest we move forward without securing them, because the 2.10.1-RC1 release date is very close, so we'd better have a 95% solution instead of keeping reflection thread-unsafe. Though here's the list of todo lazy vals for the reference: * BaseTypeSeq.maxDepth * WeakTypeTag.tpe * AnnotationInfo.forcedInfo For each of those lazy vals we need to make sure that their initializers never call back into themselves. Otherwise, there's a danger of a deadlock.
| * | introduces GIL to Scala reflectionEugene Burmako2013-02-1110-178/+235
| | | | | | | | | | | | | | | | | | | | | On a serious note, I feel really uncomfortable about having to juggle this slew of locks. Despite that I can't immediately find a deadlock, I'm 100% sure there is one hiding in the shadows. Hence, I'm abandoning all runtime reflection locks in favor of a single per-universe one.
| * | cleans up initialization of runtime reflectionEugene Burmako2013-02-117-29/+59
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At first I just tried to remove syntheticCoreClasses from missingHook and put them into the initializer of freshly created mirrors in order to reduce the non-determinism in mutations of the global symbol table. And then it didn't work, crashing on me claiming that AnyRef is missing. Apparently we still need AnyRefClass in missingHook, just because it's impossible to initialize (i.e. unpickle) ScalaPackageClass without it. And then it still didn't work, whining about multiple overloaded defs of some synthetic symbols. That was really tricky, but I figured it out as well by initializing ScalaPackageClass first before forcing any synthetic symbols (see the details in comments).
| * | reflection no longer uses atPhase and friendsEugene Burmako2013-02-114-28/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Mentioned methods mutate the global `atPhaseStack` variable, which can easily lead to imbalances and, ultimately, to the empty stack error. Luckily for us, there's only one dummy phase, SomePhase, which is used by runtime reflection, so there is absolutely zero need to invoke atPhase in non-compiler reflexive universes. The cleanest solution would be to override `atPhase` for runtime reflection, but it's @inline final, so I didn't want to pay performance penalties for something that's used three times in runtime reflection (during unpickling, in reflection-specific completers and in `Symbol.typeParams/unsafeTypeParams`). Therefore I added overrideable analogues of `atPhase` and `atPhaseNotLaterThan` which are called from the aforementioned code shared between the compiler and runtime reflection. I also had to duplicate the code of `Symbol.XXXtypeParams`, again due to them being very performance-sensitive.
| * | synchronizes symbolsEugene Burmako2013-02-113-16/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Synchronization via decoration would be neat if it actually worked. Unfortunately, root symbols never got decorated, therefore their children also never got decorated and all the way down to the very turtles. This commit fixes this sad issue by turning root symbols from objects to lazy vals. Yes, this is going to induce a performance penalty, which will hopefully not be high enough to invalidate this cornerstone of our synchronization strategy. Now when root symbols are lazy vals, they can be overridden in the runtime reflexive universe and decorated with SynchronizedSymbol, which makes their children sync and sound.
| * | removes the crazy extraneous logEugene Burmako2013-02-111-1/+1
| | |
| * | moves Symbol#SymbolKind to SymbolsEugene Burmako2013-02-111-1/+2
| |/ | | | | | | | | | | | | Too bad I didn't notice that before. That will free up quite a bit of memory, removing an extraneous field in every single Symbol, namely the: private volatile Symbols.Symbol.SymbolKind$ SymbolKind$module
* | Merge pull request #2157 from retronym/ticket/7171James Iry2013-02-221-2/+2
|\ \ | | | | | | SI-7171 Consider prefix when assessing type finality.
| * | SI-7171 Consider prefix when assessing type finality.Jason Zaugg2013-02-221-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `Type#isFinalType` determines if a type could have a non-bottom subtype. This property is exploited by the pattern matcher to flag impossible patterns. This check was ignoring the type's prefix, and incorrectly deemed that `T#A` in `trait T { final class A }` was a final type. But it could have been subtyped by `U#A` where `U` <:< `T`, or, more simply, by `T.this.A`. Now, type finality requires that the prefix is stable. The existing test cases in neg/patmat-type-check.scala still correctly flag incompatiblities. `isFinalType` is also used by some code that massages pattern matches post specialization. That is actually either broken or obsolete under virtpatmat, I've opened SI-7172 to invesigate that. It is also used by GenICode to determine whether to emit the appropriate equality checks that are correct in the face of boxing. It is possible that this change will force the slow path in some rare cases, but it won't affect correctness.
* | | Fixed error in reflection API docs about linearization order on method ↵Heather Miller2013-02-192-2/+2
|/ / | | | | | | baseClasses
* | Merge pull request #2129 from gkossakowski/issues/SI-7130-StatisticsJames Iry2013-02-191-1/+1
|\ \ | | | | | | Fix SI-7130: Memory leaked caused by Statistics
| * | Fix SI-7130: Memory leaked caused by StatisticsGrzegorz Kossakowski2013-02-141-1/+1
| |/ | | | | | | | | | | | | | | | | | | | | | | As described in the ticket, we were leaking memory by holding reference to Global through by-name argument that was captured by an instance of a class stored in global HashMap `qs`. The fix is simple: do not register quantities in HashMap unless statistics is enabled. This way, if Statistics is disabled we do not store any references. We still leak memory in case of statistics being enabled.
* / SI-5744 evidence params are now SYNTHETICUladzimir Abramchuk2013-02-161-1/+1
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | The macro def <-> macro impl correspondence check compares names of the corresponding parameters in def and impl and reports an error if they don't match. This was originally designed to avoid confusion w.r.t named arguments (which ended up being never implemented as described in SI-5920). Sometimes parameter names are generated by the compiler, which puts the user in a tough position. Luckily, there's an escape hatch built it, which omits the name correspondence check if one of the parameters is SYNTHETIC. Everything went well until we realized that evidences generated by context bounds aren't SYNTHETIC, which led to the bug at hand. Marking auto-generated evidence parameters SYNTHETIC was only the first step, as the correspondence checker uses parameter symbols, not parameter trees. Why's that a problem? Because SYNTHETIC doesn't get propagated from def trees to their underlying symbols (see ValueParameterFlags). Unfortunately one cannot just change ValueParameterFlags, because that would break printouts generated in TypeDiagnostics, which is designed to not print synthetic symbols. Thus we modify methodTypeErrorString in TypeDiagnostics to always print synthetic symbols. Therefore now we propagate all paramSym.flags when doing correspondent sweeps to keep them in sync between def trees and their underlying symbols. This fixes the problem.
* Merge pull request #2094 from scalamacros/ticket/6591James Iry2013-02-083-6/+10
|\ | | | | SI-6591 Reify and path-dependent types
| * accommodates pull request feedbackEugene Burmako2013-02-081-9/+6
| | | | | | | | https://github.com/scala/scala/pull/2072
| * SI-6591 Reify and path-dependent typesDmitry Bushev2013-02-083-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reification scheme changed. Now Select an SelectFromTypeTree trees reified appropriately, as Select and SelectFromTypeTree accordingly. Packages and Predef object was excluded in order not to break the existing reification scheme and not to break tests which rely on it. Reified free terms can contain flag <stable> to make reified values become stable identifiers. For example in the case of reify_newimpl_15.scala class C { type T reify { val v: List[T] = List(2) } } class C reified as free term C$value, and List[C.T] becomes List[C$value().T], so C$value.apply() need to pass stability test isExprSafeToInline at scala.reflect.internal.TreeInfo. For this purpose special case for reified free terms was added to isExprSafeToInline function. test run/reify_newipl_30 disabled due to SI-7082 test t6591_4 moved to pending due to SI-7083
* | Merge pull request #2092 from lrytz/t7096James Iry2013-02-081-13/+29
|\ \ | | | | | | SI-7096 SubstSymMap copies trees before modifying their symbols
| * | SI-7096 SubstSymMap copies trees before modifying their symbolsLukas Rytz2013-02-081-13/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | I removed some strange code in a06d31f6a2 and replaced it by something incorrect: SubstSymMap should never have side-effects: otherwise, calling 'tpe1 <: tpe2' for instance would modify the symbols in annotations of tpe2. SubstSymMap now always creates new trees before changing them.
* | | Merge pull request #2017 from retronym/ticket/6666James Iry2013-02-081-0/+1
|\ \ \ | |_|/ |/| | Booking more progress on SI-6666
| * | Class symbols can't be contravariant.Jason Zaugg2013-02-041-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.