diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-07-13 10:13:23 +1000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-23 15:02:25 +0200 |
commit | 091c1e6ed8254fbd75a21843e2b9d331cbabf9d8 (patch) | |
tree | 1841f26dfe1e1cce0678ec86e5d080ca064593eb /src | |
parent | 6177cb44812b92b4059ec621a34cc26ddbe532c1 (diff) | |
download | scala-091c1e6ed8254fbd75a21843e2b9d331cbabf9d8.tar.gz scala-091c1e6ed8254fbd75a21843e2b9d331cbabf9d8.tar.bz2 scala-091c1e6ed8254fbd75a21843e2b9d331cbabf9d8.zip |
[backport] SI-9392 Avoid crash in GenBCode for incoherent trees
A macro in shapeless was generating a tree of the form:
```
{
class C#2
new C#2
}.setType(C#1)
```
This happened due to an error in the macro; it used untypecheck
to try to fix the owner-chain consistency problem, but kept a
reference to the previous version of the block-local class symbol
`C` and used this in the resulting tree.
This commit detects the particular situation we encountered, and
avoids the crash by not creating the `NestedInfo` for the
`BType` corresponding to `C#1`. The code comment discusses why I
think this is safe, and suggests a refactoring that would mean
we only ever try to construct `NestedInfo` when we are going to
need them.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index cf29c8090b..7b238e56eb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -351,6 +351,14 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { val isTopLevel = innerClassSym.rawowner.isPackageClass // impl classes are considered top-level, see comment in BTypes if (isTopLevel || considerAsTopLevelImplementationArtifact(innerClassSym)) None + else if (innerClassSym.rawowner.isTerm) + // SI-9392 An errant macro might leave a reference to a local class symbol that no longer exists in the tree, + // this avoids an assertion error in that case. AFAICT, we don't actually need the `NestedInfo` for all BTypes, + // only for ones that describe classes defined in the trees that reach the backend, so this is safe enough. + // + // TODO Can we avoid creating `NestedInfo` for each type that is referred to, and instead only create if for + // symbols of ClassDefs? + None else { // See comment in BTypes, when is a class marked static in the InnerClass table. val isStaticNestedClass = isOriginallyStaticOwner(innerClassSym.originalOwner) |