| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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)
|
|\
| |
| | |
Revert "SI-6387 Clones accessor before name expansion"
|
| |
| |
| |
| |
| |
| | |
This reverts commit 4e10b2c833fa846c68b81e94a08d867e7de656aa.
Add 6387 test to pending and 7341 to up-to-date.
|
|\ \
| | |
| | | |
SI-7289 Less strict type application for TypeVar.
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
When a type constructor variable is applied to the wrong number of arguments,
return a new type variable whose instance is `ErrorType`.
Dissection of the reported test case by @retronym:
Define the first implicit:
scala> trait Schtroumpf[T]
defined trait Schtroumpf
scala> implicit def schtroumpf[T, U <: Coll[T], Coll[X] <: Traversable[X]]
| (implicit minorSchtroumpf: Schtroumpf[T]): Schtroumpf[U] = ???
schtroumpf: [T, U <: Coll[T], Coll[X] <: Traversable[X]](implicit minorSchtroumpf: Schtroumpf[T])Schtroumpf[U]
Call it explicitly => kind error during type inference reported.
scala> schtroumpf(null): Schtroumpf[Int]
<console>:10: error: inferred kinds of the type arguments (Nothing,Int,Int) do not conform to the expected kinds of the type parameters (type T,type U,type Coll).
Int's type parameters do not match type Coll's expected parameters:
class Int has no type parameters, but type Coll has one
schtroumpf(null): Schtroumpf[Int]
^
<console>:10: error: type mismatch;
found : Schtroumpf[U]
required: Schtroumpf[Int]
schtroumpf(null): Schtroumpf[Int]
^
Add another implicit, and let implicit search weigh them up.
scala> implicitly[Schtroumpf[Int]]
<console>:10: error: diverging implicit expansion for type Schtroumpf[Int]
starting with method schtroumpf
implicitly[Schtroumpf[Int]]
^
scala> implicit val qoo = new Schtroumpf[Int]{}
qoo: Schtroumpf[Int] = $anon$1@c1b9b03
scala> implicitly[Schtroumpf[Int]]
<crash>
Implicit search compares the two in-scope implicits in `isStrictlyMoreSpecific`,
which constructs an existential type:
type ET = Schtroumpf[U] forSome { type T; type U <: Coll[T]; type Coll[_] <: Traversable[_] }
A subsequent subtype check `ET <:< Schtroumpf[Int]` gets to `withTypeVars`, which
replaces the quantified types with type variables, checks conformance of that
substitued underlying type against `Schtroumpf[Int]`, and then tries to solve
the collected type constraints. The type var trace looks like:
[ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ create] ?U ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ create] ?Coll ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ setInst] Nothing ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Nothing )
[ setInst] scala.collection.immutable.Nil.type( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], U=scala.collection.immutable.Nil.type )
[ setInst] =?scala.collection.immutable.Nil.type( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], Coll==?scala.collection.immutable.Nil.type )
[ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ setInst] Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Int )
[ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ create] ?U ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ create] ?Coll ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] )
[ setInst] Nothing ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Nothing )
[ setInst] Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], U=Int )
[ setInst] =?Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], Coll==?Int )
The problematic part is when `?Int` (the type var originated from `U`) is registered
as a lower bound for `Coll`. That happens in `solveOne`:
for (tparam2 <- tparams)
tparam2.info.bounds.hi.dealias match {
case TypeRef(_, `tparam`, _) =>
log(s"$tvar addLoBound $tparam2.tpeHK.instantiateTypeParams($tparams, $tvars)")
tvar addLoBound tparam2.tpeHK.instantiateTypeParams(tparams, tvars)
case _ =>
}
|
|\ \
| |/
|/| |
SI-6937 core type tags are no longer referentially unique
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Type tag factory used to evaluate the provided type creator in the
context of the initial mirror in order to maintain referential equality
of instances of standard tags. Unfortunately this evaluation might fail
if the mirror provided doesn't contain the classes being referred to.
Therefore I think we should avoid evaluating type creators there.
Note that failure of evaluation doesn't mean that there's something
bad going on. When one creates a type tag, the correct mirror /
classloader to interpret that tag in might be unknown (like it happens
here). This is okay, and this is exactly what the 2.10.0-M4 refactoring
has addressed.
Something like `res2.typeTag[A].in(currentMirror)` should be okay.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Now, the InfoTransformer is responsible for erasing the
path dependent types of formal parameters, at the same
place where it flattens nested method types.
This is preferable to having the tree transformer overwrite
the result of the info transformer, as used to be the case
after my previous work on SI-6135 / 493197fc.
|
| |
| |
| |
| |
| |
| |
| | |
For imminent reuse in the subsequent commit.
The binary compatibility whitelist is updated to
ignore these, as they live in reflect.internal.
|
| | |
|
| | |
|
|/
|
|
|
| |
Because this implementation is more clear than 2.10.x's and it will
simplify a further commit to fix SI-6715.
|
|\
| |
| | |
SI-7285 Fix match analysis with nested objects
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The fix for SI-6146 introduced `nestedMemberType` to
enumerate sealed subtypes based on the (prefixed) type
of the scrutinee and the symbols of its sealed subclasses.
That method needed to widen `ThisType(modSym)`s to
`ModuleTypeRef(modSym)` before calling `asSeenFrom`.
However, this could lead to confused in the match analysis,
which sees `ModuleTypeRef` as distinct from singleton types
on the same modules (after all, they aren't =:=). Spurious
warnings ensued.
This commit makes two changes:
- conditionally re-narrow the result of `asSeenFrom` in `nestedMemberType`.
- present `a.b.SomeModule.type` as `SomeModule` in warnings emitted
by the pattern matcher.
|
|\ \
| | |
| | | |
SI-6387 Clones accessor before name expansion
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When a symbol's name is expanded due to a conflict during
composition (e.g. multiple traits with same-named members, but
which are not both visible at the language level in the concrete
class) the compiler renames some symbols with expanded names which
embed the full name of the declaring class to avoid clashes.
In the rare cases when the accessor overrides the member in base
class, such expansion either results in AbstractMethodError when
the base method is abstract, or, even worse, can change the
semantics of the program.
To avoid such issues, we clone the accessor symbol, clear its
ACCESSOR flag and enter the symbol with an unchanged name.
|
|\ \ \
| |_|/
|/| | |
Read version 51 (JDK 7) class files.
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This commit makes the ClassFileReader/ICodeReader parse class files
from JDK 7 (class file version 51). It does that by skipping over
the method handle related entries in the constant pool and by doing
some dummy processing on invoke dynamic instructions. The inliner
is updated to not try to inline a method with an invoke dynamic
instruction. A place holder INVOKE_DYNAMIC instruction is added to ICode
but it is designed to create an error if there's ever any attempt to
analyze it. Because the inliner is the only phase that ever tries
to analyze ICode instructions not generated from Scala source and
because Scala source will never emit an INVOKE_DYNAMIC, the place
holder INVOKE_DYNAMIC should never cause any errors.
A test is included that generates a class file with INVOKE_DYNAMIC
and then compiles Scala code that depends on it.
|
|/
|
|
|
|
|
| |
This long-standing, but trivial to fix nuisance in the implementation of
runtime reflection actively avoided being fixed in both 2.10.0 and 2.10.1.
It's finally the time to put it to a rest.
|
|\
| |
| | |
SI-7240 fixes language feature lookup
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
As I discovered today, Definitions.getMember have a fallback clause,
which accounts for the phases which have inner classes flattened.
This fallback uses nme.flattenedName to compute a flattened name, but
unfortunately nme.flattenedName produces a TermName, not a TypeName,
which means that the fallback will commence search in a wrong namespace
with predictable results.
The commit also changes another usage of nme.flattenedName in a type name
context. That one was correctly converting a TermName result to TypeName,
so this is not a bugfix, but just a refactoring for the sake of being
consistent.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
TypeVars, being mutable creatures, mustn't have structural
equality/hashing, otherwise TypeRefs that differ only by
having distinct TypeVars as components get wrongly uniqued
together.
The reported bug showed the disaterous consequences: constraints
from the `C?[Int]` in the return type applied to the `?C[?A]` in
the parameter list.
This commit overrides `equals` and `hashCode` in `TypeVar`
to use reference equality. An alternative fix would be to drop
the `case`-ness of the class, as was the case before 0cde930b
when this regressed.
|
|\ \
| | |
| | | |
SI-7214 outer check based on dealiased pattern type.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
A Typed Pattern (_: T) is more than `.isInstanceOf`: if `T` is a
path dependent type, the scrutinee's $outer reference is also
compared against the prefix of `T`.
The code that synthesises this is split into two places.
`needsOuterCheck` determines whether to add this check, based on
the type `T`, and the type of the scrutinee. If it gives the
go-ahead, `treeCondStrategy.outerCheck` synthesizes the check.
The new test case demonstrates the problems caused by the failure
to dealias in `needsOuterCheck`: it could either wrongly lead to
synthesis of an outer test (which would crash), or wrongly omit
the outer test (meaning overly liberal matching.)
A simple `dealias` remedies this. `dealiasWiden` is *not*
appropriate here; we need to keep hold of singleton types.
I'll also note that there is already a little slack between these
methods, as commented:
> ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix`
> by `Select(q, > outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix`
> if there's an outer accessor, otherwise the condition becomes `true`
> TODO: can we improve needsOuterTest so there's always an outerAccessor?
So this is probably a fragile area that warrants a careful review
with a view to design improvements.
|
|\ \ \
| | | |
| | | | |
merge 2.10.1 into 2.10.x
|
| |\ \ \
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | | |
The fix for SI-7183 in 440bf0a8c2 was forward ported in f73d50f46c.
Conflicts:
src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The kind-polymorphic nature of Nothing and Any in
concert with type argument inference could lead to
types like `T[T]` (where `type T=Any`).
Compensatory action is taken later on to recover;
see the usages of `TypeRef#typeParamsMatchArgs`.
But this these types have a nasty property, they
can dealias to themselves. Callers recursing through
types who fail to account for this hit an infinite
recursion, as was reported in SI-7126.
This commit simply dealiases `T` when registering
the type bound in `unifySimple`.
We should try to weed out additional sources of
these types.
|
|\ \ \ \
| |/ / /
|/| | | |
SI-7185 Avoid NPE in TreeInfo.isExprSafeToInline
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
We got there typechecking code with a redundant
layer of Block.
We can't express that in source code, so we test
this with manual tree construction and with XML
literals, which as reported produce such trees.
|
|\ \ \ \
| | | | |
| | | | | |
Revert SI-6240 synchronization for runtime reflection
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This commit reverts #2083:
- 387b2590db runtime reflection: death from thousand threads
- 73d079fb38 removes the assertion in missingHook
- f4dd56ca5d synchronizes names
- dd148de5a8 synchronizes pendingVolatiles
- 4cbb9357c5 synchronizes toolboxes
- 07bcb6176a SI-7045 reflection now auto-initializes selfType
- bebd62d566 optimizes Scala reflection GIL
- 735634f1d6 initializes lazy vals and inner objects in advance
- 5b37cfb19a introduces GIL to Scala reflection
- 981da8edfc cleans up initialization of runtime reflection
- b2c2493b22 reflection no longer uses atPhase and friends
- a9dca512d8 synchronizes symbols
- 0262941b3c removes the crazy extraneous log
- 21d5d3820b moves Symbol#SymbolKind to Symbols
|
|\ \ \ \
| |/ / /
|/| | | |
Merge 2.10.1 into 2.10.x
|
| |\ \ \
| | |/ /
| |/| /
| | |/ |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This reverts commit 54a84a36d5b435a787d93ca48d45399136c7e162.
This is necessary to maintain binary compatibility with 2.10.0.
run/t6989.check had to be updated as it also (indirectly) tested SI-6548
Conflicts:
test/files/lib/javac-artifacts.jar.desired.sha1
test/files/run/t6548.check
test/files/run/t6548/Test_2.scala
|
| | |
| | |
| | |
| | |
| | |
| | | |
This reworks 02ed5fb so that we don't change JavaUniverse's super classes.
This is necessary to maintain binary compatibility with 2.10.0.
|
| | |
| | |
| | |
| | |
| | |
| | | |
This reverts commit 0429f0fd9224499cd8b606490d04b1a8dcffbca8.
This is necessary to maintain binary compatibility with 2.10.0.
|
|\ \ \
| |/ /
|/| | |
SI-6240 synchronization for runtime reflection
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
In the current synchronization scheme multiple threads can enter the
missingHook trying to materialize a package, which hasn't been created.
That's fine, because makeScalaPackage, which creates and enters package
symbols is synchronized and checks whether the creation is necessary
before commencing. Therefore even if makeScalaPackage is called multiple
times in rapid succession, the calls will be serialized and all calls
except the first one won't do anything.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Previously we didn't have all possible name creation facilities covered
with locks, so some of them silently misbehaved and caused much grief:
http://groups.google.com/group/scala-internals/browse_thread/thread/ec1d3e2c4bcb000a.
This patch gets all the name factories under control. Unfortunately it
comes at a performance cost, which has to be evaluated.
|
| | |
| | |
| | |
| | |
| | | |
Called from isVolatile, which is called from isStable, which is a part
of the public reflection API.
|
| | |
| | |
| | |
| | |
| | |
| | | |
selfType joins the happy family of flags, annotations and privateWithin,
which automatically trigger initialization, when used within runtime
reflection.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
First of all, GIL should only apply to runtime reflection, because noone
is going to run toolboxes in multiple threads: a) that's impossible, b/c
the compiler isn't thread safe, b) ToolBox api prevents that.
Secondly, the only things in symbols which require synchronization are:
1) info/validTo (completers aren't thread-safe),
2) rawInfo and its dependencies (it shares a mutable field with info)
3) non-trivial caches like in typeAsMemberOfLock
If you think about it, other things like sourceModule or associatedFile
don't need synchronization, because they are either set up when a symbol
is created or cloned or when it's completed. The former is obviously safe,
while the latter is safe as well, because before acquiring init-dependent
state of symbols, the compiler calls `initialize`, which is synchronized.
We can say that symbols can be in four possible states: 1) being created,
2) created, but not yet initialized, 3) initializing, 4) initialized.
in runtime reflection can undergo is init. #3 is dangerous and needs protection
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
As discussed at http://groups.google.com/group/scala-internals/browse_thread/thread/97840ba4fd37b52e,
`synchronized(this)` employed by lazy val and inner object initialization
is an excellent way to deadlock yourself in the foot.
Imagine a thread, which grabs a reflection GIL and then calls one of those
lazy vals / objects that reflection exposes (e.g. a companion module of
an innocently looking SingleType case class). Then imagine another thread,
which calls something else in SymbolTable, grabbing symbol table's monitor,
and then tries to get a reflection GIL to do something non-trivial. Hello,
we've just arrived at a deadlock.
Since, as discussed in the aforementioned thread, there's no easy way to
change lazy vals / inner objects in reflection to use GIL instead of
synchronizing on this, I bit the bullet and manually initialized all
things with deferred initialization defined in reflect.runtime.SymbolTable.
The list of all things `$lzycompute` has been mined by a simple Python script,
then I copy/pasted that list into `JavaUniverse.scala` and went ahead forcing
objects and lazy vals mentioned there. Notably, I've been able to force all
lazy vals in Definitions.scala.
There are some todos left, but I suggest we move forward without securing them,
because the 2.10.1-RC1 release date is very close, so we'd better have a 95%
solution instead of keeping reflection thread-unsafe. Though here's the list of
todo lazy vals for the reference:
* BaseTypeSeq.maxDepth
* WeakTypeTag.tpe
* AnnotationInfo.forcedInfo
For each of those lazy vals we need to make sure that their initializers never
call back into themselves. Otherwise, there's a danger of a deadlock.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
On a serious note, I feel really uncomfortable about having to juggle
this slew of locks. Despite that I can't immediately find a deadlock,
I'm 100% sure there is one hiding in the shadows. Hence, I'm abandoning
all runtime reflection locks in favor of a single per-universe one.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
At first I just tried to remove syntheticCoreClasses from missingHook
and put them into the initializer of freshly created mirrors in order to
reduce the non-determinism in mutations of the global symbol table.
And then it didn't work, crashing on me claiming that AnyRef is missing.
Apparently we still need AnyRefClass in missingHook, just because it's
impossible to initialize (i.e. unpickle) ScalaPackageClass without it.
And then it still didn't work, whining about multiple overloaded defs
of some synthetic symbols. That was really tricky, but I figured it out
as well by initializing ScalaPackageClass first before forcing any
synthetic symbols (see the details in comments).
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Mentioned methods mutate the global `atPhaseStack` variable, which can
easily lead to imbalances and, ultimately, to the empty stack error.
Luckily for us, there's only one dummy phase, SomePhase, which is used
by runtime reflection, so there is absolutely zero need to invoke atPhase
in non-compiler reflexive universes.
The cleanest solution would be to override `atPhase` for runtime reflection,
but it's @inline final, so I didn't want to pay performance penalties for
something that's used three times in runtime reflection (during unpickling, in
reflection-specific completers and in `Symbol.typeParams/unsafeTypeParams`).
Therefore I added overrideable analogues of `atPhase` and `atPhaseNotLaterThan`
which are called from the aforementioned code shared between the compiler and
runtime reflection. I also had to duplicate the code of `Symbol.XXXtypeParams`,
again due to them being very performance-sensitive.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Synchronization via decoration would be neat if it actually worked.
Unfortunately, root symbols never got decorated, therefore their children
also never got decorated and all the way down to the very turtles.
This commit fixes this sad issue by turning root symbols from objects
to lazy vals. Yes, this is going to induce a performance penalty, which
will hopefully not be high enough to invalidate this cornerstone of our
synchronization strategy.
Now when root symbols are lazy vals, they can be overridden in the runtime
reflexive universe and decorated with SynchronizedSymbol, which makes their
children sync and sound.
|
| | | |
|
| |/
| |
| |
| |
| |
| |
| | |
Too bad I didn't notice that before. That will free up quite a bit of
memory, removing an extraneous field in every single Symbol, namely the:
private volatile Symbols.Symbol.SymbolKind$ SymbolKind$module
|
|\ \
| | |
| | | |
SI-7171 Consider prefix when assessing type finality.
|