Skip to content

Commit 6015a54

Browse files
author
Adriaan Moors
committed
SI-1832 consistent symbols in casedef's pattern&body
the only change to typedBind in this commit (beyond refactoring to keep my eyes from bleeding), is explained by the added comment: have to imperatively set the symbol for this bind to keep it in sync with the symbols used in the body of a case when type checking a case we imperatively update the symbols in the body of the case those symbols are bound by the symbols in the Binds in the pattern of the case, so, if we set the symbols in the case body, but not in the patterns, then re-type check the casedef (for a second try in typedApply for example -- SI-1832), we are no longer in sync: the body has symbols set that do not appear in the patterns since body1 is not necessarily equal to body, we must return a copied tree, but we must still mutate the original bind
1 parent 8b0259f commit 6015a54

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

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

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3883,40 +3883,51 @@ trait Typers extends Modes with Adaptations with Tags {
38833883
}
38843884
}
38853885

3886-
def typedBind(name: Name, body: Tree) = {
3887-
var vble = tree.symbol
3888-
def typedBindType(name: TypeName) = {
3889-
assert(body == EmptyTree, context.unit + " typedBind: " + name.debugString + " " + body + " " + body.getClass)
3890-
if (vble == NoSymbol)
3891-
vble =
3892-
if (isFullyDefined(pt))
3893-
context.owner.newAliasType(name, tree.pos) setInfo pt
3894-
else
3895-
context.owner.newAbstractType(name, tree.pos) setInfo TypeBounds.empty
3896-
val rawInfo = vble.rawInfo
3897-
vble = if (vble.name == tpnme.WILDCARD) context.scope.enter(vble)
3898-
else namer.enterInScope(vble)
3899-
tree setSymbol vble setType vble.tpe
3900-
}
3901-
def typedBindTerm(name: TermName) = {
3902-
if (vble == NoSymbol)
3903-
vble = context.owner.newValue(name, tree.pos)
3904-
if (vble.name.toTermName != nme.WILDCARD) {
3905-
if ((mode & ALTmode) != 0)
3906-
VariableInPatternAlternativeError(tree)
3907-
vble = namer.enterInScope(vble)
3908-
}
3909-
val body1 = typed(body, mode, pt)
3910-
vble.setInfo(
3911-
if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
3912-
else body1.tpe)
3913-
treeCopy.Bind(tree, name, body1) setSymbol vble setType body1.tpe // burak, was: pt
3914-
}
3886+
def typedBind(name: Name, body: Tree) =
39153887
name match {
3916-
case x: TypeName => typedBindType(x)
3917-
case x: TermName => typedBindTerm(x)
3888+
case name: TypeName => assert(body == EmptyTree, context.unit + " typedBind: " + name.debugString + " " + body + " " + body.getClass)
3889+
val sym =
3890+
if (tree.symbol != NoSymbol) tree.symbol
3891+
else {
3892+
if (isFullyDefined(pt))
3893+
context.owner.newAliasType(name, tree.pos) setInfo pt
3894+
else
3895+
context.owner.newAbstractType(name, tree.pos) setInfo TypeBounds.empty
3896+
}
3897+
3898+
if (name != tpnme.WILDCARD) namer.enterInScope(sym)
3899+
else context.scope.enter(sym)
3900+
3901+
tree setSymbol sym setType sym.tpe
3902+
3903+
case name: TermName =>
3904+
val sym =
3905+
if (tree.symbol != NoSymbol) tree.symbol
3906+
else context.owner.newValue(name, tree.pos)
3907+
3908+
if (name != nme.WILDCARD) {
3909+
if ((mode & ALTmode) != 0) VariableInPatternAlternativeError(tree)
3910+
namer.enterInScope(sym)
3911+
}
3912+
3913+
val body1 = typed(body, mode, pt)
3914+
val symTp =
3915+
if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
3916+
else body1.tpe
3917+
sym setInfo symTp
3918+
3919+
// have to imperatively set the symbol for this bind to keep it in sync with the symbols used in the body of a case
3920+
// when type checking a case we imperatively update the symbols in the body of the case
3921+
// those symbols are bound by the symbols in the Binds in the pattern of the case,
3922+
// so, if we set the symbols in the case body, but not in the patterns,
3923+
// then re-type check the casedef (for a second try in typedApply for example -- SI-1832),
3924+
// we are no longer in sync: the body has symbols set that do not appear in the patterns
3925+
// since body1 is not necessarily equal to body, we must return a copied tree,
3926+
// but we must still mutate the original bind
3927+
tree setSymbol sym
3928+
treeCopy.Bind(tree, name, body1) setSymbol sym setType body1.tpe
39183929
}
3919-
}
3930+
39203931

39213932
def typedArrayValue(elemtpt: Tree, elems: List[Tree]) = {
39223933
val elemtpt1 = typedType(elemtpt, mode)

test/files/pos/t1832.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait Cloning {
2+
trait Foo
3+
def fn(g: Any => Unit): Foo
4+
5+
implicit def mkStar(i: Int) = new { def *(a: Foo): Foo = null }
6+
7+
val pool = 4 * fn { case ghostSYMBOL: Int => ghostSYMBOL * 2 }
8+
}

0 commit comments

Comments
 (0)