Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 08334b0

Browse files
author
Adriaan Moors
committed
Merge pull request scala#576 from axel22/issue/4717
Fix SI-4717: lazy val declared inside an anonymous class inside a specialized context no longer crashes Duplicators.
2 parents 1f5584f + f5c1fb9 commit 08334b0

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

src/compiler/scala/tools/nsc/typechecker/Duplicators.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ abstract class Duplicators extends Analyzer {
143143
else
144144
sym
145145

146-
private def invalidate(tree: Tree) {
147-
debuglog("attempting to invalidate " + tree.symbol + ", owner - " + (if (tree.symbol ne null) tree.symbol.owner else "<NULL>"))
146+
private def invalidate(tree: Tree, owner: Symbol = NoSymbol) {
147+
debuglog("attempting to invalidate " + tree.symbol)
148148
if (tree.isDef && tree.symbol != NoSymbol) {
149149
debuglog("invalid " + tree.symbol)
150150
invalidSyms(tree.symbol) = tree
@@ -158,18 +158,20 @@ abstract class Duplicators extends Analyzer {
158158
newsym.setInfo(fixType(ldef.symbol.info))
159159
ldef.symbol = newsym
160160
debuglog("newsym: " + newsym + " info: " + newsym.info)
161-
161+
162162
case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) =>
163163
debuglog("ValDef " + name + " sym.info: " + vdef.symbol.info)
164164
invalidSyms(vdef.symbol) = vdef
165-
val newsym = vdef.symbol.cloneSymbol(context.owner)
165+
val newowner = if (owner != NoSymbol) owner else context.owner
166+
val newsym = vdef.symbol.cloneSymbol(newowner)
166167
newsym.setInfo(fixType(vdef.symbol.info))
167168
vdef.symbol = newsym
168-
debuglog("newsym: " + newsym + " info: " + newsym.info)
169-
169+
debuglog("newsym: " + newsym + " info: " + newsym.info + ", owner: " + newsym.owner + ", " + newsym.owner.isClass)
170+
if (newsym.owner.isClass) newsym.owner.info.decls enter newsym
171+
170172
case DefDef(_, name, tparams, vparamss, _, rhs) =>
171173
// invalidate parameters
172-
invalidate(tparams ::: vparamss.flatten)
174+
invalidateAll(tparams ::: vparamss.flatten)
173175
tree.symbol = NoSymbol
174176

175177
case _ =>
@@ -178,14 +180,14 @@ abstract class Duplicators extends Analyzer {
178180
}
179181
}
180182

181-
private def invalidate(stats: List[Tree]) {
182-
stats foreach invalidate
183+
private def invalidateAll(stats: List[Tree], owner: Symbol = NoSymbol) {
184+
stats.foreach(invalidate(_, owner))
183185
}
184186

185187
def retypedMethod(ddef: DefDef, oldThis: Symbol, newThis: Symbol): Tree = {
186188
oldClassOwner = oldThis
187189
newClassOwner = newThis
188-
invalidate(ddef.tparams)
190+
invalidateAll(ddef.tparams)
189191
mforeach(ddef.vparamss) { vdef =>
190192
invalidate(vdef)
191193
vdef.tpe = null
@@ -239,15 +241,15 @@ abstract class Duplicators extends Analyzer {
239241

240242
case Block(stats, res) =>
241243
debuglog("invalidating block")
242-
invalidate(stats)
244+
invalidateAll(stats)
243245
invalidate(res)
244246
tree.tpe = null
245247
super.typed(tree, mode, pt)
246248

247249
case ClassDef(_, _, _, tmpl @ Template(parents, _, stats)) =>
248-
// log("invalidating classdef " + tree.tpe)
250+
// log("invalidating classdef " + tree)
249251
tmpl.symbol = tree.symbol.newLocalDummy(tree.pos)
250-
invalidate(stats)
252+
invalidateAll(stats, tree.symbol)
251253
tree.tpe = null
252254
super.typed(tree, mode, pt)
253255

test/files/pos/t4717.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
3+
4+
5+
6+
7+
8+
trait Bug1[@specialized(Boolean) A] extends TraversableOnce[A] {
9+
10+
def ++[B >: A](that: TraversableOnce[B]): Iterator[B] = new Iterator[B] {
11+
lazy val it = that.toIterator
12+
def hasNext = it.hasNext
13+
def next = it.next
14+
}
15+
16+
}
17+
18+
19+
20+
trait WorksFine[@specialized(Boolean) A] {
21+
class SubBounds[B >: A] extends Bounds[B] {
22+
lazy val it = ???
23+
}
24+
def x[B >: A]: Unit = new SubBounds[B]
25+
}
26+
27+
28+
trait Bounds[@specialized(Boolean) A] {
29+
// okay without `>: A`
30+
def x[B >: A]: Unit = new Bounds[B] {
31+
lazy val it = ??? // def or val okay
32+
}
33+
}
34+
35+

0 commit comments

Comments
 (0)