summaryrefslogtreecommitdiff
path: root/src/reflect
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #3100 from som-snytt/paulp/reductionJason Zaugg2013-11-081-0/+38
|\ | | | | Paulper stack reduction
| * A value class for Precedence.Paul Phillips2013-11-081-0/+38
| | | | | | | | | | One fewer Int to be whizzing around the parser hoping to be confused with other Ints.
* | Address review commentsJason Zaugg2013-11-081-1/+1
| | | | | | | | | | - anonymize unused pattern binder - avoid negations
* | Avoid needless TypeRef allocation during erasure.Jason Zaugg2013-11-082-12/+18
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - ThisType(some.package) need not be erased, we can let that prefix through unchanged and avoid churning through allocations. - Sharpen the condition in `rebindInnerClass`. The answer to the deleted comment in the code, is "anonymous and local classes", which are specifically excluded in the new formulation. - Finally, detect if erasure of the TypeRef is an identity and reuse the original. Waste not, want not. To expand on the first point, here is what used to happen during erasure: scala> val scalaPack = typeOf[Predef.type].prefix scalaPack: $r.intp.global.Type = scala.type scala> typeDeconstruct.show(scalaPack) res19: String = ThisType(package scala) scala> typeDeconstruct.show(erasure.scalaErasure(scalaPack)) res20: String = TypeRef(TypeSymbol(final class scala extends )) Showing one step of the erasure type map: scala> typeDeconstruct.show(scalaPack.asInstanceOf[SubType].underlying.typeOfThis) res21: String = SingleType(pre = ThisType(package <root>), package scala)
* SI-7678 Don't cache member symbols of TypeTags in Definitions.Jason Zaugg2013-11-084-105/+116
| | | | | | | | | | | | | | | | | | | | | | | It we can only safely use vals in Definitions for top-level symbols. Otherwise, when the IDE switches to loading the symbol from source, we can hold on to a stale symbol, which in turn impedes implicit materialization of TypeTags. This commit moves (most) of the accessors for member symbols into RunDefinitions, and changes calling code accordingly. This is a win for presentation compiler correctness, and might even shave of a few cycles. In a few cases, I have had to leave a `def` to a member symbol in Definitions so we can get to it from the SymbolTable cake, which doesn't see RunDefinitions. The macro FastTrack facility now correctly recreates the mapping from Symbol to macro implementation each run, using a new facility in perRunCaches to create a run-indexed cache. The enclosed test recreates the situation reported in the ticket, in which TypeTags.scala is loaded from source.
* Add a per-run cache for member symbolsJason Zaugg2013-11-082-8/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | We are all used to calls to `definitions.PredefModule`, or `defintions.Predef_???` to grab the symbol of some well known entity. But you'll notice that some of these are lazy vals, and others are defs. Why is this so? In the presentation compiler, a member like `Predef.???` will be assigned a new symbol after the user browses into `Predef.scala`. Mistakenly using vals in definitions leads to subtle IDE bugs like SI-7678. We are able to trigger these situations in tests, as noted in the comments of that issue. Changing the vals to defs, on the other hand, has a performance penalty. Some schemes to workaround this have shown up: cache them per-implicit search, or compare method names and owners rather than symbols on hot paths in the type checker. This commit introduces a facility to cache these sort of symbols per-run, and uses it to check for `Predef.conforms` and and for the class/type tag materializers. A followup pull request (WIP: https://github.com/retronym/scala/compare/ticket/7678-2) will expand the use of to address the widespread and unsafe caching of member symbols that I found while investigating SI-7678.
* Merge pull request #3081 from JamesIry/wip_delayed_delambdafy_cleanupAdriaan Moors2013-11-074-4/+26
|\ | | | | Delay delambdafication and put the lambda's body into the containing class
| * Flesh out the Delambdafy phase.James Iry2013-11-062-1/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit puts a real body on the Delambdafy phase. From a lambda, Delambdafy will create 1) a static forwarder at the top level of the class that contained the lambda 2) a new top level class that a) has fields and a constructor taking the captured environment (including possbily the "this" reference) b) an apply method that calls the static forwarder c) if needed a bridge method for the apply method 3) an instantiation of the newly created class which replaces the lambda Trees.scala is modified to add two more convenient factories for templates and classdefs. A few basic tests are included to verify that it works as expected. Further commits will have additional tests.
| * Refactor Erasure for delambdafication.James Iry2013-11-062-3/+4
| | | | | | | | | | | | | | This commit is purely a refactor. It pulls code needed to adapt a tree of one type into a tree of another type (by casting, boxing, coercing, etc) out of Erasure and into common locations that will be usable from the Delambdafy phase.
* | Merge pull request #3084 from retronym/topic/optJason Zaugg2013-10-301-1/+1
|\ \ | |/ |/| Microoptimization in implicit search
| * Microptimization in implicit searchJason Zaugg2013-10-281-1/+1
| | | | | | | | Avoid creating a throwaway list of parameter types.
* | SI-6385 Avoid bridges to identical signatures over value classesJason Zaugg2013-10-283-10/+25
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As Paul noted in the comments to SI-6260 (from which I mined some test cases) "there is no possible basis for conflict here": scala> class C[A](val a: Any) extends AnyVal defined class C scala> class B { def x[A](ca: C[A]) = () } defined class B scala> class D extends B { override def x[A](ca: C[A]) = () } <console>:8: error: bridge generated for member method x: [A](ca: C[A])Unit in class D which overrides method x: [A](ca: C[A])Unit in class B clashes with definition of the member itself; both have erased type (ca: Object)Unit class D extends B { override def x[A](ca: C[A]) = () } ^ What was happening? Bridge computation compares `B#x` and `D#x` exitingErasure, which results in comparing: ErasedValueType(C[A(in B#x)]) =:= ErasedValueType(C[A(in D#x)]) These types were considered distinct (on the grounds of the unique type hash consing), even though they have the same erasure and involve the same value class. That triggered creation of an bridge. After post-erasure eliminates the `ErasedValuedType`s, we find that this marvel of enginineering is bridges `(Object)Unit` right back onto itself. The previous resolution of SI-6385 (d435f72e5fb7fe) was a test case that confirmed that we detected the zero-length bridge and reported it nicely, which happened after related work in SI-6260. But we can simply avoid creating in it in the first place. That's what this commit does. It does so by reducing the amount of information carried in `ErasedValueType` to the bare minimum needed during the erasure -> posterasure transition. We need to know: 1. which value class wraps the value, so we can box and unbox as needed 2. the erasure of the underlying value, which will replace this type in post-erasure. This construction means that the bridge above computation now compares: ErasedValueType(C, Any) =:= ErasedValueType(C, Any]) I have included a test to show that: - we don't incur any linkage or other runtime errors in the reported case (run/t6385.scala) - a similar case compiles when the signatures align (pos/t6260a.scala), but does *not* compile when the just erasures align (neg/t6260c.scala) - polymorphic value classes continue to erase to the instantiated type of the unbox: (run/t6260b.scala) - other cases in SI-6260 remains unsolved and indeed unsolvable without an overhaul of value classes: (neg/t6260b.scala) In my travels I spotted a bug in corner case of null, asInstanceOf and value classes, which I have described in a pending test.
* Merge pull request #3073 from retronym/ticket/7928Jason Zaugg2013-10-251-1/+5
|\ | | | | Favour module accessors symbols in rebind
| * SI-7928 Favour module accessors symbols in rebindJason Zaugg2013-10-231-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Refchecks tree transformer transforms a nested modules that overrides a method into a pair of symbols: the module itself, and an module accessor that matches the overridden symbol. [[syntax trees at end of typer]] // test1.scala package <empty> { abstract trait C2 extends scala.AnyRef { def O1: Any }; class C1 extends AnyRef with C2 { object O1 extends scala.AnyRef } } [[syntax trees at end of refchecks]] // test1.scala package <empty> { abstract trait C2 extends scala.AnyRef { def O1: Any }; class C1 extends AnyRef with C2 { object O1 extends scala.AnyRef @volatile <synthetic> private[this] var O1$module: C1.this.O1.type = _; <stable> def O1: C1.this.O1.type = { C1.this.O1$module = new C1.this.O1.type(); C1.this.O1$module } } } When constructing a TypeRef or SingleType with a prefix and and a symbol, the factory methods internally use `rebind` to see if the provided symbol should be replaced with an overriding symbol that is available in that prefix. Trying this out in the REPL is a bit misleading, because even if you change phase to `refchecks`, you won't get the desired results because the transform is not done in an InfoTransformer. scala> val O1 = typeOf[C1].decl(TermName("O1")) O1: $r.intp.global.Symbol = object O1 scala> typeRef(typeOf[C2], O1, Nil) res13: $r.intp.global.Type = C2#O1 scala> res13.asInstanceOf[TypeRef].sym.owner res14: $r.intp.global.Symbol = class C1 But debugging the test case, we get into `rebind` during an AsSeenFrom which is where we crashed when `suchThat` encountered the overloaded module and module accessor symbols: typeOf[OuterObject.Inner.type].memberType(symbolOf[InnerTrait.Collection]) ... singleTypeAsSeen(OuterTrait.this.Inner.type) val SingleType(pre, sym) = tp // pre = OuterTrait.this.type // sym = OuterTrait.Inner val pre1 = this(pre) // OuterObject.type singleType(pre1, sym) rebind(pre1, sym) // was crashing, now OuterObject.Inner } This commit excludes the module symbol from symbol lookup in the prefix in rebind.
* | Merge pull request #3059 from densh/pull/si-6840Jason Zaugg2013-10-231-1/+1
|\ \ | | | | | | SI-6840 fixes weird typing of quasiquote arguments
| * | SI-6840 fixes weird typing of quasiquote argumentsDen Shabalin2013-10-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously quasiquote arguments were type checked against Any which caused weird inference that made splicing of complex expressions unusable: val l1 = List(q"foo") val l2 = List(q"bar") q"f(..${l1 ++ l2})" // argument type checked as Any instead of List[Tree] This is fixed by forcing compiler to type check against type variable which itself isn't used in any other way.
* | | Merge pull request #3057 from xeno-by/topic/fancy-java-classesJason Zaugg2013-10-233-31/+29
|\ \ \ | |_|/ |/| | fixes handling of fancy nested classes in runtime reflection
| * | fixes handling of fancy nested classes in runtime reflectionEugene Burmako2013-10-193-31/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Replaces the `jclazz.isMemberClass` check for whether we have an inner/nested class with `jclazz.getEnclosingClass != null`, because there exist classes produced by javac (see the attached jar file and the test log) which have the following properties: * They are nested within a parent class * getEnclosingClass returns a non-null value * isMemberClass returns false Previously such classes were incorrectly treated as non-nested, were incorrectly put into an enclosing package rather than an enclosing class, and had their names trimmed in the process, leading to situations when a package has multiple declarations with the same name. This is now fixed. When changing the check, we need to be careful with interpretation of what Class.getEnclosingXXX methods return. If getEnclosingClass produces a non-null result, this doesn't mean that the class is inner or nested, because getEnclosingClass is also not null for local classes (the ones with getEnclosingMethod != null || getEnclosingConstructor != null). This is expressed in the order of pattern match clauses in `sOwner`. Now when the bug is fixed, I also revert b18a2f8798b2, restoring a very important integrity check in runtime reflection, which I had to disable a couple hours ago to fix a master breakage. More details at scala-internals: https://groups.google.com/forum/#!topic/scala-internals/hcnUFk75MgQ
* | | Merge pull request #3047 from xeno-by/topic/deprecateEugene Burmako2013-10-224-0/+36
|\ \ \ | |_|/ |/| | deprecates raw tree manipulation facilities in macros.Context
| * | deprecates raw tree manipulation facilities in macros.ContextEugene Burmako2013-10-184-0/+36
| | |
* | | Merge pull request #3007 from densh/pull/fresh-name-and-package-supportEugene Burmako2013-10-198-34/+142
|\ \ \ | |_|/ |/| | Add support for packages into quasiquotes and toolbox, improve handling of fresh names, unhardcode quasiquote expansion logic
| * | use concurrent hash map with atomic integersDen Shabalin2013-10-181-9/+5
| | | | | | | | | | | | | | | This should ensure that concurrent access to the fresh name creator is properly synchronized.
| * | re-wire fresh name creator to currentUnit.fresh at compile-timeDen Shabalin2013-10-183-1/+4
| | |
| * | use NameTransformer.encode for fresh name prefix sanitizationDen Shabalin2013-10-181-2/+2
| | |
| * | decrease duplication of fresh* function definitionsDen Shabalin2013-10-182-3/+7
| | | | | | | | | | | | | | | | | | | | | | | | This commit extracts out freshTermName and freshTypeName to the top-level with implicit fresh name creator argument. This will let to refactor out more methods out of tree builder into treegen that are dependent on fresh name generator. We also save quite a bit of boilerplate by not having to redefined fresh functions all over the place.
| * | move fresh name creator into scala.reflect.internal.utilDen Shabalin2013-10-182-10/+34
| | |
| * | rename selfdef into selfTypeDen Shabalin2013-10-182-27/+27
| | | | | | | | | | | | For sake of consistency with noSelfType.
| * | make q"f(..$xs)" deconstruction symmetrical to q"f[..$xs]"Den Shabalin2013-10-183-0/+17
| | |
| * | advanced fresh name reificationDen Shabalin2013-10-183-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During parsing some names are generated artificially using freshTermName & freshTypeName (e.g. `x$1`). Such names should be reified in a different way because they are assumed to be always fresh and non-overlapping with the environment. So `x$1` should reify down to equivalent of `freshTermName("x$")` rather than `TermName("x$1")`. But this is not enough. One name can be used more than once in a tree. E.g. `q"_ + 1"` desugars into `q"x$1 => x$1 + 1"`. So we need to ensure that every place where `x$1` is used gets the same fresh name. Hence the need for `withFreshTermName` that lets q"_ + 1" quasiquote desugare into equivalent of `withFreshTermName("x$") { freshx => q"$freshx => $freshx + 1" }`. For pattern quasiquotes it's a bit different. Due to the fact that end-result must be a pattern we need to represent fresh names as patterns too. A natural way to express that something is fresh is to represent it as a free variable (e.g. any name will do in that place). But due to possible use of the same name in multiple places we need to make sure that all such places have the same values by adding a sequence of guards to the pattern. Previously such names were reified naively and it could have caused name collision problems and inability to properly much on trees that contain such names.
| * | use regular macro expansion logic for unapply quasiquotesDen Shabalin2013-10-141-1/+1
| | | | | | | | | | | | | | | | | | | | | Previously due to limited support for expansion in apply position quasiquotes had to use a compiler hook for deconstruction. Now with recent changes in pattern matcher it's possible to remove that special case.
| * | SI-6841 SI-6657 add support for packages into quasiquotes and toolboxDen Shabalin2013-10-144-11/+57
| | | | | | | | | | | | | | | | | | In order to implement this a new parser entry point `parseStatsOrPackages` that augments current parseStats with ability to parse "package name { ... }" syntax.
* | | hotfix for runtime reflectionEugene Burmako2013-10-191-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Recent runtime reflection sync pull request, which among other things, introduced more restricted package completion rules, led to a nightmarish regression on java7, which prevented the entire scalac from starting up. This commit temporarily disables the introduced assert in order to hotfix runtime reflection. In the hours to come I'll be looking into the root of the problem, preparing a pull request that reinstates the assert, which indicates a bug in our code that's been there since 2.10.0-M3, and fixes the said bug. Details: https://groups.google.com/forum/#!topic/scala-internals/hcnUFk75MgQ
* | | pull request feedbackEugene Burmako2013-10-181-1/+2
| | | | | | | | | | | | https://github.com/scala/scala/pull/3029
* | | makes all locks and tlses private and lazyEugene Burmako2013-10-182-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | We do need lazy to be robust, because initialization sequence might trigger synced operations in unexpected order, leading to NPE's. Even if this is optimizable by removing some of the lazies or by carefully reordering cake layers, there's no guarantee that all this effort won't break after another reflection refactoring.
* | | need to synchronize Symbols.recursionTableEugene Burmako2013-10-183-1/+9
| | | | | | | | | | | | Fixes this glaring omission of synchronization for a core part of Symbol.info.
* | | replaces locks over numbers with AtomicIntegersEugene Burmako2013-10-183-15/+10
| | | | | | | | | | | | This is another optimization we discussed with Roland.
* | | thread locals instead of locks for vars in Types.scalaEugene Burmako2013-10-189-106/+148
| | | | | | | | | | | | | | | | | | | | | | | | This is one of the changes suggested by Roland in order to reduce contention caused by reflection GIL. Locks optimized away here are indirectly used for such fundamental operations as subtyping tests, so the optimization looks quite important.
* | | removes the assertion in missingHookEugene Burmako2013-10-181-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 pendingVolatilesEugene Burmako2013-10-183-5/+3
| | | | | | | | | | | | | | | 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-10-181-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-10-184-65/+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. Of those only #3 is dangerous and needs protection, which is what this commit does.
* | | SI-6240 introduces GIL to Scala reflectionEugene Burmako2013-10-1810-111/+226
| | | | | | | | | | | | | | | | | | | | | 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.
* | | eagerly initializes lazy vals and objects in runtime reflectionJason Zaugg2013-10-184-11/+497
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code to do so is curated with the help of a generator. Because this needs to inspect code post-typer, the code generator is run during partest as a code-validator. We could concievably do the same with a macro, but this approach might be a better starting point which macros continue to stabilize. Removes Definitions.AnyRefModule and an already deprecated alias, as these have been throwing exceptions for more than a year since 6bb5975289. They used to be used by AnyRef specialization.
* | | cleans up initialization of runtime reflectionEugene Burmako2013-10-188-34/+146
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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). And then it worked, but stopped working half a year later when Jason and I came to revisit this old pull request. The final twist was pre-initializing ObjectClass, because it's a dependency of AnyRefClass, which is a critical dependency of ScalaPackageClass (full information can be found in comments).
* | | reflection no longer uses enteringPhase and friendsEugene Burmako2013-10-185-28/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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` (only in SynchronizedSymbols, not in normal Symbols) again due to those methods being very performance-sensitive.
* | | synchronizes symbolsEugene Burmako2013-10-183-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.
* | | moves Symbol#SymbolKind to SymbolsEugene Burmako2013-10-181-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 #3045 from retronym/ticket/7688-4Jason Zaugg2013-10-181-4/+3
|\ \ | | | | | | Fix AsSeenFrom of ThisType from TypeVar prefix
| * | SI-7688 Fix AsSeenFrom of ThisType from TypeVar prefixJason Zaugg2013-10-171-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Restores behaviour for the AsSeenFrom before the refactoring in b457b6c477. This commit uniformly considered that a `TypeVar` prefix should not `matchesPrefixAndClass`; a condition that formerly was only applied if the type being viewed was a `TypeRef`. This condition was originally added in cc9e8eda3364d as a backstop for pos/t2797.scala. This commit leaves that backstop in place where it was, although it expresses it more directly by checking if `pre baseType clazz` is `NoType`, which was the case that cropped up in SI-2797: scala> type T = bc._1.type forSome { val bc: (AnyRef, AnyRef) } warning: there were 1 feature warning(s); re-run with -feature for details defined type alias T scala> val et = typeOf[T].dealias.asInstanceOf[ExistentialType] et: $r.intp.global.ExistentialType = bc._1.type forSome { val bc: (AnyRef, AnyRef) } scala> et.withTypeVars( { x => | println(x.prefix.typeSymbol) | println(x.prefix.typeSymbol.isSubClass(typeOf[Tuple2[_, _]].typeSymbol)) | println(x.prefix.baseType(typeOf[Tuple2[_, _]].typeSymbol)) | true | } , reflect.internal.Depth(0)) type bc.type true <notype> res98: Boolean = true
* | | Merge pull request #3033 from paulp/pr/pickler-reduxGrzegorz Kossakowski2013-10-1612-447/+453
|\ \ \ | | | | | | | | Traverser and Pickler improvements.