summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* 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 #3030 from xeno-by/topic/fundep-viewsEugene Burmako2013-10-181-5/+21
|\ | | | | SI-3346 implicit parameters can now guide implicit view inference
| * SI-3346 implicit parameters can now guide implicit view inferenceEugene Burmako2013-10-111-5/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This simple patch makes it possible for implicit views to benefit from fundep-guided type inference, eliminating a nasty special case in implicit inference. Here are the changes that I had to apply to the tests (they exposed quite a number of interesting questions that I was happy to answer): 1) neg/t5845.scala now works, so I moved it to pos. That easily makes sense, because the test was just a canary to track previous state of things. 2) neg/divergent_implicit.scala, neg/t5578.scala and neg/t7519.scala changed their messages to less informative ones, because inapplicable implicit views now get disqualified early and therefore don't display their error messages to the user. This is an unfortunate but necessary byproduct of this change, and one can argue that the behavior is now completely consistent with implicit vals (that also don't explain why this or that implicit val got disqualified, but rather display a generic implicit value not found message). 3) scaladoc/implicits-chaining.scala and scaladoc/implicits-base.scala. Immediate culling of apriori inapplicable implicit views messes things up for Scaladoc, because it's interested in potentially applicable views, having infrastructure to track various constraints (type bounds, requirements for implicit parameters, etc) that guide applicability of views and then present it to the user. Therefore, when scaladoc is detected, implicit search reverts to the old behavior. 4) We still cannot have Jason's workaround to type constructor inference mentioned in comments to SI-3346, because it's not really about implicit parameters of implicit views, but about type inference flowing from the implicit parameter list to a preceding parameter list in order to affect inference of an implicit view. This is something that's still too ambitious.
* | Merge pull request #3041 from gkossakowski/merge-2.10.xJason Zaugg2013-10-181-1/+5
|\ \ | | | | | | Merge 2.10.x into master
| * \ Merge remote-tracking branch 'scala/2.10.x' into merge-2.10.xGrzegorz Kossakowski2013-10-161-1/+5
| |\ \ | | | | | | | | | | | | | | | | | | | | Conflicts: build.number test/files/neg/classmanifests_new_deprecations.check
| | * \ Merge pull request #2985 from retronym/ticket/7783Jason Zaugg2013-10-031-1/+5
| | |\ \ | | | | | | | | | | Don't issue deprecation warnings for inferred TypeTrees
| | | * | SI-7783 Don't issue deprecation warnings for inferred TypeTreesJason Zaugg2013-09-271-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Deprecation checks in RefChecks were looking into all TypeTrees to find references to deprecated type aliases. However, when the compiler infers a type argument or type of a member it creates a TypeTree (with a null original) that was also leading to warnings. I ran into this problem often when upgrading a build from SBT 0.12 to 0.13: a plugin I was using used the deprecated type alias, and I suffered transitively when I used methods from its API. This commit disables the checks for inferred TypeTree-s.
* | | | | 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-1616-1133/+644
|\ \ \ \ \ \ | |_|/ / / / |/| | | | | Traverser and Pickler improvements.
| * | | | | Eliminate redundant pickling code.Paul Phillips2013-10-1210-1037/+369
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit drops about 700 lines of redundant traversal logic. There had been ad hoc adjustments to the pickling scheme here and there, probably in pursuit of tiny performance improvements. For instance, a Block was pickled expr/stats instead of stats/expr, a TypeDef was pickled rhs/tparams instead of tparams/rhs. The benefits derived are invisible compared to the cost of having several hundred lines of tree traversal code duplicated in half a dozen or more places. After making Traverser consistent/complete, it was a straightforward matter to use it for pickling. It is ALSO now possible to write a vastly cleaner tree printer than the ones presently in trunk, but I leave this as an exercise for Dear Reviewer.
| * | | | | Tree traversal: more uniform and granular.Paul Phillips2013-10-122-79/+122
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There's a huge amount of tree traversal related duplication which is hard to eliminate only because trees aren't properly traversed. The not-quite-tree bits of key trees are ignored during traversals, making it impossible to write e.g. a pretty printer without duplicating almost the entire traversal logic (as indeed is done for printing purposes in more than one place.) And almost the entire pickler logic is redundant with Traverser, except since it's all duplicated of course it diverged. The pickler issue is remedied in the commit to follow. The not-quite-trees not quite being traversed were Modifiers, Name, ImportSelector, and Constant. Now every case field of every tree is traversed, with classes which aren't trees traversed via the following methods, default implementations as shown: def traverseName(name: Name): Unit = () def traverseConstant(c: Constant): Unit = () def traverseImportSelector(sel: ImportSelector): Unit = () def traverseModifiers(mods: Modifiers): Unit = traverseAnnotations(mods.annotations)
| * | | | | Mappings between classes and pickler tags.Paul Phillips2013-10-121-0/+128
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This enables a measure of "command/query separation", which is to say: the same method shouldn't go on a side effecting binge and also return a value.
| * | | | | Add -Xdev to the runtime-visible settings.Paul Phillips2013-10-122-13/+17
| | | | | |
| * | | | | Convenience method findSymbol.Paul Phillips2013-10-124-4/+8
| | | | | |
* | | | | | Merge pull request #3016 from xeno-by/topic/vampiresJason Zaugg2013-10-151-1/+1
|\ \ \ \ \ \ | | | | | | | | | | | | | | [master] assorted fixes for vampire macros
| * | | | | | no longer warns on calls to vampire macrosEugene Burmako2013-10-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As eloquently elaborated and cleverly named by Travis Brown, macros defined in structural types are useful: http://meta.plasm.us/posts/2013/07/12/vampire-methods-for-structural-types/. However, since such macros are on the intersection of a number of language features, as usual, there are bugs. This commit fixes an unwanted interaction of macros defined in structural types with the scala.language.reflectiveCalls guard. Since macro calls aren't going to be carried to runtime, there's no need to warn about them.
* | | | | | | Merge pull request #3037 from gkossakowski/fix-merge-3018v2.11.0-M6Grzegorz Kossakowski2013-10-144-22/+255
|\ \ \ \ \ \ \ | | | | | | | | | | | | | | | | [resubmit] Experimental Single Abstract Method support (sammy meets world)
| * \ \ \ \ \ \ Merge remote-tracking branch 'scala/master' into fix-merge-3018Grzegorz Kossakowski2013-10-1414-460/+601
| |\ \ \ \ \ \ \ | | | |/ / / / / | | |/| | | | | | | | | | | | | | | | | | | | | Conflicts: src/compiler/scala/tools/nsc/typechecker/Typers.scala
| * | | | | | | Remove stray debug commentAdriaan Moors2013-10-081-2/+0
| | | | | | | |
| * | | | | | | Extract SerialVersionUIDAnnotation. Make SAM body synthetic.Adriaan Moors2013-10-083-12/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Addressing review feedback.
| * | | | | | | Don't pursue SAM translation after an arity mismatch.Jason Zaugg2013-10-081-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before this change: scala> trait T { def apply(a: Int): Int } defined trait T scala> ((x: Int, y: Int) => 0): T <console>:9: error: object creation impossible, since method apply in trait T of type (a: Int)Int is not defined ((x: Int, y: Int) => 0): T ^ After the change, these cases report the same errors as they do *without* -Xexperimental.
| * | | | | | | Single Abstract Method support: synthesize SAMsAdriaan Moors2013-10-041-10/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Under `-Xexperimental`, `typedFunction` invokes `synthesizeSAMFunction` when the expected type for the function literal (`pt`) is not the built-in `FunctionN` type of the expected arity, but `pt` does have a SAM with the expected number of arguments. PS: We'll require `import language.sam` instead of `-Xexperimental`, as soon as the SIP is ready and there are more tests.
| * | | | | | | Single Abstract Method support: synthesis helpersAdriaan Moors2013-10-042-0/+192
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `synthesizeSAMFunction` will be used to expand the following tree: ``` { (p1: T1, ..., pN: TN) => body } : S ``` to: ``` { def apply$body(p1: T1, ..., pN: TN): T = body new S { def apply(p1: T1, ..., pN: TN): T = apply$body(p1,..., pN) } } ``` The expansion assumes `S` (the expected type) defines a single abstract method (let's call that method `apply` for simplicity). 1. If 'T' is not fully defined, it is inferred by type checking `def apply$body` without a result type before type checking the block. The method's inferred result type is used instead of T`. [See test/files/pos/sammy_poly.scala] 2. To more easily enforce S's members are not in scope in `body`, that tree goes to the `apply$body` method that's outside the anonymous subclass of S. (The separate `apply$body` method simplifies the implementation of 1&2.) 3. The following restrictions apply to S: 1. Its primary constructor (if any) must be public, no-args, not overloaded. 2. S must have exactly one abstract member, its SAM 3. SAM must take exactly one argument list 4. SAM must be monomorphic We may later relax these requirements to allow an implicit argument list, both on the constructor and the SAM. Could also let the SAM be polymorphic.
| * | | | | | | Clarify findMembers, add reverse engineered docsAdriaan Moors2013-10-041-5/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When looking for deferred members, it only makes sense to retry when deferred members aren't excluded.
| * | | | | | | Simplify partest.task target, fix typo in comment.Adriaan Moors2013-10-041-1/+1
| | |/ / / / / | |/| | | | |
* | | | | | | Merge pull request #3038 from retronym/topic/by-name-revertGrzegorz Kossakowski2013-10-142-3/+9
|\ \ \ \ \ \ \ | | | | | | | | | | | | | | | | SI-7899 Allow by-name inference under -Yinfer-by-name
| * | | | | | | SI-7899 Allow by-name inference under -Yinfer-by-nameJason Zaugg2013-10-142-3/+9
| | |_|/ / / / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As usual, the hole has been exploited in the wild. While you can't abstract over by-name-ness without running into the ClassCastException or an un-applied Function0, there are cases like the enclosed test where you can tiptoe around those cases. I've proposed a small change to Scalaz to avoid tripping over this problem: https://github.com/scalaz/scalaz/pull/562/files But this commit I've also added a transitional flag, -Yinfer-by-name, that they could use to back-publish older versions without code changes. It is also an insurance policy for other projects that might be exploiting the same hole.
* | | | | | | Aesthetics in Trees.Paul Phillips2013-10-131-52/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As long as it's a block of pure boilerplate we have to navigate around all the time, it may as well be the most beautiful boilerplate it knows how to be.
* | | | | | | Aesthetics in GenTrees.Paul Phillips2013-10-131-24/+13
| |_|/ / / / |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A nominee for "worst textual shape" might be \\\\\ ///// \\\\\ ///// \\\\\ ///// where the zigzagging wall of text is confined to the first forty columns. In this commit we halve the vertical space usage and double the readability.
* | | | | | Merge pull request #3024 from retronym/ticket/7895Paul Phillips2013-10-122-25/+49
|\ \ \ \ \ \ | | | | | | | | | | | | | | SI-7895 Error reporting: avoid cascading, truncation
| * | | | | | SI-7985 Typecheck args after failure to typecheck functionJason Zaugg2013-10-091-6/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `missing1.foo(missing2)` now reports `missing1` and `missing2` as not found. Previously, only the first was reported. The arguments are typed with an expected type ErrorType. We propagate this through as the inferred type of anonymous function parameters to avoid issuing cascading "missing parameter type" errors in code like: scala> Nil.mapp(x => abracadabra) <console>:8: error: value mapp is not a member of object Nil Nil.mapp(x => abracadabra) ^ <console>:8: error: not found: value abracadabra Nil.mapp(x => abracadabra) ^ This was in response to unwanted changes in the output of existing neg tests; no new test is added. Similarly, we refine the errors in neg/t6436b.scala by to avoid cascaded errors after: type mismatch; found: StringContext, required: ?{def q: ?}
| * | | | | | SI-7895 Issue all buffered errors after silent mode.Jason Zaugg2013-10-092-19/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rather than just the first. For example, `foo(wizzle, wuzzle, woggle)` should report all three not-found symbols.
| * | | | | | SI-7895 Avoid cascade of "symbol not found" in pattern matchesJason Zaugg2013-10-091-3/+10
| | |_|_|_|/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | If we can't type check the `Foo` in `case Foo(a, b) => (a, b)`, we should enter error symbols for `a` and `b` to avoid further errors being reported in the case body.
* | | | | | Merge pull request #3025 from retronym/ticket/7902Paul Phillips2013-10-121-0/+1
|\ \ \ \ \ \ | | | | | | | | | | | | | | SI-7902 Fix spurious kind error due to an unitialized symbol
| * | | | | | SI-7902 Fix spurious kind error due to an unitialized symbolJason Zaugg2013-10-091-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Tracked down this error: <none> is invariant, but type Y2 is declared covariant <none>'s bounds<notype> are stricter than type X2's declared bounds >: Nothing <: Any, <none>'s bounds<notype> are stricter than type Y2's declared bounds >: Nothing <: Any to `Symbol#typeParams` returning `List(NoSymbol)` if the symbol was not initialized. This happends in the enclosed test for: // checkKindBoundsHK() hkArgs = List(type M3) hkParams = List(type M2) This commit forces the symbol of the higher-kinded type argument before checking kind conformance. A little backstory: The `List(NoSymbol)` arises from: class PolyTypeCompleter... { // @M. If `owner` is an abstract type member, `typeParams` are all NoSymbol (see comment in `completerOf`), // otherwise, the non-skolemized (external) type parameter symbols override val typeParams = tparams map (_.symbol) The variation that triggers this problem gets into the kind conformance checks quite early on, during naming of: private[this] val x = ofType[InSeq] The inferred type of which is forced during: def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations
* | | | | | | Merge pull request #3021 from paulp/pr/is-he-stable-or-is-he-volatilePaul Phillips2013-10-123-77/+85
|\ \ \ \ \ \ \ | |_|_|/ / / / |/| | | | | | Extract isStable and isVolatile from Type.
| * | | | | | Extract isStable and isVolatile from Type.Paul Phillips2013-10-053-77/+85
| | |_|/ / / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As with finalResultType, this is easier to control and WAY easier to understand. Look, all the relevant code fits on half a screenful rather than being spread out over 5000 lines and you have to be constantly conscious of what is overriding what. Truly it would be hard to damn the indiscriminate use of subtype polymorphism any more soundly than does this, by way of contrast: def isStable(tp: Type): Boolean = tp match { case _: SingletonType => true case NoPrefix => true case TypeRef(_, NothingClass | SingletonClass, _) => true case TypeRef(_, sym, _) if sym.isAbstractType => tp.bounds.hi.typeSymbol isSubClass SingletonClass case TypeRef(pre, sym, _) if sym.isModuleClass => isStable(pre) case TypeRef(_, _, _) if tp ne tp.dealias => isStable(tp.dealias) case TypeVar(origin, _) => isStable(origin) case AnnotatedType(_, atp, _) => isStable(atp) // Really? case _: SimpleTypeProxy => isStable(tp.underlying) case _ => false } That's all of it! If there are bugs in it (of course there are) some might even be found now.
* | | | | | Merge pull request #3020 from paulp/pr/overriding-pairsJason Zaugg2013-10-096-354/+458
|\ \ \ \ \ \ | |_|/ / / / |/| | | | | Generalize OverridingPairs to SymbolPairs.
| * | | | | Generalize OverridingPairs to SymbolPairs.Paul Phillips2013-10-056-354/+458
| |/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Increases your chance of knowing what is going on in OverridingPairs. Introduces some new abstractions which I hope for your own sakes you will put to use in some way: RelativeTo: operations relative to a prefix SymbolPair: two symbols being compared for something, and the enclosing class where the comparison is being performed Fixed a minor bug with access by accident by way of more principled pair analysis. See run/private-override.scala. Upgraded the error message issued on certain conflicts to give the line numbers of both conflicting methods, as opposed to just one and you go hunting.
* | | | | Merge pull request #3022 from retronym/ticket/7899Jason Zaugg2013-10-091-2/+3
|\ \ \ \ \ | |_|/ / / |/| | | | Don't infer by-name types during, e.g. eta-expansion
| * | | | SI-7899 Don't infer by-name types during, e.g. eta-expansionJason Zaugg2013-10-071-2/+3
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Given: def id[A](a: A): A = a def foo(f: (=> Int) => Int) = () foo(id) We eta-expanded `id` and inferred `A` to be `=> Int` to satisfy the expected type set forth by the formal parameter `f`. We really shouldn't go about inferring types that we can't *write*. Our attempt to do so led promptly into a `ClassCastException` in the enclosed test. This commit: - drops by-name-ness during `inferExprInstance` - tests that this results in a type error for the reported bug (neg/t7899) - tests that a method with a by-name parameter can still be eta expanded to match function with a corresponding by-name parameter (run/t7899) - discovers the same latent CCE in pos/t7584 - now that would be a type error - so we compensate by using placeholder functions rather than eta-expansion. - and move that that test to `run` for good measure.
* | | | Merge pull request #3014 from ceedubs/pr/implicitNotFound-scaladocAdriaan Moors2013-10-071-2/+5
|\ \ \ \ | |/ / / |/| | | Describe type parameter interpolation in @implicitNotFound documentation
| * | | Describe type parameter interpolation in @implicitNotFound documentationCody Allen2013-10-031-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | Using this feature is necessary for helpful error messages, so it should be documented. Thank you to @adriaanm for recommending the this description.
* | | | Merge pull request #3005 from paulp/pr/7886Paul Phillips2013-10-035-23/+28
|\ \ \ \ | | | | | | | | | | SI-7886 unsoundness in pattern matcher.
| * | | | SI-6680 unsoundness in gadt typing.Paul Phillips2013-10-013-21/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduces -Xstrict-inference to deal with the significant gap between soundness and what presently compiles. I'm hopeful that it's TOO strict, because it finds e.g. 75 errors compiling immutable/IntMap.scala, but it might be that bad.