summaryrefslogtreecommitdiff
path: root/test/files
Commit message (Collapse)AuthorAgeFilesLines
* Fix some typosSamy Dindane2013-01-245-68/+54
| | | | | | Fixes mostly "a int", "a a thing" kind of typos. Also removes trailing whitespaces, useless empty lines and commented println() from "test/files/run/ctries-new/iterator.scala".
* Merge branch '2.10.x'Adriaan Moors2013-01-1631-1/+295
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/compiler/scala/tools/nsc/doc/Settings.scala src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala src/compiler/scala/tools/nsc/matching/Patterns.scala src/compiler/scala/tools/nsc/transform/UnCurry.scala src/compiler/scala/tools/nsc/typechecker/Infer.scala src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala src/compiler/scala/tools/nsc/typechecker/Typers.scala src/reflect/scala/reflect/internal/settings/MutableSettings.scala src/reflect/scala/reflect/runtime/Settings.scala src/swing/scala/swing/SwingActor.scala src/swing/scala/swing/SwingWorker.scala test/files/run/t6955.scala
| * Merge pull request #1892 from retronym/ticket/6479Paul Phillips2013-01-151-0/+56
| |\ | | | | | | SI-6479 Don't lift try exprs in label arguments.
| | * SI-6479 Don't lift try exprs in label arguments.Jason Zaugg2013-01-131-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The new pattern matcher uses label jumps to GOTO the next case. Uncurry treated these like regular method arguments, and performed the liftedTree() transformation, which ensures that try expressions are only used in a statement position. Even try in statement position of a block used as such an argument are subject to the same transform. This transform stems from the JVM limitation, that try/catch does not leave a value on the stack. See b194446. This commit changes Uncurry to avoid this transform for arguments to label jumps. This avoids needlessly indirect code, and enables tail call elimination in more cases. As an example, Scala 2.10.0 transforms the last method of the enclosed test case to: try { case <synthetic> val x1: Int = 1; case5(){ if (2.==(x1)) { val x2: Int = x1; matchEnd4({ { def liftedTree2(): Unit = try { throw new scala.runtime.NonLocalReturnControl[Unit](nonLocalReturnKey1, ()) } catch { case (e @ (_: ClassNotFoundException)) => () }; liftedTree2() }; TailrecAfterTryCatch.this.bad() }) } else case6() }; case6(){ matchEnd4(throw new MatchError(x1)) }; matchEnd4(x: Unit){ x } } catch { case (ex @ (_: scala.runtime.NonLocalReturnControl[Unit @unchecked])) => if (ex.key().eq(nonLocalReturnKey1)) ex.value() else throw ex } After this patch: @scala.annotation.tailrec final def bad(): Unit = { case <synthetic> val x1: Int = 1; case5(){ if (2.==(x1)) { <synthetic> val x2: Int = x1; matchEnd4({ try { return () } catch { case (e @ (_: ClassNotFoundException)) => () }; TailrecAfterTryCatch.this.bad() }) } else case6() }; case6(){ matchEnd4(throw new MatchError(x1)) }; matchEnd4(x: Unit){ x } }
| * | Merge pull request #1895 from JamesIry/SI_6963_2.10.xPaul Phillips2013-01-153-0/+6
| |\ \ | | | | | | | | SI-6963 Deprecates -Xmigration switch
| | * | SI-6963 Deprecates -Xmigration switchJames Iry2013-01-143-0/+6
| | |/ | | | | | | | | | | | | | | | -Xmigration is specific to the 2.7 to 2.8 upgrade and is no longer relevant. There is no plan to maintain it so it will be removed. This commit deprecates it in anticipation.
| * | Merge pull request #1888 from retronym/ticket/6675Paul Phillips2013-01-156-0/+36
| |\ \ | | | | | | | | SI-6675 -Xlint arity enforcement for extractors
| | * | SI-6675 Test new warning under -Xoldpatmat.Jason Zaugg2013-01-153-0/+18
| | | | | | | | | | | | | | | | This commit should be discarded when merging to master.
| | * | SI-6675 -Xlint arity enforcement for extractorsJason Zaugg2013-01-153-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Extractor Patterns changed in 2.10.0 to implement the letter of the spec, which allows a single binding to capture an entire TupleN. But this can hide arity mismatches, especially if the case body uses the bound value as an `Any`. This change warns when this happens under -Xlint.
| * | | Merge pull request #1879 from adriaanm/ticket-6955Paul Phillips2013-01-152-0/+27
| |\ \ \ | | | | | | | | | | SI-6955 switch emission no longer foiled by type alias
| | * | | SI-6955 switch emission no longer foiled by type aliasAdriaan Moors2013-01-102-0/+27
| | | | | | | | | | | | | | | | | | | | | | | | | dealias the type of the scrutinee before checking it's switchable now with tests! (using IcodeTest since javap is not available everywhere)
| * | | | Merge pull request #1894 from retronym/ticket/6082Adriaan Moors2013-01-142-0/+15
| |\ \ \ \ | | | | | | | | | | | | SI-6082 Conditionally expand @ann(x) to @ann(value = x)
| | * | | | SI-6082 Conditionally expand @ann(x) to @ann(value = x)Jason Zaugg2013-01-132-0/+15
| | | |_|/ | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ... if the annotation has an argument with the name `value`. Doing so unconditionally obscures error messages. We still require that arguments to ClassFileAnnotations are named, other than for this special case.
| * | | | Merge pull request #1890 from retronym/ticket/5440Adriaan Moors2013-01-143-0/+13
| |\ \ \ \ | | | | | | | | | | | | SI-5440 Test case for exhaustiveness check
| | * | | | SI-5440 Test case for exhaustiveness checkJason Zaugg2013-01-133-0/+13
| | | |_|/ | | |/| | | | | | | | | | | | Reported against patmatclassic, working in virtpatmat.
| * | | | Merge pull request #1889 from retronym/ticket/5340Adriaan Moors2013-01-142-0/+35
| |\ \ \ \ | | | | | | | | | | | | SI-5340 Change println to log
| | * | | | SI-5340 Change println to logJason Zaugg2013-01-132-0/+35
| | |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | An esoteric implicit search could trigger an "amb prefix ..." message to standard out. Now the message has been improved and sent to the logger.
| * | | | Merge pull request #1878 from adriaanm/ticket-6925Adriaan Moors2013-01-142-0/+27
| |\ \ \ \ | | | | | | | | | | | | SI-6925 use concrete type in applyOrElse's match's selecto
| | * | | | rework partial function synthesisAdriaan Moors2013-01-091-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | no behavioral changes, just highly overdue cleanup some TODOs for further improvements
| | * | | | SI-6925 use concrete type in applyOrElse's match's selectorAdriaan Moors2013-01-091-0/+9
| | | |_|/ | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix a regression introduced in 28483739c3: PartialFunction synthesis was broken so that we'd get: ``` scala> def f[T](xs: Set[T]) = xs collect { case x => x } f: [T](xs: Set[T])scala.collection.immutable.Set[_ <: T] ``` rather than ``` scala> def f[T](xs: Set[T]) = xs collect { case x => x } f: [T](xs: Set[T])scala.collection.immutable.Set[T] ```
| * | | | Merge pull request #1876 from adriaanm/ticket-5189-infAdriaan Moors2013-01-142-0/+14
| |\ \ \ \ | | | | | | | | | | | | SI-5189 detect unsoundness when inferring type of match
| | * | | | SI-5189 detect unsoundness when inferring type of matchAdriaan Moors2013-01-092-0/+14
| | |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GADT skolems encode type slack that results from pattern matching on variant type constructors I thought they would not longer be relevant after cases have been typed, and since they caused weird issues with the old pattern matcher, I deskolemized in typedCase however, when we don't have an expected type for the match, we need to keep the skolems around until the skolemized type makes it out of the match and it becomes the result of type inference for that match when you do have an expected type, it will propagate to the case-level and the confrontation will thus already take place when typing individual cases
| * | | | Merge pull request #1891 from retronym/ticket/6126Adriaan Moors2013-01-141-0/+8
| |\ \ \ \ | | | | | | | | | | | | SI-6126 Test case for varargs of tagged primitives.
| | * | | | SI-6126 Test case for varargs of tagged primitives.Jason Zaugg2013-01-131-0/+8
| | | |_|/ | | |/| | | | | | | | | | | | | | | | | This started working after the merge fe1110f. I didn't track down precisely which commit was responsible beyond that.
| * / | | SI-5954 Implementation restriction preventing companions in package objsJames Iry2013-01-137-0/+67
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Companion objects (and thus also case classes) in package objects caused an assert about an overloaded symbol when everything was compiled twice. It's a hairy problem that doesn't fit in 2.10.1. So this fix adds an implementation restriction. It also has a test to make sure the error messages are clean and reasonably friendly, and does not catch other things defined in package objects. The test includes a commented out test in case somebody thinks they've solved the underlying problem. A handful of tests were falling afoul of the new implementation restriction. I verified that they do in fact fail on second compile so they aren't false casualties. But they do test real things we'd like to work once the re-compile issue is fixed. So I added a -X flag to disable the implementation restriction and made all the tests accidentally clobbered by the restriction use that flag.
| * | | Merge pull request #1859 from retronym/ticket/6912Paul Phillips2013-01-122-0/+13
| |\ \ \ | | |_|/ | |/| | SI-6912 Avoid a typer cycle in overload resolution.
| | * | SI-6912 Avoid a typer cycle in overload resolution.Jason Zaugg2013-01-082-0/+13
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c800d1fe, and followup commits 1ddc9358 and b10b5821 modified error handling in `Infer#inferExprAlternative`. After these changes, this method could fail to resolve the overloaded alternative if: best != NoSymbol && !competing.isEmpty && !noAlternatives && pt.isErroneous This commit calls `setError` in that case, which prevents the cycle in `adapt`. While I didn't extract a reproduction from the original code base, I've included a test case that exhibits the same symptom. It was actually pretty tough to find an program that got close to this code path, but luckilly we've been pretty close to this bug in SI-5553 / 4f99c2e5, and those test cases formed the basis for this one.
| * | Merge pull request #1869 from retronym/backport/1826Paul Phillips2013-01-1146-110/+156
| |\ \ | | | | | | | | Backport of SI-6846.
| | * | Backport of SI-6846.Jason Zaugg2013-01-0846-110/+156
| | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Squashed commit of the following: commit 55806cc0e6177820c12a35a18b4f2a12dc07bb39 Author: Paul Phillips <paulp@improving.org> Date: Wed Dec 19 07:32:19 2012 -0800 SI-6846, regression in type constructor inference. In 658ba1b4e6 some inference was gained and some was lost. In this commit we regain what was lost and gain even more. Dealiasing and widening should be fully handled now, as illustrated by the test case. (cherry picked from commit dbebcd509e4013ce02655a2687b27d0967b3650e) commit e6ef58447d0f4ef6de956fcc03ee283bb9028c02 Author: Paul Phillips <paulp@improving.org> Date: Fri Dec 21 15:11:29 2012 -0800 Cleaning up type alias usage. I determined that many if not most of the calls to .normalize have no intent beyond dealiasing the type. In light of this I went call site to call site knocking on doors and asking why exactly they were calling any of .normalize .widen.normalize .normalize.widen and if I didn't like their answers they found themselves introduced to 'dropAliasesAndSingleTypes', the recursive widener and dealiaser which I concluded is necessary after all. Discovered that the object called 'deAlias' actually depends upon calling 'normalize', not 'dealias'. Decided this was sufficient cause to rename it to 'normalizeAliases'. Created dealiasWiden and dealiasWidenChain. Dropped dropAliasesAndSingleTypes in favor of methods on Type alongside dealias and widen (Type#dealiasWiden). These should reduce the number of "hey, the type alias doesn't work" bugs. (cherry picked from commit 3bf51189f979eb0dd41744ca844fd12dfdaa0dee) Conflicts: src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala commit c1d8803cea1523f458730103386d8e14324a9446 Author: Paul Phillips <paulp@improving.org> Date: Sat Dec 22 08:13:48 2012 -0800 Shored up a hidden dealiasing dependency. Like the comment says: // This way typedNew always returns a dealiased type. This // used to happen by accident for instantiations without type // arguments due to ad hoc code in typedTypeConstructor, and // annotations depended on it (to the extent that they worked, // which they did not when given a parameterized type alias // which dealiased to an annotation.) typedTypeConstructor // dealiases nothing now, but it makes sense for a "new" to // always be given a dealiased type. PS: Simply running the test suite is becoming more difficult all the time. Running "ant test" includes time consuming activities of niche interest such as all the osgi tests, but test.suite manages to miss the continuations tests. (cherry picked from commit 422f461578ae0547181afe6d2c0c52ea1071d37b) commit da4748502792b260161baa10939554564c488051 Author: Paul Phillips <paulp@improving.org> Date: Fri Dec 21 12:39:02 2012 -0800 Fix and simplify typedTypeConstructor. Investigating the useful output of devWarning (-Xdev people, it's good for you) led back to this comment: "normalize to get rid of type aliases" You may know that this is not all the normalizing does. Normalizing also turns TypeRefs with unapplied arguments (type constructors) into PolyTypes. That means that when typedParentType would call typedTypeConstructor it would find its parent had morphed into a PolyType. Not that it noticed; it would blithely continue and unwittingly discard the type arguments by way of appliedType (which smoothly logged the incident, thank you appliedType.) The simplification of typedTypeConstructor: There was a whole complicated special treatment of AnyRef here which appears to have become unnecessary. Removed special treatment and lit a candle for regularity. Updated lots of tests regarding newly not-so-special AnyRef. (cherry picked from commit 394cc426c1ff1da53146679b4e2995ece52a133e) commit 1f3c77bacb2fbb3ba9e4ad0a8a733e0f9263b234 Author: Paul Phillips <paulp@improving.org> Date: Fri Dec 21 15:06:10 2012 -0800 Removed dead implementation. Another "attractive nuisance" burning off time until I realized it was commented out. (cherry picked from commit ed40f5cbdf35d09b02898e9c0950b9bd34c1f858)
| * / SI-6928, VerifyError with self reference to super.Paul Phillips2013-01-074-0/+28
| |/ | | | | | | | | | | | | | | | | A bug in typers mishandled varargs. We should get more aggressive about eliminating all the ad hoc parameter/argument handling code spread everywhere. For varargs especially: any code which tries to make an adjustment based on a repeated parameter is more likely to be wrong than right. In aggregate these reinventions are a huge source of bugs.
* | Merge pull request #1880 from som-snytt/issue/6894-javap-appPaul Phillips2013-01-1510-0/+136
|\ \ | | | | | | Fixes and features for javap (fixing SI-6894)
| * | Restore pending repl-javap tests that now succeed under java 6.Som Snytt2013-01-118-0/+118
| | | | | | | | | | | | Knock on wood.
| * | Fixes and features for javap (fixing SI-6894)Som Snytt2013-01-112-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Output filtering is refactored for javap6. That means javap6 also supports -raw. Handling of # is: Foo#foo filter on foo, Foo# filter on apply, -fun Foo#foo for anonfuns of foo, -fun Foo# anonfuns filtering on apply. One is loath to add command options, so it's not possible to ask for "only apply methods in anonfuns pertaining to a method." Hypothetical syntax to say "show me the apply only": -fun Foo#foo(), for future reference.
* | | Merge pull request #1881 from adriaanm/rebase-1879-masterPaul Phillips2013-01-152-0/+29
|\ \ \ | | | | | | | | SI-6955 switch emission no longer foiled by type alias
| * | | SI-6955 switch emission no longer foiled by type aliasAdriaan Moors2013-01-112-0/+29
| |/ / | | | | | | | | | | | | | | | | | | dealiasWiden the type of the scrutinee before checking it's switchable now with tests! (using IcodeTest since javap is not available everywhere) rebase of #1879
* | | Merge pull request #1897 from retronym/ticket/6964Paul Phillips2013-01-15153-759/+0
|\ \ \ | | | | | | | | SI-6964 Remove build managers, both simple and refined.
| * | | SI-6964 Remove build managers, both simple and refined.Jason Zaugg2013-01-12153-759/+0
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | Deprecated in 2.10.0, out to pasture in 2.11.0. Users are advised to migrate to: https://github.com/typesafehub/zinc http://www.scala-sbt.org/
* | | Merge pull request #1803 from paulp/issue/6375Paul Phillips2013-01-153-0/+95
|\ \ \ | | | | | | | | SI-6375, warn on lost annotation.
| * | | Tweaked meta-annotation error based on feedback.Paul Phillips2013-01-141-8/+8
| | | |
| * | | SI-6375, warn on lost annotation.Paul Phillips2013-01-143-0/+95
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Annotations on abstract vals which are not meta-annotated were silently discarded. Still discarded, only less silently. I warned on as many "lost annotation" situations as I was reasonably able to cover without false positives.
* | | | Merge pull request #1877 from adriaanm/rebase-1876-masterAdriaan Moors2013-01-142-0/+14
|\ \ \ \ | | | | | | | | | | SI-5189 detect unsoundness when inferring type of match
| * | | | SI-5189 detect unsoundness when inferring type of matchAdriaan Moors2013-01-142-0/+14
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GADT skolems encode type slack that results from pattern matching on variant type constructors I thought they would not longer be relevant after cases have been typed, and since they caused weird issues with the old pattern matcher, I deskolemized in typedCase however, when we don't have an expected type for the match, we need to keep the skolems around until the skolemized type makes it out of the match and it becomes the result of type inference for that match when you do have an expected type, it will propagate to the case-level and the confrontation will thus already take place when typing individual cases
* / / / SI-6966 Fix regression in implicit resolutionJason Zaugg2013-01-121-0/+17
|/ / / | | | | | | | | | | | | Reverts this line: 9c09c17#L50L671. That value was apparantly discarded intentionally.
* | | Merge commit 'refs/pull/1844/head' into merge/pr-1844Paul Phillips2013-01-1125-12/+88
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * commit 'refs/pull/1844/head': macroExpandAll is now triggered by typed SI-5923 adapt macros when they are deferred generalizes macroExpand typedPrimaryConstrBody now returns supercall more precise errors for macros parentTypes => typedParentTypes changes isTermMacro checks to something more universal fixes printing of AppliedTypeTree adds Trees.replace(Tree, Tree) makes macro override error more consistent refactors handling of macros in repl SI-5903 extractor macros do work adds c.macroRole Conflicts: src/compiler/scala/tools/nsc/typechecker/Macros.scala src/compiler/scala/tools/nsc/typechecker/Typers.scala
| * | | macroExpandAll is now triggered by typedEugene Burmako2013-01-094-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously delayed macro expansions (the sole purpose of macroExpandAll) were triggered by `typedArgs`. Probably I wanted to save CPU cycles on not checking whether we have pending macro expansions on every iteration of typecheck. However this optimization is uncalled for, because the check just entails reading a var, therefore benefits of the current approach are negliible, whereas the robustness hit is tangible. After delayed macro expansion mechanism became more robust, it exposed a bug, well-hidden before. If one first delays a macro and then finds out that the expandee is erroneous, subsequent `macroExpandAll` will crash, because it expects a macro runtime attachment to be present. Previously the erroneous code path never got triggered, because the macro expansion never commenced. Luckily the fix was easy.
| * | | SI-5923 adapt macros when they are deferredEugene Burmako2013-01-099-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Amazingly enough, the fix for the "macro not expanded" problem was super easy. (And I remember spending a day or two trying to find a quick fix somewhen around Scala Days 2012!) The problem was in the implementation of the macro expansion trigger, which was buried in a chain of if-elif-elif. This meant that macro expansion was mutually exclusive with a lot of important adaptations, e.g. with `instantiate`. More precisely, if an expandee contains an undetparam, its expansion should be delayed until all its undetparams are inferred and then retried later. Sometimes such inference can only happen upon a call to instantiate in one of the elif's coming after the macro expansion elif. However this elif would never be called for expandees, because control flow would always enter the macro expansion branch preceding the inference branch. Consequences of this fix are vast. First of all, we can get rid of the "type parameter must be specified" hack. Secondly and most importantly, we can now remove the `materializeImplicit` method from Implicits and rely on implicit macros to materialize tags for us. (This is a tricky change, and I'll do it later after we merge as much of my pending work as possible). Finally, we learn that the current scheme of interaction between macros, type inference and implicits is, in principle, sound!
| * | | makes macro override error more consistentEugene Burmako2013-01-093-3/+3
| | | |
| * | | refactors handling of macros in replEugene Burmako2013-01-092-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Macros now have a dedicated member handler, so that the logic of their processing doesn't get mixed up with vanilla DefHandler. I've also factored out an abstract MacroHandler to provides a basis to build the upcoming type macro handler upon.
| * | | SI-5903 extractor macros do workEugene Burmako2013-01-098-0/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Apparently it is already possible to use macros to customize pattern matching as described in the comments to the aforementioned JIRA issue. What's even better - with the incoming addition of c.introduceTopLevel it becomes possible to generate arbitrarily complex unappliers, even with heterogeneous types of arguments varying from expansion to expansion
* | | | Merge pull request #1874 from paulp/pr/mode-value-classPaul Phillips2013-01-111-1/+1
|\ \ \ \ | |_|/ / |/| | | Made "mode" into a value class.