| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Imagine a macro writer which wants to synthesize a complex implicit
Complex[T] by making recursive calls to Complex[U] for its parts.
E.g. if we have `class Foo(val bar: Bar)` and `class Bar(val x: Int)`,
then it's quite reasonable for the macro writer to synthesize
Complex[Foo] by calling `inferImplicitValue(typeOf[Complex[Bar])`.
However if we didn't insert `info.sym.isMacro` check in `typedImplicit`,
then under some circumstances (e.g. as described in http://groups.google.com/group/scala-internals/browse_thread/thread/545462b377b0ac0a)
`dominates` might decide that `Bar` dominates `Foo` and therefore a
recursive implicit search should be prohibited.
Now when we yield control of divergent expansions to the macro writer,
what happens next? In the worst case, if the macro writer is careless,
we'll get a StackOverflowException from repeated macro calls. Otherwise,
the macro writer could check `c.openMacros` and `c.openImplicits` and
do `c.abort` when expansions are deemed to be divergent. Upon receiving
`c.abort` the typechecker will decide that the corresponding implicit
search has failed which will fail the entire stack of implicit searches,
producing a nice error message provided by the macro writer.
NOTE: the original commit from macro paradise also introduced a new
class, which encapsulates information about implicits in flight.
Unfortunately we cannot do that in 2.10.x, because of binary compatibility
concerns, therefore I'm marking this commit as [nomaster] and will be
resubmitting its full version in a separate pull request exclusively
targetting master.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
macroExpandAll is the key player in the mechanism of expanding macros after
their type arguments have been inferred. (Macro applications that contain
yet uninferred type arguments don't get expanded and are delayed until
the targs are inferred. Therefore later on we need to trigger those delayed
expansions manually, which is done by macroExpandAll).
Previously macroExpandAll was only called from a few selected places in
the typechecker, but that's quite risky, since typer evolves, and who knows
when this scheme breaks.
To make things more robust, I'm now calling macroExpandAll in the epilogue
of every single call to `typed`. Don't worry - this shouldn't impose
noticeable performance penalties, since the call is guarded by a branch
upon a plain boolean field.
NOTE: This patch is a second take on fixing implicit macros, with the first
one being a backport from macro paradise merged into master in January 2013:
https://github.com/scala/scala/commit/fe60284769.
The original fix had an unfortunate error, as described on scala-internals:
https://groups.google.com/forum/#!msg/scala-internals/7pA9CiiD3u8, so I had
to refine the approach here.
This means that it's not possible to directly merge this commit into master,
so I'm marking it as [nomaster] and will submit a separate pull request
targetting master later on.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 in `adapt`. 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.
Therefore `macroExpand` now takes the matters in its own hands,
calling `instantiate` if the expansion has been delayed and we're not in
POLYmode (see a detailed explanation in a comment to `macroExpand`).
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!
NOTE: This patch is a second take on fixing implicit macros, with the first
one being a backport from macro paradise merged into master in January 2013:
https://github.com/scala/scala/commit/fe60284769.
The original fix had an unfortunate error, as described on scala-internals:
https://groups.google.com/forum/#!msg/scala-internals/7pA9CiiD3u8, so I had
to refine the approach here.
This means that it's not possible to directly merge this commit into master,
so I'm marking it as [nomaster] and will submit a separate pull request
targetting master later on.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The subsequent fix to SI-5923 unmasks the fact that SI-5353 has not
been fixed - it's just that one of its manifestation got hidden behing
SI-5923. In fact, if in the code snippet from the bug report we change
Array() to Array[Nothing](), things will start crashing as usual.
The problem we have here is that arrays of nothings and nulls are very
weird in a sense that their compile-time representations (types) and
their runtime representations (JVM arrays of Object) behave differently
with respect to subtyping. Due to an unlucky coincidence SI-5923 prevented
some of the arrays of nothing from being compilable, so the problem was
well hidden until now.
A principled approach to handling the situation we have here would be to
fix SI-5353 (we already know how to do that: https://github.com/scala/scala/pull/2486)
and to disallow arrays of nothings and nulls as suggested in SI-7453.
Unfortunately, both fixes are going to bring incompatibilities, which are
not acceptable in a minor release (this pull request targets 2.10.x).
Therefore we decided to turn a blind eye on the iceberg and just fix a tip
of it by emulating the portion of SI-5923 that used to mask SI-5353, retaining
perfect backward compatibility.
Unfortunately, it's not that easy. Apparently one cannot simply report
all the occurrences of Array() as errors, because if we know expected type
of that expression, then everything's fine - the expected type will drive type
inference and the dreaded Array[Nothing]() will not arise. All right,
so let's just check whether pt == WildcardType and then report errors.
However that's still not enough because of SI-3859.
Having my hack failing for the third time, made me stop for a second and
think whether it's worth to play with fire and introduce potential
breakages for the sake of preventing a quite unlikely bug from happening.
I don't think the it's okay to risk here, therefore I just disable the
failing test, especially because we already have a working fix to SI-5353
submitted to master, so it's not like we're deferring the work to be done
to a random point in unclear future.
NOTE: That's only a temporary hack targeted at 2.10.x. There's no
reason for this code to be merged into master, because master is soon
going to have a principled solution to the problem:
https://github.com/scala/scala/pull/2486.
|
|
|
|
|
|
| |
The breakage is caused by https://github.com/scala/scala/commit/fbb13630d3
and https://github.com/scala/scala/commit/a8edefcef8 having been merged
independently from each other.
|
|\
| |
| | |
SI-7398 Add support for java8 default methods
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
In classfile parser: mark symbols which represent interface
methods yet have code attributes with new flag DEFAULTMETHOD.
These must be kept distinct from regular method bodies so that
an error can be issued when a regular concrete method is
overridden without the override keyword, but not when the
overridden method is a default.
In java source parser: mark Modifiers of interface default
methods with DEFAULTMETHOD flag.
Writing the test was everything I dreamed, and more! However,
% test/partest --debug test/files/run/t7398.scala
Skipping java8-specific test under java version 1.7.0_21
testing: [...]/files/run/t7398.scala [ OK ]
All of 1 tests were successful (elapsed time: 00:00:04)
% test/partest --debug test/files/run/t7398.scala
Attempting java8-specific test under java version 1.8.0-ea
testing: [...]/files/run/t7398.scala [ OK ]
All of 1 tests were successful (elapsed time: 00:00:13)
|
| |
| |
| |
| |
| | |
There was no way to make a java compilation unit.
Now there is.
|
|\ \
| | |
| | | |
Some fixes for string interpolation
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
See comments in code for the exhaustive list of the cases handled.
Also note that treatment of non-formatting percents has been changed.
Embedding literal %'s now requires escaping.
Moreover, this commit also features exact error positions for string
interpolation, something that has been impossible until the fix for
SI-7271, also included in this patch.
|
| |/
| |
| |
| |
| |
| |
| |
| |
| | |
Positions of static parts are now set explicitly during parsing rather
than filled in wholesale during subsequent atPos after parsing.
I also had to change the offsets that scanner uses for initial static
parts of string interpolations so that they no longer point to the
opening double quote, but rather to the actual beginning of the part.
|
|\ \
| | |
| | | |
SI-7426 Crash in pickler.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
I wonder if the supply of copy-pasted code, and the bugs
which always accompany it, will ever run low. Here we have
a couple hundred lines of tree traversal which appears
roughly identical in structure to a different couple hundred
lines of tree traversal, except one calls methods called
putXXX and the other calls methods called writeXXX.
Except there was one call to writeXXX among all the putXXX
calls. Guess where it was crashing.
This entire file should be expunged.
|
|\ \ \
| | | |
| | | | |
SI-7441 Don't ramble on about inapplicable implicits.
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
SI-7385 crash in erroneous code
|
| | | | |
| | | | |
| | | | |
| | | | | |
Less crashing, more emitting errors.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-6091 overeager warning for reference equality
|
| | |/ / /
| |/| | |
| | | | |
| | | | | |
Don't warn on eq and ne unless they're the real eq or ne.
|
|\ \ \ \ \
| |/ / / /
|/| | | | |
SI-6771 Alias awareness for checkableType in match analysis.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Failure to dealias the type of the scrutinee led the pattern
matcher to incorrectly reason about the type test in:
type Id[X] = X; (null: Id[Option[Int]]) match { case Some(_) => }
Before, `checkableType` returned `Id[?]`, now it returns `Some[?]`.
|
|\ \ \ \ \
| |_|/ / /
|/| | | | |
Warn on selection of vals from DelayedInit subclasses.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Which are likely to yield null, if the program didn't start.
This is a common source of confusion for people new to
the language, as was seen during the Coursera course.
The test case shows that the usage pattern within Specs2
won't generate these warnings.
|
|\ \ \ \ \
| |_|_|/ /
|/| | | | |
SI-7369 Avoid spurious unreachable warnings in patterns
|
| | |/ /
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Unreachability analysis draws on the enumerated domain of types
(e.g sealed subclasses + null, or true/false), and also looks at all
stable identifier patterns tested for equality against the same 'slot'
in a pattern.
It was drawing the wrong conclusions about stable identifier patterns.
Unlike the domain constants, two such values may hold the same value,
so we can't assume that matching X precludes matching Y in the same
slot in a subsequent case.
For example:
val X: Boolean = true; val Y: Boolean = true
def m1(t1: Tuple1[Boolean]) = t1 match {
case Tuple1(true) =>
case Tuple1(false) =>
case Tuple1(false) => // correctly unreachable
}
def m2(t1: Tuple1[Boolean]) = t1 match {
case Tuple1(X) =>
case Tuple1(Y) => // spurious unreachable warning
}
//
// Before
//
reachability, vars:
V2: Boolean ::= true | false// Set(false, Y, X, true) // = x1._1
V1: (Boolean,) ::= null | ... // = x1
equality axioms:
V2=true#4 \/ V2=false#5 /\
-V2=false#5 \/ -V2=Y#3 /\
-V2=false#5 \/ -V2=X#2 /\
-V2=false#5 \/ -V2=true#4 /\
-V2=Y#3 \/ -V2=X#2 /\
-V2=Y#3 \/ -V2=true#4 /\
-V2=X#2 \/ -V2=true#4
//
// After
//
reachability, vars:
V2: Boolean ::= true | false// Set(false, Y, X, true) // = x1._1
V1: (Boolean,) ::= null | ... // = x1
equality axioms:
V2=true#4 \/ V2=false#5 /\
-V2=false#5 \/ -V2=true#4
|
|\ \ \ \
| |_|_|/
|/| | | |
SI-7367 scaladoc crash on constructing the model for annotations.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Scaladoc only checks primary constructor when building annotation
model.
Here we instead find the constructor matching the annotation's symbol.
Also change TreeFactory.makeTree to return TreeEntity rather than
Option[TreeEntity] and force the caller check for EmptyTree.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
There's a very dangerous situation running around when you
combine universal equality with value classes:
// All over your code
val x = "abc"
if (x == "abc") ...
// Hey let's make x a value class
val x = new ValueClass("abc")
// Uh-oh
There was until now no warning when comparing a value class
with something else. Now there is.
|
|\ \ \ \
| |_|/ /
|/| | | |
SI-6675 Avoid spurious warning about pattern bind arity.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
In 692372ce, we added a warning (under -Xlint) when binding
a `TupleN` in to a single pattern binder, which wasn't allowed
before 2.10.0, and more often than not represents a bug.
However, that warning overstretched, and warned even when
using a Tuple Pattern to bind to the elements of such a value.
This commit checks for this case, and avoids the spurious warnings.
A new test case is added for this case to go with the existing
test for SI-6675:
$ ./tools/partest-ack 6675
% tests-with-matching-paths ... 3
% tests-with-matching-code ... 2
# 3 tests to run.
test/partest --show-diff --show-log \
test/files/neg/t6675-old-patmat.scala \
test/files/neg/t6675.scala \
test/files/pos/t6675.scala \
""
Testing individual files
testing: [...]/files/pos/t6675.scala [ OK ]
Testing individual files
testing: [...]/files/neg/t6675-old-patmat.scala [ OK ]
testing: [...]/files/neg/t6675.scala [ OK ]
All of 3 tests were successful (elapsed time: 00:00:03)
|
|\ \ \ \
| | | | |
| | | | | |
SI-7330 better error when pattern's not a value
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Somehow an applied type managed to sneak past the type checker in pattern mode.
Patterns must be values, though.
`case C[_] =>` was probably meant to be `case _: C[_] =>`
Advice is dispensed accordingly. (Generalizing the existing advice machinery.)
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Quiet down overloaded implicit warning.
|
| | |/ / /
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Apparently implicit classes product both a method symbol and
a module symbol, both of which are marked implicit, which left
this warning code believing there was an overloaded implicit
method.
|
|\ \ \ \ \
| |_|_|_|/
|/| | | | |
SI-7200 Test case for fixed type inference error.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Broken in 2.9.2 and 2.10.0, but working in 2.10.1
--- sandbox/2.10.0.log
+++ sandbox/2.10.1.log
def coflatMap[A >: Nothing <: Any, B >: Nothing <: Any](f: Test.Nel[A] => B): Test.Nel[A] => Test.Nel[B] = ((l: Test.Nel[A]) => Test.this.Nel.apply[B](f.apply(l), l.tail match {
case immutable.this.Nil => immutable.this.Nil
- case (hd: A, tl: List[A])scala.collection.immutable.::[A]((h @ _), (t @ _)) => {
- val r: Test.Nel[Nothing] = NelFoo.this.coflatMap[A, Nothing](f).apply(Test.this.Nel.apply[A](h, t));
+ case (hd: A, tl: List[A])scala.collection.immutable.::[?A1]((h @ _), (t @ _)) => {
+ val r: Test.Nel[B] = NelFoo.this.coflatMap[A, B](f).apply(Test.this.Nel.apply[A](h, t));
{
- <synthetic> val x$1: Nothing = r.head;
- r.tail.::[Nothing](x$1)
+ <synthetic> val x$1: B = r.head;
+ r.tail.::[B](x$1)
}
}
}))
b74c33eb86 represents the exact moment of progression. Comments
in pos/t7200b.scala, a minimal test that demonstrates the problem
without type constructors or code execution, pinpoint the line of
code responsible for the fix.
Incidentally, I'm currently on a train somewhere between Solothurn
and Biel, and am consequently without the power of scala-bisector.
Undeterred, and inspired by a line I saw in Skyfall last night
("sometimes the olds ways are better"), I just pulled off a two-hop
bisection. Take that, O(log N)!
The one remaining worry is the appearance of the type variable
?A1 in the output of -Xprint:typer for run/t7200.scala.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Absolute path in error message.
|
| | |/ / /
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | | |
As soon as you have a directory called "language" lying around,
you will appreciate why the advice given regarding SIP-18
should be "import scala.language..." not "import language..."
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-7388 Be more robust against cycles in error symbol creation.
|
| |/ / / /
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`Symbol#toString` was triggering `CyclicReferenceError` (specifically,
`accurateKindString` which calls `owner.primaryConstructor`.)
The `toString` output is used when creating an error symbol to
assign to the tree after an error (in this case, a non-existent
access qualifier.)
This commit catches the error, and falls back to just using the
symbol's name.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-7377 Fix retypechecking of patterns on case companion alias
|
| |/ / / /
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Some ancient code in Typers switches from PATTERNmode to
EXPRmode when encountering `stableF(...)`. It just
typechecks `stableF` and discards the arguments.
To the best of Martin's recollection, this has something
to do with the need to typecheck patterns rather late in
the compiler, after `a.b` had been translated to `a.b()`
in `Uncurry`. I'm not able to motivate this with tests
using `-Xoldpatmat`; was there ever an even older pattern
matcher that ran *after* uncurry?
What changed in 2.10.1 to expose this wrinkle? dfbaaa17
fixed `TypeTree.copyAttrs` to copy the original tree.
During the descent of `ResetAttrs`, sub-trees are duplicated
before begin further transformed. Duplicating the `Match`
in 2.10.0 would forget that the original tree of:
pat = (a: Int)Foo(_)
`----------`
`- TypeTree((a: Int)Foo), with original Select(..., "FooAlias")
The retypechecking would operate on the `MethodType`, rather
than the `Select`, which was not considered a stable
application.
For 2.10.x, I've just tightened up the condition to only
hit this if `args` is empty. I'm almost certain that the code
can be removed altogether, and I'll do that when this is merged
to master.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-7319 Avoid unflushed error/warning buffers in startContext
|
| | |_|_|/
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Contexts share error/warning buffers with their
children, and this also applies ot the shared
`startContext`.
That context flushes the buffers in `startContext`
in `resetContexts`.
It also removes `typerReportAnyContextErrors`, which
appears to be an elaborate no-op. It is only ever passed
a context `c` which is a direct child of `this.context`.
So taking a buffered error out of `c` and reissuing it
into `this.context` merely re-inserts into into the same
error buffer. Consrast this with `silent`, which uses
a child context with a fresh error buffer.
SI-7319 Flush error buffer in typerReportAnyContextErrors.
After this change, we no longer rely on the backstop in resetContexts
introduced in the previous commit.
|
|\ \ \ \ \
| |_|/ / /
|/| | | | |
SI-7329 duplicate default getters for specialized parameters.
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The default getter is generated with @specialized annotation if the
type parameter corresponding to the type of the parameter is
specialized. Consequently specialize pass tries to generate overloads.
Rather than pruning overloads to exclude duplicates, let's notice
that default getter specialization is not needed at all:
- The dynamic scope of default getter doesn't include specialized
method or class constructor.
- generic default getter is called even when calling specialized
method:
object V {
@specialized def foo[@specialized B](b: B = (??? : B)) = {}
foo[Int]()
}
gives:
invokevirtual Method V$.foo$default$1:()Ljava/lang/Object;
invokestatic (unboxToInt)
invokevirtual Method V$.foo$mIc$sp:(I)V
|
| |/ /
|/| |
| | |
| | |
| | |
| | | |
Specialize assigns SpecialOverride info to a specialized method
even when there is a further specialization that should be forwarded
to.
|
|\ \ \
| | | |
| | | | |
Revert "SI-6387 Clones accessor before name expansion"
|
| |/ /
| | |
| | |
| | |
| | |
| | | |
This reverts commit 4e10b2c833fa846c68b81e94a08d867e7de656aa.
Add 6387 test to pending and 7341 to up-to-date.
|
|\ \ \
| | | |
| | | | |
SI-6386 typed existential type tree's original now have tpe set
|