| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
Initial implementation of pluginsEnterStats was incorrect, because I got
the foldLeft wrong, making it perpetuate the initial value of stats.
This worked fine if zero or one macro plugins were active at a time,
but broke down if there were multiple of such plugins (concretely,
I discovered this issue when trying to marry macro paradise with scalahost).
|
|\
| |
| | |
SI-9153 More complete and stable results for completions
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Three items of background are needed to understand this bug.
1. When typechecking an application like `qual.m({stats; expr})`, the
argument is typechecked using the formal parameter type of `m` as the
expected type. If this fails with a type error located within in
`expr`, the typer instead re-typechecks under `ContextMode.ReTyping`
without an expected type, and then searches for an implicit adaptation
to enable `view(qual).m(args)`. Under this mode, `Typer#typed1`
clears the type of incoming trees.
2. The presentation compiler performs targetted operations like
type completions by:
- typechecking the enclosing tree, registering all typechecker
`Context`s created in the process (`registerContext`)
- finding the smallest enclosing `Context` around the target
position (`doLocateContext`)
- Using this context to perform implicit search, which can
contribute members to the completion. (`applicableViews` within
`interactive.Global#typeMembers`)
3. When verifiying whether or not a candidate implicit is applicable
as a view from `F => T`, implicit search typechecks a dummy call
of the form `q"candiate(${Ident("<argument>").setType(typeOf[F])})".
Now, picture yourself at the nexus of these three storms.
In the enclosed test case, we search for completions at:
x + 1.<caret>
1. Because the code is incomplete, the application of `Int#+`
doesn't typecheck, and the typer also tries to adapt `x` to a
method applicable to the re-typechecked argument.
2. This process registers a context with `retypechecking` set to
true. (If multiple contexts at the same position are registered,
the last one wins.)
3. Implicit search uses this context to typecheck
`Predef.Ensuring(<argument>.setType(Int))`, but the argument
is promptly stripped of its type and retypechecking fails
as there is no definition named `<argument>` in scope.
As such, we missed out on extension methods, like `ensuring` in the
list of completions.
This commit changes the presentation compiler to turn off retyping
mode in the context before starting to work with it. (Are the other
modes that might cause similar bugs?)
Once I made that change, I noticed that the results the enclosed test
was not stable. I tracked this down to the use of a `HashMap` to
carry the applicable implicit views, together with the way that
the presentation compiler removes duplicates. This commit
switched to a `LinkedHashMap`.
|
| |
| |
| |
| |
| |
| | |
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-4959 - UNIX bin scripts now work for paths with spaces
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The bin scripts fsc, scala, scalac, scaladoc, and scalap were not
working when spaces were in the true path of the file (after symbolic
links were resolved). This is now fixed.
The problem affected OS X, Linux, and mingw on Windows. It did not
affect cygwin, because the code was special-cased for cygwin to use
cygpath to convert to short filenames, which eliminates spaces.
It did not affect the Windows command prompt, because that uses a
separate batch file.
The problem was that there was a shell function, classpathArgs, used
to generate the arguments for the classpath. Shell functions can only
return status codes, and emit text which can be captured in a command
substitution. Thus, they can contain strings, but not distinguish
which spaces should be part of a word, and which ones should separate
words.
The solution was to switch to using a bash array, as java_args and
scala_args were already doing. In this way, each element of the array
can contain spaces, but the elements are kept distinct.
There was an additional problem with mingw. There was some code that
used 'cmd //c' to convert the path to Windows format (drive letters
with colons, backslashes and semicolons instead the UNIX-style slashes
with colon separators). It turns out that when there are spaces in the
path, 'cmd //c' adds quotes around the result to protect it. This was
superfluous and actually caused a problem with parsing the first and
last paths in the classpath, leading to trouble in finding jars.
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|\
| |
| | |
Fixes and tests for InnerClass / EnclsoingMethod classfile attributes
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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).
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Trait implementation classes and specialized classes are always
considered top-level in terms of the InnerClass / EnclosingMethod
attributes. These attributes describe source-level properties, and
such classes are a compilation artifact.
Note that the same is true for delambdafy:method closure classes
(they are always top-level).
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Private trait methods are not added to the generated interface, they
end up only in the implementation class. For classes nested in such
methods, the EnclosingMethod attribute was incorrect.
Since the EnclosingMethod attribute expresses a source-level property,
but the actual enclosing method does not exist in the bytecode, we
set the enclosing method to null.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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-8841 report named arg / assignment ambiguity also in silent mode.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
For local definitions (eg. in a block that is an argument of a method
call), the type completer may have a silent context. A CyclicReference
is then not thrown but transformed into a NormalTypeError. When
deciding if 'x = e' is an assignment or a named arg, we need to report
cyclic references, but not other type errors. In the above case, the
cyclic reference was not reported.
Also makes sure that warnings are printed after typing argument
expressions.
|
|\ \ \
| | | |
| | | | |
SI-9097 Remove spurious warning about conflicting filenames
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Uses the same idiom in `Flatten` and `LambdaLift` as is established
in `Extender` and (recently) `Delambdafy`. This avoids any possibility
of adding a member to a package twice, as used to happen in SI-9097.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
When using delambdafy:method, closure classes are generated late.
The class is added to a map and integrated into the PackageDef in
transformStats.
When declaring a package object, there are potentially multiple
PackageDefs for the same package. In this case, the closure class
was added to all of them. As a result, GenASM / GenBCode would run
multiple times on the closure class. In GenBCode this would trigger
a warning about conflicting filenames.
|
|\ \ \ \
| | | | |
| | | | | |
SI-9041 Avoid unreported type error with overloading, implicits
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
If `qual.foo(args)` fails to typecheck, we fall back to
`ImplicitView(qual).foo(args)`. However, if the original type error
stemmed from an overload ambiguity, the tree `Select(qual, 'foo')`
holds onto an error symbol. The fall back attempt just returns an
`Apply` tree containing the erroneous qualifier, as it does not
want to issue cascading type errors.
This commit replaces the error symbol with a `NoSymbol`, which
triggers the second try typechecking to perform overload resolution
again.
A more principled fix might be to more pervasively duplicate trees
before mutating their types and symbols, that this is beyond the
scope of this bug fix.
|
|\ \ \ \ \
| |_|_|_|/
|/| | | | |
SI-9123 More coherent trees with patmat, dependent types
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The pattern matcher needs to substitute references to bound
variables with references to either a) synthetic temporary vals,
or to b) selections. The latter occurs under -optimize to avoid
to be frugal with local variable slots.
For instance:
```
def test(s: Some[String]) = s match {
case Some(elem) => elem.length
}
```
Is translated to:
```
def test(s: Some[String]): Int = {
case <synthetic> val x1: Some[String] = s;
case4(){
if (x1.ne(null))
matchEnd3(x1.x.length())
else
case5()
};
case5(){
matchEnd3(throw new MatchError(x1))
};
matchEnd3(x: Int){
x
}
}
```
However, for a long time this translation failed to consider
references to the binder in types. #4122 tried to address this
by either using standard substitution facilities where available
(references to temp vals), and by expanding the patmat's
home grown substitution to handle the more complex case of
referencing a selection.
However, this left the tree in an incoherent state; while it
patched up the `.tpe` field of `Tree`s, it failed to modify the
info of `Symbol`-s.
This led to a crash in the later uncurry phase under
`-Ydelambdafy:method`.
This commit modifies the info of such symbols to get rid of stray
refeferences to the pattern binder symbols.
|
|\ \ \ \
| | | | |
| | | | | |
SI-9086 Fix regression in implicit search
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Implicit search declines to force the info of candidate implicits
that either a) are defined beyond the position of the implicit search
site, or b) enclose the implicit search site.
The second criterion used to prevent consideration of `O` in
the super constructor call:
implicit object O extends C( { implicitly[X] })
However, after https://github.com/scala/scala/pull/4043, the
block containing the implicit search is typechecked in a context
owned by a local dummy symbol rather than by `O`. (The dummy and
`O` share an owner.)
This led to `O` being considered as a candidate for this implicit
search. This search is undertaken during completion of the info of
`O`, which leads to it being excluded on account of the LOCKED flag.
Unfortunately, this also excludes it from use in implicit search
sites subsequent to `O`, as `ImplicitInfo` caches
`isCyclicOrErroneous`.
This commit adjusts the position of the local dummy to be identical
to that of the object. This serves to exclude `O` as a candidate
during the super call on account of criterion a).
|
|\ \ \ \
| | | | |
| | | | | |
SI-9093 Fix value discarding / multiple param list crasher
|
| | |/ /
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The type error stemming from missing argument list was being
swallowed when the expected type was `Unit` and there were
undetermined type parameters in the expression.
This commit modifies `adapt` to avoid using
`instantiateExpectingUnit` when the tree is typed with `MethodType`.
|
| |/ /
|/| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
An -Xlint:stars-align warning for the case of patterns
with at least one "fixed" component and a varargs component.
Warn if the fixed patterns don't exactly align with the fixed
value components, such that a sequence wildcard aligns exactly
with the varargs component (either a T* parameter in a case class
or a Seq[T] in an extractor result).
This addresses the case of the xml.Elem extractor, which does
not correspond to the Elem class constructor. One can be fooled
into supplying an extra field for extraction.
Vanilla extractors of type `Option[Seq[_]]` are unaffected by
this flag. It's OK to ask for `case X(a, b, c)` in the expectation
that three results are forthcoming. There is no semantic confusion
over where the varargs begin.
|
|\ \ \
| |/ /
|/| | |
SI-5154 Parse leading literal brace in XML pattern
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Don't consume literal brace as Scala pattern.
Previously, leading space would let the text parser `xText`
handle it correctly instead.
|
| | |
| | |
| | |
| | |
| | |
| | | |
- Rename CodeRepository to ByteCodeRepository
- Scaladoc on OptimizerReporting
- Scaladoc on ByteCodeRepository
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This infrastructure is required for the inliner: when inlining code
from a classfile, the corresponding ClassBType is needed for various
things (eg access checks, InnerClass attribute).
The test creates two ClassBTypes for the same class: once using the
(unpickled) Symbol, once using the parsed ASM ClassNode, and verifies
that the two are the same.
There's a cleanup to the InnerClass attribute:
object T { class Member; def foo = { class Local } }
class T
For Java compatibility the InnerClass entry for Member says the class
is nested in T (not in the module class T$). We now make sure to add
that entry only to T, not to T$ (unless Member is actually referenced
in the classfile T$, in that case it will be added, as required).
|
| | |
| | |
| | |
| | |
| | | |
Introduces methods for textifying classes, methods, InsnLists and
individual AbstractInsnNodes.
|
| | |
| | |
| | |
| | |
| | | |
There's already the map classBTypeFromInternalNameMap in BTypes which
stores all ClassBTypes.
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Each ClassBType is identified by its internalName, the fully qualified
JVM class name. Before this change, the name was stored in the `chrs`
array of the compiler name table (hash consed), with the idea to avoid
materializing the string.
However, we materialize the string anyway, because each ClassBType is
stored in the classBTypeFromInternalNameMap, indexed by the string.
If string equality turns out to be too slow we can use interning.
For the inliner, we read classes from bytecode and create ClassBTypes
for them. The names of these classes would not yet exist in the name
table, so the backend would need to be able to create new names. Using
Strings removes this dependency.
|
|\ \ \
| | | |
| | | | |
SI-9089 Another REPL/FSC + specialization bug fix
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The enclosed test case stopped working in 2.11.5 on the back of
https://github.com/scala/scala/pull/4040.
The key change was that we ran all post-typer info transformers
on each run of the compiler, rather than trying to reuse the results
of the previous run.
In that patch, I noticed one place [1] in specialization that
aggressively entered specialized members into the owning scope,
rather than relying on `transformInfo` to place the new members
in the scope of the newly created element of the info history.
I made that change after noticing that this code could actually
mutated scopes of specializaed types at the parser phase, which
led to fairly obscure failures.
This bug is another one of these obscure failures, and has the
same root cause. We effectively "double specialiaze" Function0,
which trips an assertion when `method apply$mcI$sp` is found
twice in a scope.
I have found another spot that was directly manipulating the scope,
and removed the offending code.
[1] https://github.com/scala/scala/pull/4040#commitcomment-8531516
|
|\ \ \ \
| |/ / /
|/| | | |
Fix many typos in docs and comments
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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-7965 Support calls to MethodHandle.{invoke,invokeExact}
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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
```
|
|\ \ \ \
| | | | |
| | | | | |
SI-9044 Fix order of interfaces in classfiles
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
It was reversed since ced3ca8ae1. The reason is that the backend used
`mixinClasses` to obtain the parents of a class, which returns them in
linearization order.
`mixinClasses` als returns all ancestors (not only direct parents),
which means more work for `minimizeInterfaces`. This was introduced
in cd62f52 for unclear reasons. So we switch back to using `parents`.
|
|\ \ \ \
| | | | |
| | | | | |
SI-8999 Reduce memory usage in exhaustivity check
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The OOM could occur when all models are forcibly expanded in the DPLL solver.
The simplest solution would be to limit the number of returned models but then
we are back in non-determinism land (since the subset we get back depends on
which models were found first).
A better alternative is to create only the models that have corresponding
counter examples.
If this does not ring a bell, here's a longer explanation:
TThe models we get from the DPLL solver need to be mapped back to counter
examples. However there's no precalculated mapping model -> counter example.
Even worse, not every valid model corresponds to a valid counter example.
The reason is that restricting the valid models further would for example
require a quadratic number of additional clauses. So to keep the optimistic case
fast (i.e., all cases are covered in a pattern match), the infeasible counter
examples are filtered later.
The DPLL procedure keeps the literals that do not contribute to the solution
unassigned, e.g., for `(a \/ b)` only {a = true} or {b = true} is required and
the other variable can have any value. This function does a smart expansion of
the model and avoids models that have conflicting mappings.
For example for in case of the given set of symbols (taken from `t7020.scala`):
"V2=2#16"
"V2=6#19"
"V2=5#18"
"V2=4#17"
"V2=7#20"
One possibility would be to group the symbols by domain but
this would only work for equality tests and would not be compatible
with type tests.
Another observation leads to a much simpler algorithm:
Only one of these symbols can be set to true,
since `V2` can at most be equal to one of {2,6,5,4,7}.
TODO: How does this fare with mixed TypeConst/ValueConst assignments?
When the assignments are e.g., V2=Int | V2=2 | V2=4, only the assignments
to value constants are mutually exclusive.
|
|\ \ \ \
| | | | |
| | | | | |
SI-7459 Handle pattern binders used as prefixes in TypeTrees.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Match translation was incorrect for:
case t => new t.C
case D(t) => new d.C
We would end up with Types in TypeTrees referring to the wrong
symbols, e.g:
// t7459a.scala
((x0$1: this.LM) => {
case <synthetic> val x1: this.LM = x0$1;
case4(){
matchEnd3(new tttt.Node[Any]())
};
matchEnd3(x: Any){
x
}
Or:
// t7459b.scala
((x0$1: CC) => {
case <synthetic> val x1: CC = x0$1;
case4(){
if (x1.ne(null))
matchEnd3(new tttt.Node[Any]())
else
case5()
};
This commit:
- Changes `bindSubPats` to traverse types, as well as terms,
in search of references to bound symbols
- Changes `Substitution` to reuse `Tree#substituteSymbols` rather
than the home-brew substitution from `Tree`s to `Tree`s, if the
`to` trees are all `Ident`s
- extends `substIdentsForTrees` to substitute selections like
`x1.caseField` into types.
I had to dance around the awkward handling of "swatches" (exception
handlers that can be implemented with JVM native type switches) by
duplicating trees to avoid seeing the results of `substituteSymbols`
in `caseDefs` after we abandon that approach if we detect the
patterns are too complex late in the game.
I also had to add an escape hatch for the "type selection from
volatile type" check in the type checker. Without this, the
translation of `pos/t7459c.scala`:
case <synthetic> val x1: _$1 = (null: Test.Mirror[_]).universe;
case5(){
if (x1.isInstanceOf[Test.JavaUniverse])
{
<synthetic> val x2: _$1 with Test.JavaUniverse = (x1.asInstanceOf[_$1 with Test.JavaUniverse]: _$1 with Test.JavaUniverse);
matchEnd4({
val ju1: Test.JavaUniverse = x2;
val f: () => x2.Type = (() => (null: x2.TypeTag[Nothing]).tpe);
.. triggers that error at `x2.TypeTag`.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Suppress match analysis under -Xno-patmat-analysis
|
| | |/ / /
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
NoSuppression doesn't suppress. FullSuppression does.
Now using the latter when running under `-Xno-patmat-analysis`.
I should really have tested. /me hides under a rock
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Run dead code elimination by default in GenBCode
|