| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
```
|
|\
| |
| | |
SI-8893 Restore linear perf in TailCalls with nested matches
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Another excellent test suggestion by Dear Reviewer.
After tail calls, the transform results in:
```
def tick(i: Int): Unit = {
<synthetic> val _$this: Test.type = Test.this;
_tick(_$this: Test.type, i: Int){
if (i.==(0))
()
else
if (i.==(42))
{
Test.this.tick(0);
_tick(Test.this, i.-(1).asInstanceOf[Int]())
}
else
_tick(Test.this, i.-(1).asInstanceOf[Int]()).asInstanceOf[Unit]()
}
};
```
We test this by mostly exercising the tail-recursive code path with
a level of recursion that would overflow the stack if we weren't
using jumps.
|
| |
| |
| |
| |
| |
| |
| |
| | |
As suggested during code review, this test checks that
the tailcalls phase recurses appropriately below a method
that doesn and does not itself tail call. The test case is
based on the pattern of code that to trigger super-linear
performance in this transform.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Compilation perfomance of the enclosed test regressed when the
new pattern matcher was introduced, specifically when the tail
call elimination phase was made aware of its tree shapes in cd3d34203.
The code added in that commit detects an application to a tail label
in order to treat recursive calls in the argument as in tail position.
If the transform of that argument makes no change, it falls
back to `rewriteApply`, which transforms the argument again
(although this time on a non-tail-position context.)
This commit avoids the second transform by introducing a flag
to `rewriteApply` to mark the arguments are pre-transformed.
I don't yet see how that fixes the exponential performance, as
on the surface it seems like a constant factor improvement.
But the numbers don't lie, and we can now compile the test
case in seconds, rather than before when it was running for
> 10 minutes.
This test case was based on a code pattern generated by the Avro
serializer macro in:
https://github.com/paytronix/utils-open/tree/release/2014/ernststavrosgrouper
The exponential performance in that context is visualed here:
https://twitter.com/dridus/status/519544110173007872
Thanks for @rmacleod2 for minimizing the problem.
|
|\ \
| | |
| | | |
Make global-showdef a DirectTest
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
You can only show one class or object at a time,
but we can show one of each to reduce the compilations
for this test.
It seems the original issue happened because the test
started to create class files after SI-8217.
So, also stop compile after typer, because why stress the kitteh.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The test test/files/run/global-showdef.scala was outputting
to the cwd instead of the test output dir.
Good behavior is now inherited from DirectTest.
Test frameworks, of any ilk or capability, rock.
|
|\ \ \
| | | |
| | | | |
SI-4950 Add tests, looks like it has been fixed earlier
|
| |/ / |
|
|\ \ \
| | | |
| | | | |
SI-8943 Handle non-public case fields in pres. compiler
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When a case class is type checked, synthetic methods are added,
such as the `hashCode`/`equals`, implementations of the `Product`
interface. At the same time, a case accessor method is added for
each non-public constructor parameter. This the accessor for a
parameter named `x` is named `x$n`, where `n` is a fresh suffix.
This is all done to retain universal pattern-matchability of
case classes, irrespective of access. What is the point of allowing
non-public parameters if pattern matching can subvert access? I
believe it is to enables private setters:
```
case class C(private var x: String)
scala> val x = new C("")
x: C = C()
scala> val c = new C("")
c: C = C()
scala> val C(x) = c
x: String = ""
scala> c.x
<console>:11: error: variable x in class C cannot be accessed in C
c.x
^
scala> c.x = ""
<console>:13: error: variable x in class C cannot be accessed in C
val $ires2 = c.x
^
<console>:10: error: variable x in class C cannot be accessed in C
c.x = ""
^
```
Perhaps I'm missing additional motivations.
If you think scheme sounds like a binary compatiblity nightmare,
you're right: https://issues.scala-lang.org/browse/SI-8944
`caseFieldAccessors` uses the naming convention to find the right
accessor; this in turn is used in pattern match translation.
The accessors are also needed in the synthetic `unapply` method
in the companion object. Here, we must tread lightly to avoid
triggering a typechecking cycles before; the synthesis of that method
is not allowed to force the info of the case class.
Instead, it uses a back channel, `renamedCaseAccessors` to see
which parameters have corresonding accessors.
This is pretty flaky: if the companion object is typechecked
before the case class, it uses the private param accessor directly,
which it happends to have access to, and which duly gets an
expanded name to allow JVM level access. If the companion
appears afterwards, it uses the case accessor method.
In the presentation compiler, it is possible to typecheck a source
file more than once, in which case we can redefine a case class. This
uses the same `Symbol` with a new type completer. Synthetics must
be re-added to its type.
The reported bug occurs when, during the second typecheck, an entry
in `renamedCaseAccessors` directs the unapply method to use `x$1`
before it has been added to the type of the case class symbol.
This commit clears corresponding entries from that map when we
detect that we are redefining a class symbol.
Case accessors are in need of a larger scale refactoring. But I'm
leaving that for SI-8944.
|
|\ \ \
| | | |
| | | | |
SI-8941 Idempotent presentation compilation of implicit classes
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
A retrospective test case which covers typechecking idempotency which
was introduced in 0b78a0196 / 148736c3df. It also tests the
implicit class handling, which was fixed in the previous commit.
It is difficult to test this using existing presentation compiler
testing infrastructure, as one can't control at which point during
the first typechecking the subesquent work item will be noticed.
Instead, I've created a test with a custom subclass of
`interactive.Global` that allows precise, deterministic control
of when this happens. It overrides `signalDone`, which is called
after each tree is typechecked, and watches for a defintion with
a well known name. At that point, it triggers a targetted typecheck
of the tree marked with a special comment.
It is likely that this approach can be generalized to a reusable
base class down the track. In particular, I expect that some of
the nasty interactive ScalaDoc bugs could use this single-threaded
approach to testing the presentation compiler.
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When we name an implicit class, `enterImplicitWrapper` is called,
which enters the symbol for the factory method into the
owning scope. The tree defining this factory method is stowed into
`unit.synthetics`, from whence it will be retrieved and incorporated
into the enclosing tree during typechecking (`addDerivedTrees`).
The entry in `unit.synthetics` is removed at that point.
However, in the presentation compiler, we can typecheck a unit
more than once in a single run. For example, if, as happens
in the enclosed test, a call to ask for a type at a given
position interrupts type checking of the entire unit, we
can get into a situation whereby the first type checking
invocation has consumed the entry from `unit.synthetics`,
and the second will crash when it can't find an entry.
Similar problems have been solved in the past in
`enterExistingSym` in the presentation compiler. This method
is called when the namer encounters a tree that already has
a symbol attached. See 0b78a0196 / 148736c3df.
This commit takes a two pronged approach.
First, `enterExistingSym` is extended to handle implicit classes.
Any previous factory method in the owning scope is removed, and
`enterImplicitWrapper` is called to place a new tree for the factory
into `unit.synthetics` and to enter its symbol into the owning scope.
Second, the assertions that could be tripped in `addDerivedTrees`
and in `ImplicitClassWrapper#derivedSym` have been converted to
positioned errors.
The first change is sufficient to fix this bug, but the second
is also enough to make the enclosed test pass, and has been retained
as an extra layer of defence.
|
|\ \ \
| | | |
| | | | |
SI-3439 Fix use of implicit constructor params in super call
|
| | | | |
|
| | |/
| |/|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When typechecking the primary constructor body, the symbols of
constructor parameters of a class are owned by the class's owner.
This is done make scoping work; you shouldn't be able to refer to
class members in that position.
However, other parts of the compiler weren't so happy about
this arrangement. The enclosed test case shows that our
checks for invalid, top-level implicits was spuriously triggered,
and implicit search itself would fail.
Furthermore, we had to hack `Run#compiles` to special case
top-level early-initialized symbols. See SI-7264 / 86e6e9290.
This commit:
- introduces an intermediate local dummy term symbol which
will act as the owner for constructor parameters and early
initialized members
- adds this to the `Run#symSource` map if it is top level
- simplifies `Run#compiles` accordingly
- tests this all in a top-level class, and one nested in
another class.
|
|\ \ \
| | | |
| | | | |
SI-8934 Fix whitebox extractor macros in the pres. compiler
|
| | |/
| |/|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The code that "aligns" patterns and extractors assumes that it can
look at the type of the unapply method to figure the arity of the
extractor.
However, the result type of a whitebox macro does not tell the
whole story, only after expanding an application of that macro do
we know the result type.
During regular compilation, this isn't a problem, as the macro
application is expanded to a call to a synthetic unapply:
{
class anon$1 {
def unapply(tree: Any): Option[(Tree, List[Treed])]
}
new anon$1
}.unapply(<unapply selector>)
In the presentation compiler, however, we now use
`-Ymacro-expand:discard`, which expands macros only to compute
the type of the application (and to allow the macro to issue
warnings/errors). The original application is retained in the
typechecked tree, modified only by attributing the potentially-sharper
type taken from the expanded macro.
This was done to improve hyperlinking support in the IDE.
This commit passes `sel.tpe` (which is the type computed by the
macro expansion) to `unapplyMethodTypes`, rather than using
the `finalResultType` of the unapply method.
This is tested with a presentation compiler test (which closely
mimics the reported bug), and with a pos test that also exercises
`-Ymacro-expand:discard`. Prior to this patch, they used to fail with:
too many patterns for trait api: expected 1, found 2
|
|\ \ \
| |/ /
|/| | |
FSC / REPL Bug Bonanza
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
We needed to hop from the enum's owner to its companion
module in an early phase of the compiler.
The enclosed test used to fail when this lookup returned
NoSymbol on the second run of the resident compiler when
triggered from `MixinTransformer`: the lookup didn't work
after the flatten info transform. This is related to the
fact that module classes are flattened into the enclosing
package, but module accessors remain in the enclosing class.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The transformation of applications to specialized methods
relies on the owner of said method having had the specialization
info transform run which stashes a bunch of related data into
per-run caches such as `SpecializeTypes#{typeEnv}`.
Recently, we found that per-run caches didn't quite live up
to there name, and in fact weren't being cleaned up before
a new run. This was remedied in 00e11ff.
However, no good deed goes unpunished, and this led to a
regression in specialization in the REPL and FSC.
This commit makes two changes:
- change the specialization info tranformer to no longer
directly enter specialized methods into the `info` of whatever
the current phase happens to be. This stops them showing up
`enteringTyper` of the following run.
- change `adaptInfos` to simply discard all but the oldest
entry in the type history when bringing a symbol from one
run into the next. This generalizes the approach taken to
fix SI-7801. The specialization info transformer will now
execute in each run, and repopulate `typeEnv` and friends.
I see that we have a seemingly related bandaid for this sort
of problem since 08505bd4ec. In a followup, I'll try to revert
that.
|
|\ \ \
| | | |
| | | | |
SI-8900 Don't assert !isDelambdafyFunction, it may not be accurate
|
| | |/
| |/|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The implementations of isAnonymousClass, isAnonymousFunction,
isDelambdafyFunction and isDefaultGetter check if a specific substring
(eg "$lambda") exists in the symbol's name.
SI-8900 shows an example where a class ends up with "$lambda" in its
name even though it's not a delambdafy lambda class. In this case the
conflict seems to be introduced by a macro. It is possible that the
compiler itself never introduces such names, but in any case, the
above methods should be implemented more robustly.
This commit is band-aid, it fixes one specific known issue, but there
are many calls to the mentioned methods across the compiler which
are potentially wrong.
Thanks to Jason for the test case!
|
|\ \ \
| | | |
| | | | |
[nomerge] SI-8899 Revert "SI-8627 make Stream.filterNot non-eager"
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This reverts commit 9276a1205f74fdec74206209712831913e93f359.
The change is not binary compatible, See discussion on SI-8899. Making
filterImpl non-private changes its call-sites (within TraversableLike)
from INVOKESTATIC to INVOKEINTERFACE. Subclasses of TraversableLike
compiled before this change don't have a mixin for filterImpl.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Test case by Jason.
RefChecks adds the lateMETHOD flag lazily in its info transformer.
This means that forcing the `sym.info` may change the value of
`sym.isMethod`.
0ccdb151f introduced a check to force the info in isModuleNotMethod,
but it turns out this leads to errors on stub symbols (SI-8907).
The responsibility to force info is transferred to callers, which
is the case for other operations on symbols, too.
|
|\ \
| | |
| | | |
SI-8894 dealias when looking at tuple components
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Classic bait-and-switch: `isTupleType` dealiases, but `typeArgs` does not.
When deciding with `isTupleType`, process using `tupleComponents`.
Similar for other combos. We should really enforce this using extractors,
and only decouple when performance is actually impacted.
|
|/ /
| |
| |
| |
| |
| |
| | |
When buffering, we must report the ambiguity error to avoid a stack overflow.
When the error refers to erroneous types/symbols,
we don't report it directly to the user,
because there will be an underlying error that's the root cause.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Note that I removed the check to ignore @deprecated:
- @deprecated extends StaticAnnotation, so they aren't
supposed to show up in the RuntimeInvisibleAnnotation
attribute anyway, and the earlier check for "extends
ClassfileAnnotationClass" makes this check superflous
anyway.
- Otherwise, if @deprecated was extending
ClassfileAnnotationClass it would seem inconsistent
that we don't emit @deprecated, but would do so for
@deprecatedOverriding, @deprecatedInheritance, etc.
Anyway, due to ClassfileAnnotation not working in
Scala, and the additional check which only allows
Java-defined annotations, this is pretty pointless
from every perspective.
|
|\ \
| | |
| | | |
SI-8843 AbsFileCL acts like a CL
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Let the AbstractFileClassLoader override just the usual suspects.
Normal delegation behavior should ensue.
That's instead of overriding `getResourceAsStream`, which was intended
that "The repl classloader now works more like you'd expect a classloader to."
(Workaround for "Don't know how to construct an URL for something which exists
only in memory.")
Also override `findResources` so that `getResources` does the obvious thing,
namely, return one iff `getResource` does.
The translating class loader for REPL only special-cases `foo.class`: as
a fallback, take `foo` as `$line42.$read$something$foo` and try that class file.
That's the use case for "works like you'd expect it to."
There was a previous fix to ensure `getResource` doesn't take a class name.
The convenience behavior, that `classBytes` takes either a class name or a resource
path ending in ".class", has been promoted to `ScalaClassLoader`.
|
|\ \ \
| | | |
| | | | |
SI-6502 Repl reset/replay take settings args
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The reset and replay commands take arbitrary command line args.
When settings args are supplied, the compiler is recreated.
For uniformity, the settings command performs only the usual
arg parsing: use -flag:true instead of +flag, and clearing a
setting is promoted to the command line, so that -Xlint: is not
an error but clears the flags.
```
scala> maqicode.Test main null
<console>:8: error: not found: value maqicode
maqicode.Test main null
^
scala> :reset -classpath/a target/scala-2.11/sample_2.11-1.0.jar
Resetting interpreter state.
Forgetting all expression results and named terms: $intp
scala> maqicode.Test main null
Hello, world.
scala> val i = 42
i: Int = 42
scala> s"$i is the loneliest numbah."
res1: String = 42 is the loneliest numbah.
scala> :replay -classpath ""
Replaying: maqicode.Test main null
Hello, world.
Replaying: val i = 42
i: Int = 42
Replaying: s"$i is the loneliest numbah."
res1: String = 42 is the loneliest numbah.
scala> :replay -classpath/a ""
Replaying: maqicode.Test main null
<console>:8: error: not found: value maqicode
maqicode.Test main null
^
Replaying: val i = 42
i: Int = 42
Replaying: s"$i is the loneliest numbah."
res1: String = 42 is the loneliest numbah.
```
Clearing a clearable setting:
```
scala> :reset -Xlint:missing-interpolator
Resetting interpreter state.
scala> { val i = 42 ; "$i is the loneliest numbah." }
<console>:8: warning: possible missing interpolator: detected interpolated identifier `$i`
{ val i = 42 ; "$i is the loneliest numbah." }
^
res0: String = $i is the loneliest numbah.
scala> :reset -Xlint:
Resetting interpreter state.
Forgetting this session history:
{ val i = 42 ; "$i is the loneliest numbah." }
scala> { val i = 42 ; "$i is the loneliest numbah." }
res0: String = $i is the loneliest numbah.
```
|
|\ \ \ \
| | | | |
| | | | | |
SI-8731 warning if @switch is ignored
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
For matches with two or fewer cases, @switch is ignored. This should
not happen silently.
|
|\ \ \ \ \
| |_|_|_|/
|/| | | | |
SI-8888 Avoid ClassFormatError under -Ydelambdafy:method
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The pattern matcher phase (conceivably, among others) can generate
code that binds local `Ident`s symbolically, rather than according
to the lexical scope. This means that a lambda can capture more than
one local of the same name.
In the enclosed test case, this ends up creating the following
tree after delambdafy
[[syntax trees at end of delambdafy]] // delambday-patmat-path-dep.scala
matchEnd4({
case <synthetic> val x1: Object = (x2: Object);
case5(){
if (x1.$isInstanceOf[C]())
{
<synthetic> val x2#19598: C = (x1.$asInstanceOf[C](): C);
matchEnd4({
{
(new resume$1(x2#19598, x2#19639): runtime.AbstractFunction0)
};
scala.runtime.BoxedUnit.UNIT
})
}
else
case6()
};
...
})
...
<synthetic> class resume$1 extends AbstractFunction0 {
<synthetic> var x2: C = null;
<synthetic> var x2: C = null;
...
}
After this commit, the var members of `resume$1` are given fresh
names, rather than directly using the name of the captured var:
<synthetic> var x2$3: C = null;
<synthetic> var x2$4: C = null;
|
|\ \ \ \
| | | | |
| | | | | |
SI-7746 fix unspecifc non-exhaustiveness warnings and non-determinism in pattern matcher (2.11)
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Fixes non-determinism within the DPLL algorithm and disallows
infeasible counter examples directly in the formula.
The function to compute all solutions was flawed and thus only
returned a subset of the solutions. The algorithm would stop too soon
and thus depending on the ordering of the symbols return more or less
solutions. I also added printing a warning when the search was stopped
because the max recursion depth was reached. This is very useful as an
explanation of spuriously failing regression tests, since less counter
examples might be reported. In such a case the recursion depth should
be set to infinite by adding `-Ypatmat-exhaust-depth off`.
The mapping of the solutions of the DPLL algorithm to counter examples
has been adapted to take the additional solutions from the
solver into account:
Consider for example `t8430.scala`:
```Scala
sealed trait CL3Literal
case object IntLit extends CL3Literal
case object CharLit extends CL3Literal
case object BooleanLit extends CL3Literal
case object UnitLit extends CL3Literal
sealed trait Tree
case class LetL(value: CL3Literal) extends Tree
case object LetP extends Tree
case object LetC extends Tree
case object LetF extends Tree
object Test {
(tree: Tree) => tree match {case LetL(CharLit) => ??? }
}
```
This test contains 2 domains, `IntLit, CharLit, ...` and `LetL, LetP, ...`,
the corresponding formula to check exhaustivity looks like:
```
V1=LetC.type#13 \/ V1=LetF.type#14 \/ V1=LetL#11 \/ V1=LetP.type#15 /\
V2=BooleanLit.type#16 \/ V2=CharLit#12 \/ V2=IntLit.type#17 \/ V2=UnitLit.type#18 /\
-V1=LetL#11 \/ -V2=CharLit#12 \/ \/
```
The first two lines assign a value of the domain to the scrutinee (and
the correponding member in case of `LetL`) and prohibit the counter
example `LetL(CharLit)` since it's covered by the pattern match. The
used Boolean encoding allows that scrutinee `V1` can be equal to
`LetC` and `LetF` at the same time and thus, during enumeration of all
possible solutions of the formula, such a solution will be found,
since only one literal needs to be set to true, to satisfy that
clause. That means, if at least one of the literals of such a clause
was in the `unassigned` list of the DPLL procedure, we will get
solutions where the scrutinee is equal to more than one element of the
domain.
A remedy would be to add constraints that forbid both literals
to be true at the same time. His is infeasible for big domains (see
`pos/t8531.scala`), since we would have to add a quadratic number of
clauses (one clause for each pair in the domain). A much simpler
solution is to just filter the invalid results. Since both values for
`unassigned` literals are explored, we will eventually find a valid
counter example.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Revert "Disable flaky presentation compiler test."
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This reverts commit 8986ee4fd56c53d563165d992185c6c532f35790.
Scaladoc seems to work reliably for 2.11.x. We are using it in the IDE builds and haven't noticed any
flakiness, so we'd like to get reinstate this test.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
SI-8291 Fix implicitNotFound message with type aliases
|
| | |_|/ / /
| |/| | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This pattern of code is typically a bug:
if (f(tp.typeSymbol)) {
g(tp.typeArgs)
}
Intead, one needs to take the base type of `tp` wrt `tp.typeSymbol`.
This commit does exactly that when formatting the `@implicitNotFound`
custom error message.
Patch found on the back of an envelope in the handwriting of @adriaanm
|
|\ \ \ \ \ \
| |/ / / / /
|/| | | | | |
SI-8845 Control flow pot-pourri crashes GenASM, but not -BCode
|
| | |_|/ /
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Given that we'll switch to GenBCode in 2.12, the test case
showing the bug is fixed under that option is all I plan to
offer for this bug.
The flags file contains `-Ynooptimize` to stay locked into
`GenBCode`.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-8267 Avoid existentials after polymorphic overload resolution
|