| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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-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.
|
|\ \
| | |
| | | |
Color REPL under -Dscala.color
|
| | |
| | |
| | |
| | |
| | | |
* Errors are red
* Warnings are yellow
|
| |/
|/|
| |
| |
| |
| |
| | |
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.
|
|\ \
| | |
| | | |
SI-4788/SI-5948 Respect RetentionPolicy of Java annotations
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
|/ /
| |
| |
| |
| |
| | |
@SerialVersionUID is special-cased, the warning doesn't apply.
Related to SI-7041.
|
|\ \
| | |
| | | |
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)
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
to initial implementation).
Assuming that the DPLL procedure does not run into max recursion
depth, that workaround is not needed anymore, since the non-
determinism has been fixed.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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.
|
| |/ / /
|/| | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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-8267 Avoid existentials after polymorphic overload resolution
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
... which can be introduced by `memberType` for methods
with parameter types dependent on class type parameters.
Here's an example of such a type:
```
scala> class Bippy { trait Foo[A] }
defined class Bippy
scala> final class RichBippy[C <: Bippy with Singleton](val c1: C) {
| def g[A](x: A)(ev: c1.Foo[A]): Int = 2
| }
defined class RichBippy
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> val g = typeOf[RichBippy[_]].member(TermName("g"))
g: $r.intp.global.Symbol = method g
scala> val c = new Bippy
c: Bippy = Bippy@92e2c93
scala> val memberType = typeOf[RichBippy[c.type]].memberType(g)
memberType: $r.intp.global.Type = ([A](x: A)(ev: _7.c1.Foo[A])Int) forSome { val _7: RichBippy[c.type] }
```
In this example, if we were to typecheck the selection
`new RichBippy[c.type].g` that existential type would be short lived.
Consider this approximation of `Typer#typedInternal`:
```scala
val tree1: Tree = typed1(tree, mode, ptWild)
val result = adapt(tree1, mode, ptPlugins, tree)
```
Given that `tree1.tpe` is not an overloaded, adapt will find its
way to:
```
case tp if mode.typingExprNotLhs && isExistentialType(tp) =>
adapt(tree setType tp.dealias.skolemizeExistential(context.owner, tree), mode, pt, original)
```
Which would open the existential as per:
```
scala> memberType.skolemizeExistential
res2: $r.intp.global.Type = [A](x: A)(ev: _7.c1.Foo[A])Int
```
However, if do have overloaded alternatives, as in the test case,
we have to remember to call `adapt` again *after* we have picked
the winning alternative.
We actually don't have a centralised place where overload resolution
occurs, as the process differs depending on the context of the
selection. (Are there explicit type arguments? Inferred type
arguments? Do we need to use the expected type to pick a winner?)
This commit finds the existing places that call adapt after
overloade resolution and routes those calls through a marker
method. It then adds one more call to this in `inferPolyAlternatives`,
which fixes the bug.
|
|\ \ \ \
| | | | |
| | | | | |
SI-8217 allow abstract type members in objects
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Previously, abstract type members were allowed in objects only when inherited,
but not when declared directly. This inconsistency was not intended. In dotty,
abstract type members are allowed in values and represent existentials; so upon
discussion, it was decided to fix things to conform to dotty and allow such type
members. Adriaan also asked to keep rejecting abstract type members in methods
even though they would conceivably make sense.
Discussions happened on #3407, scala/scala-dist#127.
This code is improved from #3442, keeps closer to the current logic, and passes tests.
Existing tests that have been converted to `pos` tests show that
this works, and a new test has been added to show that local
aliases (ie term-owned) without a RHS are still rejected.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-8869 Prevent ill-kindedness in type lambdas
|
| | |_|_|/
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
When type checking an type application, the arguments are allowed
to be of kinds other than *. This leniency is controlled by the
`ContextMode` bit `TypeConstructorAllowed`.
(More fine grained checking of matching arity a bounds of type
constructors is deferred until the refchecks phase to avoid
cycles during typechecking.)
However, this bit is propagated to child contexts, which means
that we fail to report this error in the lexical context marked
here:
T[({type x = Option}#x)]
`-------------'
This commit resets this bit to false in any child context
relates to a different tree from its parent.
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | | |
Doing so relies on implementation details which might change.
See #3911 / SI-8774.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
If you look at the implementation of that method and its usage
its clear that it should have been named `findClassFile` from the
beginning because that's what it does: find a class file and
not a source file.
|
| |/ /
|/| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Previously, if we wanted to override the shell.prompt property, we had
to modify compiler.properties in the jar. This change lets us do the
following, instead:
scala -Dscala.shell.prompt="$(echo -e "\npuffnfresh> ")"
All properties previously loaded from compiler.properties now fall back
to "scala." in the system properties when not found.
|
|\ \ \
| | | |
| | | | |
SI-8459 fix incorrect positions for incomplete selection trees
|
| | |/
| |/|
| | |
| | |
| | |
| | | |
The mentioned issue is a presentation compiler issue, but its root cause is a bug in the parser which incorrectly assigned positions to incomplete selection trees (i.e. selections that lack an indentifier after dot and have some whitespace instead).
In detail: for such incomplete selection trees, the "point" of the position should be immediately after the dot but instead was at the start of next token after the dot. For range positions, this caused a pathological situation where the "point" was greater than the "end" of the position. This position is later used by the typechecker during resolution of dynamic calls and causes it to crash. Of course, because a syntactically incorrect code is required for the bug to manifest, it only happens in the presentation compiler.
|
|\ \ \
| | | |
| | | | |
SI-8852 Support joint compilation of Java interfaces w. statics
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
We had to change the java parser to accomodate this language
change in Java 8.
The enclosed test does not require JDK8 to run, it only tests
JavaParsers.
Here is a transcript of my manual testing using Java 8.
```
% tail test/files/run/8852b/{Interface.java,client.scala}
==> test/files/run/8852b/Interface.java <==
public interface Interface {
public static int staticMethod() {
return 42;
}
}
==> test/files/run/8852b/client.scala <==
object Test extends App {
assert(Interface.staticMethod() == 42)
}
// Under separate compilation, statics in interfaces were already working
% rm /tmp/*.class 2> /dev/null; javac -d /tmp test/files/run/8852b/Interface.java && scalac-hash v2.11.2 -classpath /tmp -d /tmp test/files/run/8852b/client.scala && scala-hash v2.11.2 -classpath /tmp -nc Test
// Under joint compilation, statics in interfaces now work.
% rm /tmp/*.class 2> /dev/null; qscalac -d /tmp test/files/run/8852b/{client.scala,Interface.java} && javac -d /tmp test/files/run/8852b/Interface.java && qscala -classpath /tmp -nc Test
```
|
|\ \ \
| |/ /
|/| | |
This ensures that typechecking custom unapplications in silent mode
|
| | |
| | |
| | |
| | |
| | |
| | | |
doesn't leak uncatchable errors. Interestingly enough, the problem
only manifested itself for custom unapply methods, not for synthetic
ones generated for case classes.
|
|\ \ \
| | | |
| | | | |
SI-8806 Add lower bound check to Any lint
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
We already exclude the lint check for infer-any if
Any is somewhere explicit.
This commit adds lower bounds of type params to
the somewheres.
Motivated by:
```
scala> f"${42}"
<console>:8: warning: a type was inferred to be `Any`; this may indicate a programming error.
f"${42}"
^
res0: String = 42
```
|
|\ \ \ \
| | | | |
| | | | | |
isAnonymousClass/Function for delambdafy classes is not true
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Ydelambdafy:method lambda classes are not anonymous classes, and not
anonymous function classes either. They are somethig new, so there's
a new predicate isDelambdafyFunction.
They are not anonymous classes (or functions) because anonymous
classes in Java speak are nested. Delambdafy classes are always
top-level, they are just synthetic.
Before this patch, isAnonymous was sometimes accidentailly true: if
the lambda is nested in an anonymous class. Now it's always false.
|
|\ \ \ \ \
| |_|_|_|/
|/| | | | |
GenBCode: eliminate unreachable code
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This is required for correctness of the generated bytecode. Exception
handlers and local variable descriptors specify code offset ranges.
These offsets have to exist, not be eliminated.
|
| | | | |
| | | | |
| | | | |
| | | | | |
Tests for emitting expressions of type Nothing.
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
We rely on dead code elimination provided by the ASM framework, as
described in the ASM User Guide (http://asm.ow2.org/index.html),
Section 8.2.1. It runs a data flow analysis, which only computes
information for reachable instructions. Instructions for which no
data is available after the analyis are unreachable.
There's one issue with the ASM framework (or the way we use it): Data
flow analysis requires the maxlocals and maxstack of each method to be
computed. The ASM framework calculates these maxes only when
writing the classfiles, not during code generation. In order to run
DCE, we therefore run a MethodWriter beforehand on every method. This
assings the MethodNode's maxStack/maxLocals, but it does more work
(writes the instructions to a byte array).
This is also what Miguel uses on his branch. The change is basically
the same as https://github.com/lrytz/scala/commit/bfadf92c20.
We could probably make this faster (and allocate less memory) by
hacking the ASM framework: create a subclass of MethodWriter with a
/dev/null byteVector. Another option would be to create a separate
visitor for computing those values, duplicating the functionality from
the MethodWriter.
For now, I added some timers to be able to measure the time DCE takes.
Here's compiling the library with -Ystatistics:jvm
time in backend : 1 spans, 6597ms
bcode initialization : 1 spans, 8ms (0.1%)
code generation : 1 spans, 4580ms (69.4%)
dead code elimination : 3771 spans, 742ms (11.2%)
classfile writing : 1 spans, 879ms (13.3%)
|
| |/ / / |
|
| |_|/
|/| |
| | |
| | |
| | |
| | |
| | | |
This brings consistency with scala.reflect.reify and scala.reflect.macros
already existing in scala-compiler. To the contrast, scala.tools.reflect,
the previous home of quasiquotes, is a grab bag of various stuff without
any central theme.
|
|/ /
| |
| |
| | |
Compiler internals treat lazy vals as methods. Therefore, we need to have a special case for them when assembling the warning message.
|
|\ \
| | |
| | | |
SI-8764 fix return type of case class productElement under Xexperimental
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Xexperimental
Under Xexperimental, productElement now returns the lub instead
of the weak lub of case class parameter types (numeric widening
shouldn't magically happen *inside* productElement).
This was removed from 2.12.x in 6317ae2.
|
|\ \
| | |
| | | |
SI-5254 running an empty scala script should succeed
|