summaryrefslogtreecommitdiff
path: root/test/files/run
Commit message (Collapse)AuthorAgeFilesLines
* adds Context.enclosingOwnerEugene Burmako2014-02-142-8/+16
| | | | | | | | | | | | | | | | | | | | As per discussion at https://groups.google.com/forum/#!topic/scala-internals/nf_ooEBn6-k, this commit introduces the new c.enclosingOwner API that is going to serve two purposes: 1) provide a better controlled alternative to c.enclosingTree, 2) enable low-level tinkering with owner chains without having to cast to compiler internals. This solution is not ideal, because: 1) symbols are much more than I would like to expose about enclosing lexical contexts (after the aforementioned discussion I’m no longer completely sure whether exposing nothing is the right thing to do, but exposing symbol completers is definitely something that should be avoided), 2) we shouldn’t have to do that low-level stuff in the first place. However, let’s face the facts. This change represents both an improvement over the state of the art wrt #1 and a long-awaited capability wrt #2. I think this pretty much warrants its place in trunk in the spirit of gradual, evolutionary development of reflection API.
* establishes scala.reflect.api#internalEugene Burmako2014-02-1424-43/+61
| | | | | | | | | | | | | | | | | | | | | | | | | Reflection API exhibits a tension inherent to experimental things: on the one hand we want it to grow into a beautiful and robust API, but on the other hand we have to deal with immaturity of underlying mechanisms by providing not very pretty solutions to enable important use cases. In Scala 2.10, which was our first stab at reflection API, we didn't have a systematic approach to dealing with this tension, sometimes exposing too much of internals (e.g. Symbol.deSkolemize) and sometimes exposing too little (e.g. there's still no facility to change owners, to do typing transformations, etc). This resulted in certain confusion with some internal APIs living among public ones, scaring the newcomers, and some internal APIs only available via casting, which requires intimate knowledge of the compiler and breaks compatibility guarantees. This led to creation of the `internal` API module for the reflection API, which provides advanced APIs necessary for macros that push boundaries of the state of the art, clearly demarcating them from the more or less straightforward rest and providing compatibility guarantees on par with the rest of the reflection API. This commit does break source compatibility with reflection API in 2.10, but the next commit is going to introduce a strategy of dealing with that.
* deprecates api#Name.decoded and api#Name.encodedEugene Burmako2014-02-141-1/+1
| | | | | | | | | | | Presence of both decoded/encoded and decodedName/encodedName has always baffled me, as one of those method groups is clearly redundant, and this pull request presents a great opportunity to address this by deprecating one of the groups. After some deliberation, I’ve chosen decoded/encoded as the deprecation target, because its derivation from decodedName/encodedName is easier than the other way around.
* deprecates String => Name implicit conversionsEugene Burmako2014-02-148-14/+14
| | | | | | | Given that in 2.11 we have upgraded our name construction facility from `newTxxxName` to `TxxxName`, I think it’s time we retire these implicit conversions, as they no longer save keystrokes, but continue to present ambient danger associated with implicit conversions.
* SI-6732 deprecates internal#Symbol.isPackageEugene Burmako2014-02-144-16/+32
| | | | | | | | This is the first step in disentangling api#Symbol.isPackage, which is supposed to return false for package classes, and internal#Symbol.isPackage, which has traditionally being used as a synonym for hasPackageFlag and hence returned true for package classes (unlike isModule which is false for module classes).
* Merge remote-tracking branch 'origin/master' into topic/palladium0Eugene Burmako2014-02-1414-21/+187
|\
| * Merge pull request #3531 from Ichoran/issue/8188Adriaan Moors2014-02-141-0/+25
| |\ | | | | | | SI-8188 NPE during deserialization of TrieMap
| | * SI-8188 NPE during deserialization of TrieMapRex Kerr2014-02-141-0/+25
| | | | | | | | | | | | The writer was using the constructor headf and ef instead of the internal vars hashingobj and equalityobj.
| * | Merge pull request #3530 from Ichoran/issue/6632Adriaan Moors2014-02-142-18/+13
| |\ \ | | | | | | | | SI-6632 ListBuffer's updated accepts negative positions
| | * | SI-6632 ListBuffer's updated accepts negative positionsRex Kerr2014-02-132-18/+13
| | |/ | | | | | | | | | | | | | | | Changed the behavior in SeqLike.updated (which would silently accept negatives and throw on empty.tail) to throw IndexOutOfBoundException. Updated tests to verify the behavior in ListBuffer. Everything else SeqLike will come along for the ride.
| * | Merge pull request #3525 from adriaanm/t8177bAdriaan Moors2014-02-144-3/+10
| |\ \ | | | | | | | | SI-8177 specializeSym must use memberInfo on high side
| | * | SI-8177 tidy up in type reificationEugene Burmako2014-02-144-3/+10
| | | |
| | * | SI-8177 specializeSym must use memberInfo on high sideAdriaan Moors2014-02-131-1/+1
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When determining whether member `symLo` of `tpLo` has a stronger type than member `symHi` of `tpHi`, should we use memberType or memberInfo? Well, memberType transforms (using `asSeenFrom`) `sym.tpe`, whereas memberInfo performs the same transform on `sym.info`. For term symbols, this ends up being the same thing (`sym.tpe == sym.info`). For type symbols, however, the `.info` of an abstract type member is defined by its bounds, whereas its `.tpe` is a `TypeRef` to that type symbol, so that `sym.tpe <:< sym.info`, but not the other way around. Thus, for the strongest (correct) result, we should use `memberType` on the low side. On the high side, we should use the result appropriate for the right side of the `<:<` above (`memberInfo`). I also optimized the method a little bit by avoiding calling memberType if the symbol on the high side isn't eligble (e.g., it's a class). PS: I had to add a workaround to reifyType, because we now dealias a little less eagerly, which means a type selection on refinement class symbols makes it to reify this broke the t8104 tests. I also had to update the run/t6992 test, which should now test the right thing. Tests should be commented and/or use sensible names. What is it testing? What is the expected outcome? We should not be left guessing.
| * | Merge pull request #3376 from Ichoran/issue/8153Adriaan Moors2014-02-142-0/+15
| |\ \ | | | | | | | | SI-8153 Mutation is hard, let's go shopping with an empty list
| | * | SI-8153 Mutation is hard, let's go shopping with an empty listRex Kerr2014-02-122-0/+15
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | Changed the implementation of iterator to be more robust to mutation of the underlying ListBuffer. Added a test to make sure bug is gone. Fixed an "unsafe" usage of ListBuffer.iterator in the compiler, and added a comment explaining the (new) policy for iterating over a changing ListBuffer. The compiler now uses a synchronized-wrapped ArrayBuffer instead of ListBuffer, as that makes the (custom) units Iterator more natural to write (and avoids O(n) lookups).
| * / SI-8280 regression in implicit selection.Paul Phillips2014-02-132-0/+91
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 2fa2db7840 I fixed a bug where applicable implicit conversions would not be found for numeric types if one introduced any aliasing or singleton types, for the usual reasons involving the absence of uniform type normalization. See pos/t7228 for examples - that test case has 20 errors in 2.10.3 but compiles in master. An unintended side effect was making implicit search less oblivious. It turns out that in so doing I had created ambiguity where there was none before. Not because it was any more ambiguous, but because the compiler now had the wits to notice the ambiguity at an earlier time. The fix for this is not intuitive. The way the internal logic is, we need to keep the wool over implicit search's eyes, which leads to those unrecognized types being passed to adapt, where they are recognized and weak subtyping suffices to be more specific. It is sufficient for SI-7228 that weak subtyping be done correctly - the other change, which is reverted here, was exposing the type arguments of Function1 when a view exists as a subtype of Function1. It is also possible this could be remedied by calling weak_<:< somewhere which is presently <:<, but I don't know where and it has a far greater chance of affecting something else than does this, which is a straight reversion of a post-2.10.3 change.
| * SI-8177 refine embeddedSymbolsAdriaan Moors2014-02-121-0/+20
| | | | | | | | | | | | | | | | | | We look for any prefix that has a refinement class for a type symbol. This includes ThisTypes, which were not considered before. pos/t8177g.scala, neg/t0764*scala now compile, as they should Additional test cases contributed by Jason & Paul.
| * SI-261 private vals in traits depend on composition orderAdriaan Moors2014-02-112-0/+13
| | | | | | | | | | | | | | Fix for SI-7475 in #3440 took care of this one. I nixed the old (redundant) test cases and replaced by a single run/ test, which didn't compile until.
* | SI-6814 adds typechecker modes to c.typecheckEugene Burmako2014-02-143-0/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | As per multiple user requests, this commit introduces a shortcut to typecheck trees under multiple different modes: terms (EXPRmode, was exposed in Scala 2.10) and types (TYPEmode). Looking into the rest of a dozen of internal typechecker modes, to the best of my knowledge, I can’t find other modes that we could expose. FUNmode is useful, but very situational. PATTERNmode is useful, but also situational, because we don’t expand macros inside patterns except for whitebox extractor macros. The rest (e.g. POLYmode or TAPPmode) are too low-level.
* | SI-8118 simplifies Annotation down to a plain TreeEugene Burmako2014-02-148-15/+35
| | | | | | | | | | | | | | | | | | | | | | As per https://groups.google.com/forum/#!topic/scala-internals/8v2UL-LR9yY, annotations don’t have to be represented as AnnotationInfos and can be reduced to plain Trees. Due to compatibility reasons and because of the limitations of the cake pattern used in implementing current version of Reflection, we can’t just say `type Annotation = Tree`, however what we can definitely do is to deprecate all the methods on Annotation and expose `tree: Tree` instead.
* | sane semantics for Symbols.companionSymbolEugene Burmako2014-02-144-6/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While playing with tests for Type.companionType, I figured out that companionSymbol isn’t what it seems to be: scala> ScalaPackage.companionSymbol res5: $r.intp.global.Symbol = <none> scala> ScalaPackageClass.companionSymbol res6: $r.intp.global.Symbol = package scala Or even funnier observation: scala> class C; object C defined class C defined object C scala> val classC = typeOf[C].typeSymbol classC: $r.intp.global.Symbol = class C scala> val moduleC = classC.companionSymbol moduleC: $r.intp.global.Symbol = object C scala> classC.companionSymbol == moduleC res0: Boolean = true scala> moduleC.companionSymbol == classC res1: Boolean = true scala> moduleC.moduleClass.companionSymbol == moduleC res2: Boolean = true Of course, I rushed to clean this up, so that `companionSymbol` only returns something other than NoSymbol if the target has a companion in the common sense, not wrt the internal “class with the same name in the same package” convention of scalac, and that `companionSymbol` for module classes is a class, not a source module. Unfortunately it’s not that easy, because api.Symbol#companionSymbol has the same name as internal.Symbol#companionSymbol, so we can’t change the behavior of the former without changing the behavior of the latter. Therefore I deprecated api.Symbol#companionSymbol and introduced a replacement called api.Symbol#companion with sane semantics.
* | adds Type.companionTypeEugene Burmako2014-02-142-0/+34
| | | | | | | | | | | | Introduces a dedicated facility to go from a type to a type of its companion. Previously we had to do something really horrible for that, something like: tp.typeSymbol.companionSymbol.typeSignature.
* | splits Type.normalize into dealias and etaExpandEugene Burmako2014-02-142-0/+22
| | | | | | | | | | normalize is a highly overloaded name and it also conflates two distinct operators, so how about we give our users self-explaning atomic tools instead.
* | adds showDeclaration(sym: Symbol): StringEugene Burmako2014-02-145-15/+111
| | | | | | | | | | | | As per Paul’s request, this commit exposes Symbol.defString, although in a different way to ensure consistency with our other prettyprinting facilities provided in the reflection API.
* | SI-8194 adds Universe.symbolOf[T]Eugene Burmako2014-02-142-0/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A very frequent use for a result of typeOf is obtaining an underlying type symbol. Another thing that comes up occasionally at stack overflow is a request to add facilities for reification of symbols. This naturally suggests that our reflection API would benefit from a method called symbolOf that can take a term or type argument and return an underlying symbol. While an API to extract a term symbol from an expression needs some time to be designed and then implemented robustly (we don’t have untyped macros so we’ll have to account for various desugarings), meaning that we probably won’t have time for that in 2.11, a type symbol extractor seems to be a very low-hanging fruit.
* | SI-6484 adds Universe.typeOf[T](x: T)Eugene Burmako2014-02-144-0/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a nice addition to Universe.typeOf[T], quite frequently useful for inspecting ad-hoc types. As promised by https://github.com/scala/scala/pull/1741, which represented my previous stab at adding this API, I ran into problems when trying to introduce the API naively. def typeOf[T](implicit ttag: TypeTag[T]): Type def typeOf[T: TypeTag](x: T): Type The first problem came from the fact that even though they don't look ambiguous, under certain circumstances, the couple of typeOf overloads can become ambiguous. Concretely, ambiguity happens when T <: TypeTag[T], which makes the compiler uncapable to choose an overload to typecheck `typeOf[T](<materialized>: TypeTag[T])`. Luckily, defining x as a by-name parameter fixes the problem. def typeOf[T](implicit ttag: TypeTag[T]): Type def typeOf[T: TypeTag](x: => T): Type The second problem manifested itself in reification of snippets that contained calls to typeOf. Apparently, materialized tags get rolled back by reify as products of macro expansion, becoming replaced with `implicitly[TypeTag[T]]`. Afterwards, subsequent rollback of TypeTree's strips the replacement of its type argument, producing bare `implicitly`. Back then when typeOf wasn't overloaded, this abomination typechecked and worked correctly, but now, due to some weird reason, it stopped. I have worked around this by performing the rollback on a larger scale - instead of hunting down materialized tags, this commit detects calls to typeOf and removes their implicit argument lists altogether.
* | SI-8192 adds ClassSymbol.isPrimaryConstructorEugene Burmako2014-02-145-2/+129
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Exposes a popular code pattern in macros as a dedicated reflection API. This simple commit, however, ended up being not so simple, as it often happens with our compiler. When writing a test for the new API, I realized that our (pre-existing) MethodSymbol.isPrimaryConstructor API returns nonsensical results for implementation artifacts (trait mixin ctors, module class ctors). What’s even more funny is that according to our reflection internals, even Java classes have primary constructors. Well, that’s not surprising, because `primaryConstructor` is just `decl(ctorName).alternatives.head`. Good thing that package classes don’t have constructors or that would elevate the situation to three fries short of a happy meal. At the moment, I’m too scared to fiddle with internal#Symbol.primaryConstructor, because that could easily break someone right before RC1, so I simply documented the findings in SI-8193 and postponed the actual work, except for one thing - isJavaDefined symbols no longer have primary constructors.
* | SI-6379 adds MethodSymbol.exceptionEugene Burmako2014-02-143-0/+62
| | | | | | | | | | | | Following Simon’s request, this commit introduces a dedicated API that can be used to acquire the list of exceptions thrown by a method, abstracting away from whether it’s a Java or a Scala artifact.
* | additional class tags for reflection APIEugene Burmako2014-02-142-0/+18
| | | | | | | | | | | | | | | | | | Introduces a test that iterates all abstract types in reflection API and makes sure that every one of them has an associated class tag. After being introduced, the test has immediately failed exposing the lack of tags for TreeCopier, Mirror and RuntimeClass, which has been subsequently fixed in this commit.
* | SI-8190 erasure identities for types in reflection APIEugene Burmako2014-02-144-2/+400
| | | | | | | | | | | | | | | | | | | | | | Makes sure that almost every abstract type declared in reflection API erases to a unique class, so that they can be adequately used for method overloading to the same extent that tags allow them to be used in pattern matching. The only two exceptions from this rule are the types whose implementations we do not control: FlagSet that is implemented as Long and RuntimeClass that is implemented as java.lang.Class[_].
* | SI-6733 LOCAL, isLocal, and private[this]Eugene Burmako2014-02-122-0/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Due to an unfortunate name collision, internal.Symbols#Symbol.isLocal means something different from Flag.LOCAL. Therefore api.Symbols#Symbol.isLocal was directly violating its documentation. Since we can’t give api#isLocal an implementation different from internal#isLocal, we have to rename, and for that occasion I have come up with names api#isPrivateThis and api#isProtectedThis, which in my opinion suits the public API better than internal#isPrivateLocal and internal#isProtectedLocal. Given the extraordinary circumstances of having no way for api#isLocal to work correctly, I’m forced to remove api#isLocal without a deprecation notice, exercising our right to break experimental APIs, something that we have never done before for reflection or macros. This is sad.
* | SI-7533 Adds Symbol.isAbstractEugene Burmako2014-02-122-0/+68
|/ | | | | | | Amazingly enough, we've missed the fact that non-type symbols can also be abstract. Having been enlightened by this, I'm exposing isDeferred and merging it along with isAbstractType and isAbstractClass into the unified Symbol.isAbstract method.
* SI-7475 Private members are not inheritableJason Zaugg2014-02-104-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out `findMembers` has been a bit sloppy in recent years and has returned private members from *anywhere* up the base class sequence. Access checks usually pick up the slack and eliminate the unwanted privates. But, in concert with the "concrete beats abstract" rule in `findMember`, the following mishap appeared: scala> :paste // Entering paste mode (ctrl-D to finish) trait T { def a: Int } trait B { private def a: Int = 0 } trait C extends T with B { a } // Exiting paste mode, now interpreting. <console>:9: error: method a in trait B cannot be accessed in C trait C extends T with B { a } ^ I noticed this when compiling Akka against JDK 8; a new private method in the bowels of the JDK was enough to break the build! It turns out that some finesse in needed to interpret SLS 5.2: > The private modifier can be used with any definition or declaration > in a template. They are not inherited by subclasses [...] So, can we simply exclude privates from all but the first base class? No, as that might be a refinement class! The following must be allowed: trait A { private def foo = 0; trait T { self: A => this.foo } } This commit: - tracks when the walk up the base class sequence passes the first non-refinement class, and excludes private members - ... except, if we are at a direct parent of a refinement class itself - Makes a corresponding change to OverridingPairs, to only consider private members if they are owned by the `base` Symbol under consideration. We don't need to deal with the subtleties of refinements there as that code is only used for bona-fide classes. - replaces use of `hasTransOwner` when considering whether a private[this] symbol is a member. The last condition was not grounded in the spec at all. The change is visible in cases like: // Old scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:7: error: value x in trait A cannot be accessed in A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ // New scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:8: error: value x is not a member of A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ Furthermore, we no longer give a `private[this]` member a free pass if it is sourced from the very first base class. trait Cake extends Slice { private[this] val bippy = () } trait Slice { self: Cake => bippy // BCS: Cake, Slice, AnyRef, Any } The different handling between `private` and `private[this]` still seems a bit dubious. The spec says: > An different form of qualification is private[this]. A member M > marked with this modifier can be accessed only from within the > object in which it is defined. That is, a selection p.M is only > legal if the prefix is this or O.this, for some class O enclosing > the reference. In addition, the restrictions for unqualified > private apply. This sounds like a question of access, not membership. If so, we should admit `private[this]` members from parents of refined types in `FindMember`. AFAICT, not too much rests on the distinction: do we get a "no such member", or "member foo inaccessible" error? I welcome scrutinee of the checkfile of `neg/t7475f.scala` to help put this last piece into the puzzle. One more thing: findMember does not have *any* code the corresponds to the last sentence of: > SLS 5.2 The modifier can be qualified with an identifier C > (e.g. private[C]) that must denote a class or package enclosing > the definition. Members labeled with such a modifier are accessible > respectively only from code inside the package C or only from code > inside the class C and its companion module (§5.4). > Such members are also inherited only from templates inside C. When I showed Martin this, he suggested it was an error in the spec, and we should leave the access checking to callers of that inherited qualified-private member.
* SI-7475 findMember and findMembers: estranged no moreJason Zaugg2014-02-101-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Swathes of important logic are duplicated between `findMember` and `findMembers` after they separated on grounds of irreconcilable differences about how fast they should run: d905558 Variation #10 to optimze findMember fcb0c01 Attempt #9 to opimize findMember. 71d2ceb Attempt #8 to opimize findMember. 77e5692 Attempty #7 to optimize findMember 275115e Fixing problem that caused fingerprints to fail in e94252e Attemmpt #6 to optimize findMember 73e61b8 Attempt #5 to optimize findMember. 04f0b65 Attempt #4 to optimize findMember 0e3c70f Attempt #3 to optimize findMember 41f4497 Attempt #2 to optimize findMember 1a73aa0 Attempt #1 to optimize findMember This didn't actually bear fruit, and the intervening years have seen the implementations drift. Now is the time to reunite them under the banner of `FindMemberBase`. Each has a separate subclass to customise the behaviour. This is primarily used by `findMember` to cache member types and to assemble the resulting list of symbols in an low-allocation manner. While there I have introduced some polymorphic calls, the call sites are only bi-morphic, and our typical pattern of compilation involves far more `findMember` calls, so I expect that JIT will keep the virtual call cost to an absolute minimum. Test results have been updated now that `findMembers` correctly excludes constructors and doesn't inherit privates. Coming up next: we can actually fix SI-7475!
* SI-8129 Make Object#== override Any#==Jason Zaugg2014-02-101-4/+0
| | | | | | | | | | | | | | | | | | | | And the same for != If we tried to declare these signatures in non-fictional classes, we would be chastised about collapsing into the "same signature after erasure". This will have an influence of typing, as the typechecking of arguments is sensitive to overloading: if multiple variants are feasible, the argument will be typechecked with a wildcard expected type. So people inspecting the types of the arguments to `==` before this change might have seen an interesting type for `if (true) x else y`, but now the `If` will have type `Any`, as we don't need to calculate the LUB. I've left a TODO to note that we should really make `Any#{==, !=}` non-final and include a final override in `AnyVal`. But I don't think that is particularly urgent.
* Merge pull request #3480 from paulp/pr/publicize-abstract-starGrzegorz Kossakowski2014-02-102-0/+181
|\ | | | | Make the Abstract* classes public.
| * SI-6948 Make the Abstract* classes public.Paul Phillips2014-02-062-0/+181
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Several weaknesses in the implementation converge and force multiply. 1) Type constructor inference is not persistent. During implicit search it will give up after the first seen parent even if some deeper base type (even another direct parent) would satisfy the search. 2) Type inference is not aware of access restrictions. Inferred types are calculated with disregard for whether the inferred type is visible at the point of inference. That means that package-private types - which may be private for any number of good reasons, such as not wanting them to appear in bytecode thus creating binary compatibility obligations - are not private. There is no such thing as a qualified private type. package p { trait PublicInterface[T] { def foo(): Int } private[p] trait ImplementationOnly[T] extends PublicInterface[T] { def foo(): Int = 1 } class PublicClass extends ImplementationOnly[PublicClass] } package q { object Test { def f[A, CC[X]](xs: CC[A]): CC[A] = xs def g = f(new p.PublicClass) // inferred type: p.ImplementationOnly[p.PublicClass] def h = g.foo() // Bytecode contains: // public p.ImplementationOnly<p.PublicClass> g(); // public int h(); // 0: aload_0 // 1: invokevirtual #30 // Method g:()Lp/ImplementationOnly; // 4: invokeinterface #33, 1 // InterfaceMethod p/ImplementationOnly.foo:()I // 9: ireturn } } 3) The trait encoding leads to a proliferation of forwarder methods, so much so that 1.5 Mb of bytecode was taken off of the standard library size by creating abstract classes which act as central mixin points so that leaf classes can inherit some methods the old fashioned way rather than each receiving their own copy of every trait defined method. This was done for 2.10 through the creation of the Abstract* classes, all of which were given reduced visibility to keep them out of the API. private[collection] class AbstractSeq extends ... This achieved its intended goal very nicely, but also some unintended ones. In combination with 1) above: scala> val rand = new scala.util.Random() rand: scala.util.Random = scala.util.Random@7f85a53b // this works scala> rand.shuffle(0 to 5) res1: scala.collection.immutable.IndexedSeq[Int] = Vector(4, 0, 1, 2, 5, 3) // and this doesn't! good luck reasoning that one out scala> rand.shuffle(0 until 5) <console>:9: error: Cannot construct a collection of type scala.collection.AbstractSeq[Int] with elements of type Int based on a collection of type scala.collection.AbstractSeq[Int]. rand.shuffle(0 until 5) ^ // Somewhat comically, in scala 2.9 it was flipped: to failed (differently), until worked. scala> scala.util.Random.shuffle(0 to 5) <console>:8: error: type mismatch; found : scala.collection.immutable.Range.Inclusive required: ?CC[?T] scala> scala.util.Random.shuffle(0 until 5) res2: scala.collection.immutable.IndexedSeq[Int] = Vector(4, 3, 1, 2, 0) In combination with 2) above: scala> def f[A, CC[X]](xs: CC[A]): CC[A] = xs f: [A, CC[X]](xs: CC[A])CC[A] scala> var x = f(1 until 10) x: scala.collection.AbstractSeq[Int] = Range(1, 2, 3, 4, 5, 6, 7, 8, 9) // It has inferred a type for our value which it will not allow us to use or even to reference. scala> var y: scala.collection.AbstractSeq[Int] = x <console>:10: error: class AbstractSeq in package collection cannot be accessed in package collection var y: scala.collection.AbstractSeq[Int] = x ^ // This one is a straight regression - in scala 2.9, scala> var x = f(1 until 10) x: scala.collection.immutable.IndexedSeq[Int] = Range(1, 2, 3, 4, 5, 6, 7, 8, 9) Since 1) and 2) are essentially unfixable - at least by me - I propose to ameliorate these regressions by attacking the symptoms at the leaves. That means making all the Abstract* classes public - keeping in mind that they must already be assumed to be in the binary compatibility footprint, since they have been leaking throughout their existence. This only impacts the inference of inaccessible collections types - it doesn't help with the more serious issue with type inference.
* | Merge pull request #3428 from retronym/ticket/6260Grzegorz Kossakowski2014-02-105-0/+39
|\ \ | | | | | | SI-6260 Avoid double-def error with lambdas over value classes
| * | SI-6260 Avoid double-def error with lambdas over value classesJason Zaugg2014-02-105-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Post-erasure of value classs in method signatures to the underlying type wreaks havoc when the erased signature overlaps with the generic signature from an overriden method. There just isn't room for both. But we *really* need both; callers to the interface method will be passing boxed values that the bridge needs to unbox and pass to the specific method that accepts unboxed values. This most commonly turns up with value classes that erase to Object that are used as the parameter or the return type of an anonymous function. This was thought to have been intractable, unless we chose a different name for the unboxed, specific method in the subclass. But that sounds like a big task that would require call-site rewriting, ala specialization. But there is an important special case in which we don't need to rewrite call sites. If the class defining the method is anonymous, there is actually no need for the unboxed method; it will *only* ever be called via the generic method. I came to this realisation when looking at how Java 8 lambdas are handled. I was expecting bridge methods, but found none. The lambda body is placed directly in a method exactly matching the generic signature. This commit detects the clash between bridge and target, and recovers for anonymous classes by mangling the name of the target method's symbol. This is used as the bytecode name. The generic bridge forward to that, as before, with the requisite box/unbox operations.
* | | Merge pull request #3406 from xeno-by/ticket/7570Jason Zaugg2014-02-106-0/+45
|\ \ \ | | | | | | | | SI-7570 top-level codegen for toolboxes
| * | | SI-7570 top-level codegen for toolboxesEugene Burmako2014-01-246-0/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Provides a way to inject top-level classes, traits and modules into toolbox universes. Previously that was impossible, because compile and eval both wrap their arguments into an enclosing method of a synthetic module, which makes it impossible to later on refer to any definitions from the outside.
* | | | Merge pull request #3409 from xeno-by/ticket/6411Jason Zaugg2014-02-107-1/+213
|\ \ \ \ | | | | | | | | | | SI-6411 SI-7328 value class fixes for runtime reflection
| * | | | SI-7328 FieldMirrors now support value classesEugene Burmako2014-01-253-1/+23
| | | | |
| * | | | unifies method and constructor handling in JavaMirrorsEugene Burmako2014-01-255-1/+14
| | | | | | | | | | | | | | | | | | | | | | | | | This automatically brings performance fixes and correct handling of values class / by-name params into the constructor land.
| * | | | updates the test for by-name value class parametersEugene Burmako2014-01-242-0/+24
| | | | |
| * | | | SI-6411 reflection is now aware of posterasureEugene Burmako2014-01-242-0/+153
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The `transformedType` method, which is used to bring Scala types to Java world, was written in pre-valueclass times. Therefore, this method only called transforms from erasure, uncurry and refChecks. Now runtime reflection becomes aware of posterasure and as a consequence methods, which have value classes in their signatures, can be called without having to wrap them in catch-a-crash clause. Another facet to this fix was the realization that value classes need to be unwrapped, e.g. C(2) needs to be transformed to just 2, when they are used naked in method signatures (i.e. `c` in `def foo(c: C)` needs to be unwrapped, whereas `cs: List[C]`, `cs: C*` and even `cs: Array[C]` do not).
* | | | Merge pull request #3433 from rjolly/si-7933Adriaan Moors2014-02-094-0/+23
|\ \ \ \ | | | | | | | | | | SI-7933 REPL javax.script eval is cached result
| * | | | SI-7933 REPL javax.script eval is cached resultRaphael Jolly2014-01-314-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The problem is that the repl underneath the script engine evaluates input to val res0..resN, so it is a one shot operation. To allow repetition, compile(script) now returns a CompiledScript object whose eval method can be called any number of times.
* | | | | Merge pull request #3484 from retronym/ticket/8237Adriaan Moors2014-02-091-1/+1
|\ \ \ \ \ | | | | | | | | | | | | SI-8237 Avoid cyclic constraints when inferring hk type args
| * | | | | SI-8237 Avoid cyclic constraints when inferring hk type argsJason Zaugg2014-02-091-1/+1
| | |_|_|/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An `AppliedTypeVars` spawned from `HKTypeVar#applyArgs` (necessarily) shares the same `TypeConstraints`. But, we can have multiple ATVs based on a single HKTV floating around during inference, and they can appear on both sides of type relations. An example of this is traced out in the enclosed test. This commit avoids registering upper/lower bound constraints when this is detected. In the enclosed test, we end up with an empty set of constraints for `?E`, which results in inference of Nothing, which is what we expect. I have also improved the printing of ATVs (to include the args) and sharpened the log message when `solve` leaves type variables instantiated to `NoType`, rather than some other type that doesn't conform to the bounds. Both of these changes helped me to get to the bottom of this ticket. The improved `ATV#toString` shows up in some updated checkfiles. The reported test has quite a checkered history: - in 2.10.0 it worked, but more by good luck than good planning - after the fix for SI-7226 / 221f52757aa6, it started crashing - from 3bd897ba0054f (a merge from 2.10.x just before 2.11.0-M1) we started getting a type inference failure, rather than a crash. "no type parameters for method exists [...] because cyclic instantiation". - It still crashes in `isGround` in 2.10.3.