summaryrefslogtreecommitdiff
path: root/src/reflect
Commit message (Collapse)AuthorAgeFilesLines
...
| * | | Cache name for dummy argument used in implicit searchJason Zaugg2015-02-171-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | This avoids a minor inefficiency of interning the name on each implicit candidate. Instead, we follow the usual practice and use a pre-baked name from `StdNames`.
* | | | SI-9157 Avoid exponential blowup with chained type projectionsJason Zaugg2015-02-181-5/+5
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Calling `findMember` in the enclosed test was calling into `NonClassTypeRef#relativeInfo` an exponentially-increasing number of times, with respect to the length of the chained type projections. The numbers of calls increased as: 26, 326, 3336, 33446, 334556. Can any pattern spotters in the crowd that can identify the sequence? (I can't.) Tracing the calls saw we were computing the same `memberType` repeatedly. This part of the method was not guarded by the cache. I have changed the method to use the standard idiom of using the current period for cache invalidation. The enclosed test now compiles promptly, rather than in geological time.
* | | Merge pull request #4296 from lrytz/t9105Adriaan Moors2015-02-132-1/+23
|\ \ \ | | | | | | | | Fixes and tests for InnerClass / EnclsoingMethod classfile attributes
| * | | Fix InnerClass / EnclosingMethod for closures nested in value classesLukas Rytz2015-02-071-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Members of value classes are moved over to the companion object early. This change ensures that closure classes nested in value classes appear that way to Java reflection. This commit also changes the EnclosingMethod attribute for classes (and anonymous functions) nested in anonymous function bodies. Before, the enclosing method was in some cases the function's apply method. Not always though: () => { class C ... val a = { class D ...} } The class C used to be nested in the function's apply method, but not D, because the value definition for a was lifted out of the apply. After this commit, we uniformly set the enclosing method of classes nested in function bodies to `null`. This is consistent with the source-level view of the code. Note that under delambdafy:method, closures never appear as enclosing classes (this didn't change in this commit).
| * | | SI-9105 Fix EnclosingMethod for classes defined in lambdasLukas Rytz2015-02-071-0/+17
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change fixes both GenASM and GenBCode, except for the change to renaming in LamdaLift mentioned below. The reason for an inconsistent EnclosingMethod attribute was the symbol owner chain. Initially, closure class symbols don't exist, they are only created in UnCurry (delambdafy:inline). So walking the originalOwner of a definition does not yield closure classes. The commit also fixes uses of isAnonymousClass, isAnonymousFunction and isDelambdafyFunction in two ways: 1. by phase-travelling to an early phase. after flatten, the name includes the name of outer classes, so the properties may become accidentally true (they check for a substring in the name) 2. by ensuring that the (destructive) renames during LambdaLift don't make the above properties accidentally true. This was in fact the cause for SI-8900.
* / / SI-8818 FreshName extractor forgives suffixSom Snytt2015-02-091-10/+14
|/ / | | | | | | | | | | The test is corrected (inverted) and the extractor is made more succinct. Succinctness isn't enforced by the test, but I checked it manually.
* | SI-9135 Fix NPE, a regression in the pattern matcherJason Zaugg2015-02-051-1/+1
| | | | | | | | | | | | | | | | The community build discovered that #4252 introduced the possibility for a NullPointerException. The tree with a null type was a synthetic `Apply(<<matchEnd>>)` created by the pattern matcher. This commit adds a null check.
* | Merge pull request #4252 from retronym/ticket/9050Lukas Rytz2015-02-031-1/+19
|\ \ | | | | | | SI-9050 Fix crasher with value classes, recursion
| * | SI-9050 Fix crasher with value classes, recursionJason Zaugg2015-01-161-1/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | From the "Substitution is hard to do" department. In 7babdab9a, TreeSymSubstitutor was modified to mutate the info of symbols defined in the tree, if that symbol's info referred to one of the `from` symbols in the substitution. It would have been more principled to create a cloned symbol with the updated info, and add that to the substitution. But I wasn't able implement that correctly (let alone efficiently.) The in-place mutation of the info of a symbol led to the crasher in this bug: a singleton type over that symbol ends up with a stale cached value of 'underlying'. In the enclosed test case, this leads to a type error in the `SubstituteRecursion` of the extension methods phase. This commit performs a cleanup job at the end of `substituteSymbols` by invalidating the cache of any `SingleType`-s in the tree that refer to one of the mutated symbols.
* | | SI-9133 Harden against infinite loop in NoSymbol.ownerJason Zaugg2015-02-031-1/+5
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | The available evidence gathered in an IDE hang suggests that while editing erronenous code, a call to `Erasure#javaSig` by the IDE's structure builder triggered the `ExplicitOuter` info transformer on a symbol with some sort of incoherent owner chain, which led to an infinite loop in `NoSymbol#outerClass`. This commit hardens that method to work in the same manner as a call to `NoSymbol.owner`: log the error under -Xdev or -Ydebug and return return `NoSymbol` to soldier on without crashing / hanging. I haven't formulated a theory about how we might have ended up with the corrupt owner chain.
* | Merge pull request #4201 from mpociecha/fix-typos-in-docs-and-commentsGrzegorz Kossakowski2015-01-1424-45/+45
|\ \ | | | | | | Fix many typos in docs and comments
| * | Fix many typos in docs and commentsmpociecha2014-12-1424-45/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit corrects many typos found in scaladocs, comments and documentation. It should reduce a bit number of PRs which fix one typo. There are no changes in the 'real' code except one corrected name of a JUnit test method and some error messages in exceptions. In the case of typos in other method or field names etc., I just skipped them. Obviously this commit doesn't fix all existing typos. I just generated in IntelliJ the list of potential typos and looked through it quickly.
* | | SI-9057 - fix `showCode` to put backticks around names including dotsJan Bessai2015-01-071-1/+2
| | | | | | | | | | | | | | | | | | | | | Missing backticks cause the parser to treat names as paths, which is obviously invalid. A unit test is included.
* | | Merge pull request #4139 from retronym/ticket/7965Adriaan Moors2014-12-233-0/+7
|\ \ \ | | | | | | | | SI-7965 Support calls to MethodHandle.{invoke,invokeExact}
| * | | SI-7965 Support calls to MethodHandle.{invoke,invokeExact}Jason Zaugg2014-12-033-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These methods are "signature polymorphic", which means that compiler should not: 1. adapt the arguments to `Object` 2. wrap the repeated parameters in an array 3. adapt the result type to `Object`, but instead treat it as it it already conforms to the expected type. Dispiritingly, my initial attempt to implement this touched the type checker, uncurry, erasure, and the backend. However, I realized we could centralize handling of this in the typer if at each application we substituted the signature polymorphic symbol with a clone that carried its implied signature, which is derived from the types of the arguments (typechecked without an expected type) and position within and enclosing cast or block. The test case requires Java 7+ to compile so is currently embedded in a conditionally compiled block of code in a run test. We ought to create a partest category for modern JVMs so we can write such tests in a more natural style. Here's how this looks in bytecode. Note the `bipush` / `istore` before/after the invocation of `invokeExact`, and the descriptor `(LO$;I)I`. ``` % cat sandbox/poly-sig.scala && qscala Test && echo ':javap Test$#main' | qscala import java.lang.invoke._ object O { def bar(x: Int): Int = -x } object Test { def main(args: Array[String]): Unit = { def lookup(name: String, params: Array[Class[_]], ret: Class[_]) = { val lookup = java.lang.invoke.MethodHandles.lookup val mt = MethodType.methodType(ret, params) lookup.findVirtual(O.getClass, name, mt) } def lookupBar = lookup("bar", Array(classOf[Int]), classOf[Int]) val barResult: Int = lookupBar.invokeExact(O, 42) () } } scala> :javap Test$#main public void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC Code: stack=3, locals=3, args_size=2 0: aload_0 1: invokespecial #18 // Method lookupBar$1:()Ljava/lang/invoke/MethodHandle; 4: getstatic #23 // Field O$.MODULE$:LO$; 7: bipush 42 9: invokevirtual #29 // Method java/lang/invoke/MethodHandle.invokeExact:(LO$;I)I 12: istore_2 13: return LocalVariableTable: Start Length Slot Name Signature 0 14 0 this LTest$; 0 14 1 args [Ljava/lang/String; 13 0 2 barResult I LineNumberTable: line 16: 0 } ``` I've run this test across our active JVMs: ``` % for v in 1.6 1.7 1.8; do java_use $v; pt --terse test/files/run/t7965.scala || break; done java version "1.6.0_65" Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716) Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode) Selected 1 tests drawn from specified tests . 1/1 passed (elapsed time: 00:00:02) Test Run PASSED java version "1.7.0_71" Java(TM) SE Runtime Environment (build 1.7.0_71-b14) Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode) Selected 1 tests drawn from specified tests . 1/1 passed (elapsed time: 00:00:07) Test Run PASSED java version "1.8.0_25" Java(TM) SE Runtime Environment (build 1.8.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) Selected 1 tests drawn from specified tests . 1/1 passed (elapsed time: 00:00:05) Test Run PASSED ```
* | | | fix ByteCodecs scaladocxuwei-k2014-12-141-2/+2
| |/ / |/| |
* | | Merge pull request #4176 from mpociecha/flat-classpath2Grzegorz Kossakowski2014-12-055-26/+21
|\ \ \ | | | | | | | | The alternative, flat representation of classpath elements
| * | | Cleanup and refactoring - semicolons, unused or commented out codempociecha2014-12-055-20/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit contains some minor changes made by the way when implementing flat classpath. Sample JUnit test that shows that all pieces of JUnit infrastructure work correctly now uses assert method form JUnit as it should do from the beginning. I removed commented out lines which were obvious to me. In the case of less obvious commented out lines I added TODOs as someone should look at such places some day and clean them up. I removed also some unnecessary semicolons and unused imports. Many string concatenations using + have been changed to string interpolation. There's removed unused, private walkIterator method from ZipArchive. It seems that it was unused since this commit: https://github.com/scala/scala/commit/9d4994b96c77d914687433586eb6d1f9e49c520f However, I had to add an exception for the compatibility checker because it was complaining about this change. I made some trivial corrections/optimisations like use 'findClassFile' method instead of 'findClass' in combination with 'binary' to find the class file.
| * | | Add flat classpath implementation for zip and jar filesmpociecha2014-11-301-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit adds an implementation of flat classpath which can handle both jar and vanilla zip files. In fact there are two versions - for a class- and a sourcepath. Both extend ZipArchiveFileLookup which provides common logic. They use FileZipArchive. @gkossakowski made a comparison of different ways of handling zips and jars (e.g. using javac's ZipFileIndex). He stated that general efficiency of FileZipArchive, taking into account various parameters, is the best. FileZipArchive is slightly changed. From now it allows to find the entry for directory in all directory entries without iterating all entries regardless of a type. Thanks to that we can simply find a directory for a package - like in the case of DirectoryFileLookup. There's also added possibility to cache classpath representation of classpath elements from jar and zip files across compiler instances. The cache is just a map AbstractFile -> FlatClassPath. It should reduce the number of created classpath and file instances e.g. in the case of many ScalaPresentationCompilers in Scala IDE. To prevent the possibility to avoid a cache, caches are created as a part of factories responsible for the creation of these types of the flat classpath.
* | | | Merge pull request #4178 from retronym/ticket/9018Jason Zaugg2014-12-031-2/+14
|\ \ \ \ | | | | | | | | | | SI-9018 Fix regression: cycle in LUBs
| * | | | SI-9018 Fix regression: cycle in LUBsJason Zaugg2014-12-031-2/+14
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Regressed in 4412a92d, which admirably sought to impose some structure on the domain of depths, but failed to preserve an imporatnt part of said structure. When calculating LUBs and GLBs, the recursion depth is limited by propagating a decreasing depth parameter. Its initial value is the recursion limit, and is calcluated from the maximum depth of the types fed into the calculation. Here are a few examples that give a flavour of this calculation: ``` scala> class M[A] defined class M scala> class N extends M[M[M[M[A]]]] <console>:34: error: not found: type A class N extends M[M[M[M[A]]]] ^ scala> class N extends M[M[M[M[Int]]]] defined class N scala> lubDepth(typeOf[N] :: Nil) res5: scala.reflect.internal.Depth = Depth(4) scala> type T = M[Int] with M[M[Int]] defined type alias T scala> lubDepth(typeOf[T] :: Nil) res7: scala.reflect.internal.Depth = Depth(3) ``` One parts of the LUB calculation, `lub0`, truncates the lub to `Any` when the depth dives below zero. Before 4412a92d: ------------------ value decr incr ------------------ -3 -3 -2 (= AnyDepth) -2 -3 -1 -1 -2 0 0 -1 1 1 0 2 ... After 4412a92d: ----------------------- value decr incr ----------------------- -MaxInt -MaxInt -MaxInt (= AnyDepth) 0 -MaxInt 1 1 0 2 ... The crucial difference that triggered the regression is that decrementing a depth of zero now goes to the sentinel value, `AnyDepth`, rather than to `-1`. This commit modifies `Depth` to allow it to represent any negative depth. It also switches the sentinel value for `AnyDepth`. Even though I don't believe it is needed, I have also allowed for `Depth.Zero.decr.decr.decr == Depth.AnyVal`, which was historically the case in 2.10.4. To better understand what was happening, I added tracing to the calculation and diffed the before and after: https://gist.github.com/retronym/ec59608eecc52bb497fa Notice that when `elimSub(ts, depth = 0)` recursively calls `lub`, it does so with the variant that caluculates the allowable depth from the shape of the given types. We can then infinitely recurse. Before 4412a92d: ``` |-- elimSub(depth = 0, ts = List(Comparable[_ >: TestObject.E.Value with String <: Comparable[_ >: TestObject.E.Valu | |-- lub(depth = -1, ts = List(TestObject.E.Value with String, TestObject.C)) | | |-- lub0(depth = -1, ts0 = List(TestObject.E.Value with String, TestObject.C)) | | | |-- elimSub(depth = -1, ts = List(TestObject.E.Value with String, TestObject.C)) | | | |== List(TestObject.E.Value with String, TestObject.C) | | | |-- Truncating LUB to | | | |== Any | | |== Any | |== Any |== List(Comparable[_ >: TestObject.E.Value with String <: Comparable[_ >: TestObject.E.Value with String <: java.io |-- lub(depth = 0, ts = List(java.lang.type, java.lang.type)) | |-- lub0(depth = 0, ts0 = List(java.lang.type, java.lang.type)) | | |-- elimSub(depth = 0, ts = List(java.lang.type, java.lang.type)) | | |== List(java.lang.type) | |== java.lang.type |== java.lang.type |-- elimSub(depth = 0, ts = List(Object, Object)) |== List(Object) |-- elimSub(depth = 0, ts = List(Any, Any)) |== List(Any) ``` After 4412a92d: ``` |-- elimSub(depth = 0, ts = List(Comparable[_ >: TestObject.E.Value with String <: Comparable[_ >: TestObject.E.Valu | |-- lub(depth = _, ts = List(TestObject.E.Value with String, TestObject.C)) | | |-- lub(depth = 3, ts = List(TestObject.E.Value with String, TestObject.C)) | | | |-- lub0(depth = 3, ts0 = List(TestObject.E.Value with String, TestObject.C)) | | | | |-- elimSub(depth = 3, ts = List(TestObject.E.Value with String, TestObject.C)) | | | | |== List(TestObject.E.Value with String, TestObject.C) | | | | |-- lub1(depth = 3, ts = List(TestObject.E.Value with String, TestObject.C)) | | | | | |-- elimSub(depth = 3, ts = List(scala.math.Ordered[TestObject.E.Value], scala.math.Orde | | | | | |== List(scala.math.Ordered[TestObject.E.Value], scala.math.Ordered[TestObject.C]) ```
* | | | Merge pull request #4166 from lpiepiora/update-scaladoc-examplesAdriaan Moors2014-12-0110-35/+35
|\ \ \ \ | |/ / / |/| | | Update ScalaDoc code examples not to use deprecated constructs
| * | | Update ScalaDoc code examples not to use deprecated constructsLukasz Piepiora2014-11-2610-35/+35
| | | | | | | | | | | | | | | | | | | | - Replace newTermName in favour of TermName - Replace newTypeName in favour of TypeName
* | | | SI-8502 Improve resiliance to absent packagesJason Zaugg2014-11-282-6/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When unpickling a class, we create stub symbols for references to classes absent from the current classpath. If these references only appear in method signatures that aren't called, we can proceed with compilation. This is in line with javac. We're getting better at this, but there are still some gaps. This bug is about the behaviour when a package is completely missing, rather than just a single class within that package. To make this work we have to add two special cases to the unpickler: - When unpickling a `ThisType`, convert a `StubTermSymbol` into a `StubTypeSymbol`. We hit this when unpickling `ThisType(missingPackage)`. - When unpickling a reference to `<owner>.name` where `<owner>` is a stub symbol, don't call info on that owner, but rather allow the enclosing code in `readSymbol` fall through to create a stub for the member. The test case was distilled from an a problem that a Spray user encountered when Akka was missing from the classpath. Two existing test cases have progressed, and the checkfiles are accordingly updated.
* | | | Fixes memory leak when using reflectionTim Harper2014-11-221-2/+6
|/ / / | | | | | | | | | | | | | | | References to Threads would be retained long after their termination if reflection is used in them. This led to a steady, long memory leak in applications using reflection in thread pools.
* | | Merge pull request #4099 from retronym/ticket/7596Grzegorz Kossakowski2014-11-211-1/+1
|\ \ \ | | | | | | | | SI-7596 Curtail overloaded symbols during unpickling
| * | | SI-7596 Curtail overloaded symbols during unpicklingJason Zaugg2014-11-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In code like: object O { val x = A; def x(a: Any) = ... } object P extends O.x.A The unpickler was using an overloaded symbol for `x` in the parent type of `P`. This led to compilation failures under separate compilation. The code that leads to this is in `Unpicklers`: def fromName(name: Name) = name.toTermName match { case nme.ROOT => loadingMirror.RootClass case nme.ROOTPKG => loadingMirror.RootPackage case _ => adjust(owner.info.decl(name)) } This commit filters the overloaded symbol based its stability unpickling a singleton type. That seemed a slightly safer place than in `fromName`.
* | | | Merge pull request #4115 from retronym/ticket/8597Grzegorz Kossakowski2014-11-211-0/+4
|\ \ \ \ | |_|/ / |/| | | SI-8597 Improved pattern unchecked warnings
| * | | SI-8597 Improved pattern unchecked warningsJason Zaugg2014-11-091-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The spec says that `case _: List[Int]` should be always issue an unchecked warning: > Types which are not of one of the forms described above are > also accepted as type patterns. However, such type patterns > will be translated to their erasure (§3.7). The Scala compiler > will issue an “unchecked” warning for these patterns to flag > the possible loss of type-safety. But the implementation goes a little further to omit warnings based on the static type of the scrutinee. As a trivial example: def foo(s: Seq[Int]) = s match { case _: List[Int] => } need not issue this warning. These discriminating unchecked warnings are domain of `CheckabilityChecker`. Let's deconstruct the reported bug: def nowarn[T] = (null: Any) match { case _: Some[T] => } We used to determine that if the first case matched, the scrutinee type would be `Some[Any]` (`Some` is covariant). If this statically matches `Some[T]` in a pattern context, we don't need to issue an unchecked warning. But, our blanket use of `existentialAbstraction` in `matchesPattern` loosened the pattern type to `Some[Any]`, and the scrutinee type was deemed compatible. I've added a new method, `scrutConformsToPatternType` which replaces pattern type variables by wildcards, but leaves other abstract types intact in the pattern type. We have to use this inside `CheckabilityChecker` only. If we were to make `matchesPattern` stricter in the same way, tests like `pos/t2486.scala` would fail. I have introduced a new symbol test to (try to) identify pattern type variables introduced by `typedBind`. Its not pretty, and it might be cleaner to reserve a new flag for these. I've also included a test variation exercising with nested matches. The pattern type of the inner case can't, syntactically, refer to the pattern type variable of the enclosing case. If it could, we would have to be more selective in our wildcarding in `ptMatchesPatternType` by restricting ourselves to type variables associated with the closest enclosing `CaseDef`. As some further validation of the correctness of this patch, four stray warnings have been teased out of neg/unchecked-abstract.scala I also had to changes `typeArgsInTopLevelType` to extract the type arguments of `Array[T]` if `T` is an abstract type. This avoids the "Checkability checker says 'Uncheckable', but uncheckable type cannot be found" warning and consequent overly lenient analysis. Without this change, the warning was suppressed for: def warnArray[T] = (null: Any) match { case _: Array[T] => }
* | | | Merge pull request #4123 from retronym/ticket/8253Jason Zaugg2014-11-201-0/+2
|\ \ \ \ | | | | | | | | | | SI-8253 Fix incorrect parsing of <elem xmlns={f("a")}/>
| * | | | SI-8253 Fix incorrect parsing of <elem xmlns={f("a")}/>Jason Zaugg2014-11-101-0/+2
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The spliced application was placed in the `attrMap` in `SymbolicXMLBuilder` and later incorrectly matched by a pattern intended only to match: xml.Text(s) That attribute value is generated by parsing: <elem xmlns='a'/> So the net effect was that the two fragments of XML were identical! This commit sharpens up the match to really look for a syntactic `_root_.scala.xml.Text("...")`. The test just prints the parse trees of a variety of cases, as we we should not test the modularized XML library in scala/scala.
* | | | Merge pull request #4051 from heathermiller/repl-cp-fix2Jason Zaugg2014-11-181-7/+9
|\ \ \ \ | | | | | | | | | | SI-6502 Reenables loading jars into the running REPL (regression in 2.10)
| * | | | SI-6502 Refactorings suggested by reviewHeather Miller2014-11-101-7/+9
| | |/ / | |/| | | | | | | | | | | | | | - Moves mergeUrlsIntoClassPath from Global into ClassPath - Revises and documents AbstractFile.getURL
* | | | Merge pull request #4101 from adriaanm/sam-exLukas Rytz2014-11-103-1/+18
|\ \ \ \ | |_|/ / |/| | | [sammy] eta-expansion, overloading, existentials
| * | | [sammy] use correct type for method to overrideAdriaan Moors2014-11-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Don't naively derive types for the single method's signature from the provided function's type, as it may be a subtype of the method's MethodType. Instead, once the sam class type is fully defined, determine the sam's info as seen from the class's type, and use those to generate the correct override. ``` scala> Arrays.stream(Array(1, 2, 3)).map(n => 2 * n + 1).average.ifPresent(println) 5.0 scala> IntStream.range(1, 4).forEach(println) 1 2 3 ``` Also, minimal error reporting Can't figure out how to do it properly, but some reporting is better than crashing. Right? Test case that illustrates necessity of the clumsy stop gap `if (block exists (_.isErroneous))` enclosed as `sammy_error_exist_no_crash` added TODO for repeated and by-name params
| * | | [sammy] eta-expansion, overloading (SI-8310)Adriaan Moors2014-11-063-1/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Playing with Java 8 Streams from the repl showed we weren't eta-expanding, nor resolving overloading for SAMs. Also, the way Java uses wildcards to represent use-site variance stresses type inference past its bendiness point (due to excessive existentials). I introduce `wildcardExtrapolation` to simplify the resulting types (without losing precision): `wildcardExtrapolation(tp) =:= tp`. For example, the `MethodType` given by `def bla(x: (_ >: String)): (_ <: Int)` is both a subtype and a supertype of `def bla(x: String): Int`. Translating http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ into Scala shows most of this works, though we have some more work to do (see near the end). ``` scala> import java.util.Arrays scala> import java.util.stream.Stream scala> import java.util.stream.IntStream scala> val myList = Arrays.asList("a1", "a2", "b1", "c2", "c1") myList: java.util.List[String] = [a1, a2, b1, c2, c1] scala> myList.stream.filter(_.startsWith("c")).map(_.toUpperCase).sorted.forEach(println) C1 C2 scala> myList.stream.filter(_.startsWith("c")).map(_.toUpperCase).sorted res8: java.util.stream.Stream[?0] = java.util.stream.SortedOps$OfRef@133e7789 scala> Arrays.asList("a1", "a2", "a3").stream.findFirst.ifPresent(println) a1 scala> Stream.of("a1", "a2", "a3").findFirst.ifPresent(println) a1 scala> IntStream.range(1, 4).forEach(println) <console>:37: error: object creation impossible, since method accept in trait IntConsumer of type (x$1: Int)Unit is not defined (Note that Int does not match Any: class Int in package scala is a subclass of class Any in package scala, but method parameter types must match exactly.) IntStream.range(1, 4).forEach(println) ^ scala> IntStream.range(1, 4).forEach(println(_: Int)) // TODO: can we avoid this annotation? 1 2 3 scala> Arrays.stream(Array(1, 2, 3)).map(n => 2 * n + 1).average.ifPresent(println(_: Double)) 5.0 scala> Stream.of("a1", "a2", "a3").map(_.substring(1)).mapToInt(_.parseInt).max.ifPresent(println(_: Int)) // whoops! ReplGlobal.abort: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false error: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false scala.reflect.internal.FatalError: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false at scala.reflect.internal.Reporting$class.abort(Reporting.scala:59) scala> IntStream.range(1, 4).mapToObj(i => "a" + i).forEach(println) a1 a2 a3 ```
* | | | Merge pull request #4097 from retronym/ticket/7602Jason Zaugg2014-11-071-1/+3
|\ \ \ \ | | | | | | | | | | SI-7602 Avoid crash in LUBs with erroneous code
| * | | | SI-7602 Avoid crash in LUBs with erroneous codeJason Zaugg2014-11-071-1/+3
| | |/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a class contains a double defintion of a method that overrides an interface method, LUBs could run into a spot where filtering overloaded alternatives to those that match the interface method fails to resolve to a single overload, which crashes the compiler. This commit uses `filter` rather than `suchThat` to avoid the crash.
* | | | Merge pull request #4083 from retronym/ticket/8947Jason Zaugg2014-11-071-0/+8
|\ \ \ \ | | | | | | | | | | SI-8947 Avoid cross talk between tag materializers and reify
| * | | | SI-8947 Additional layers of defence against EmptyTree mutationJason Zaugg2014-11-061-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As suggested in review: - Use `abort` rather than `{error; EmptyTree} when we hit an error in reification or tag materialization. - Explicitly avoid adding the `MacroExpansionAttachment` to the macro expansion if it an `EmptyTree` - Emit a `-Xdev` warning if any other code paths find a way to mutate attachments in places they shouldn't.
| * | | | SI-8947 Avoid cross talk between tag materializers and reifyJason Zaugg2014-10-301-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After a macro has been expanded, the expandee are expansion are bidirectionally linked with tree attachments. Reify uses the back reference to replace the expansion with the expandee in the reified tree. It also has some special cases to replace calls to macros defined in scala-compiler.jar with `Predef.implicitly[XxxTag[T]]`. This logic lives in `Reshape`. However, the expansion of a macro may be `EmptyTree`. This is the case when a tag materializer macro fails. User defined macros could do the also expand to `EmptyTree`. In the enclosed test case, the error message that the tag materializer issued ("cannot materialize class tag for unsplicable type") is not displayed as the typechecker finds another means of making the surrounding expression typecheck. However, the macro engine attaches a backreference to the materializer macro on `EmpytyTree`! Later, when `reify` reshapes a tree, every occurance of `EmptyTree` will be replaced by a call to `implicitly`. This commit expands the domain of `CannotHaveAttrs`, which is mixed in to `EmptyTree`. It silently ignores all attempts to mutate attachments. Unlike similar code that discards mutations of its type and position, I have refrained from issuing a developer warning in this case, as to silence this I would need to go and add a special case at any places adding attachments.
* | | | | Merge pull request #4093 from lrytz/t8960Lukas Rytz2014-11-061-1/+1
|\ \ \ \ \ | |_|/ / / |/| | | | SI-8960 Bring back the SerialVersionUID to anonymous function classes
| * | | | SI-8960 Bring back the SerialVersionUID to anonymous function classesLukas Rytz2014-11-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In PR #1673 / 4267444, the annotation `SerialVersionId` was changed from a `StaticAnnotation` to `ClassFileAnnotation` in order to enforce annotation arguments to be constants. That was 2.11.0. The ID value in the AnnotationInfo moved from `args` to `assocs`, but the backend was not adjusted. This was fixed in PR #3711 / ecbc9d0 for 2.11.1. Unfortunately, the synthetic AnnotationInfo that is added to anonymous function classes still used the old constructor (`args` instead of `assocs`), so extracting the value failed, and no field was added to the classfile.
* | | | | Merge pull request #4089 from gourlaysama/wip/t6626-scaladoc-throws-linksVlad Ureche2014-11-053-5/+5
|\ \ \ \ \ | | | | | | | | | | | | SI-6626 make @throws tags create links to exceptions
| * | | | | cleanup @throws tags in library and reflectAntoine Gourlay2014-11-053-5/+5
| |/ / / / | | | | | | | | | | | | | | | | | | | | - there is no need for explicit links with [[ and ]] - there is no need for explicit backquoting
* | | | | Merge pull request #4017 from lrytz/t6541Lukas Rytz2014-11-051-0/+1
|\ \ \ \ \ | |_|_|/ / |/| | | | SI-6541 valid wildcard existentials for case-module-unapply
| * | | | SI-6541 valid wildcard existentials for case-module-unapplyLukas Rytz2014-11-051-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of letting the compiler infer the return type of case module unapply methods, provide them explicitly. This is enabled only under -Xsource:2.12, because the change is not source compatible.
* | | | | Merge pull request #4054 from soc/SI-8916Lukas Rytz2014-11-0410-13/+2
|\ \ \ \ \ | |_|/ / / |/| | | | SI-8916 Clean up unused imports, values and variables
| * | | | SI-8916 Fix -Ywarn-unused-import warningsSimon Ochsenreither2014-10-2410-13/+2
| | |/ / | |/| |
* | | | Merge pull request #4036 from retronym/topic/opt-tail-callsJason Zaugg2014-11-041-0/+4
|\ \ \ \ | | | | | | | | | | SI-8893 Restore linear perf in TailCalls with nested matches