Skip to content

Commit 5f08c78

Browse files
committed
untyper is no more
Unlike with default getters, removing untyper from case class synthesis was trivial. Just resetLocalAttrs on a duplicate of the provided class def, and that’s it. resetAllAttrs, you’re next. We’ll get to you! Eventually...
1 parent 59cdd50 commit 5f08c78

File tree

1 file changed

+12
-36
lines changed

1 file changed

+12
-36
lines changed

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

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,6 @@ trait Unapplies extends ast.TreeDSL {
4343
def unapply(tp: Type): Option[Symbol] = unapplyMember(tp).toOption
4444
}
4545

46-
// NOTE: Do not unprivate this method! Even if you think you need it, you most likely don't need it.
47-
//
48-
// resetAllAttrs, copyUntyped and likes irreparably break certain important tree shapes (see SI-5464 for details),
49-
// including a very common case of TypeTree's without originals, which means that every call to resetAllAttrs
50-
// breaks code that emits such trees.
51-
//
52-
// However there are situations when we want to reuse already attributed trees somewhere else
53-
// (e.g. for case class synthesis, for auxiliary codegen that desugars default parameters, etc), and then the only way to go
54-
// in the current architecture is to erase attributes. That's a sad lose-lose situation.
55-
//
56-
// But not all hope is lost! First of all, resetLocalAttrs is oftentimes good enough (e.g. see addDefaultGetters),
57-
// and since it's much less destructive that resetAllAttrs, the breakages that it causes are going to manifest themselves
58-
// much less frequently. Secondly, research into hygiene promises to give us a better way of doing bindings, so let's cross our fingers.
59-
private def copyUntyped[T <: Tree](tree: T): T = {
60-
object UnTyper extends Traverser {
61-
override def traverse(tree: Tree) = {
62-
if (tree.canHaveAttrs) {
63-
tree.clearType()
64-
if (tree.hasSymbolField) tree.symbol = NoSymbol
65-
}
66-
super.traverse(tree)
67-
}
68-
}
69-
returning[T](tree.duplicate)(UnTyper traverse _)
70-
}
71-
72-
// NOTE: do not unprivate this method
73-
// see comments for copyUntyped for more information
74-
private def copyUntypedInvariant(td: TypeDef): TypeDef =
75-
copyTypeDef(copyUntyped(td))(mods = td.mods &~ (COVARIANT | CONTRAVARIANT))
76-
7746
private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
7847

7948
private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
@@ -83,8 +52,15 @@ trait Unapplies extends ast.TreeDSL {
8352
}
8453

8554
private def constrParamss(cdef: ClassDef): List[List[ValDef]] = {
86-
val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor cdef.impl.body
87-
mmap(vparamss)(copyUntyped[ValDef])
55+
val ClassDef(_, _, _, Template(_, _, body)) = resetLocalAttrs(cdef.duplicate)
56+
val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor body
57+
vparamss
58+
}
59+
60+
private def constrTparamsInvariant(cdef: ClassDef): List[TypeDef] = {
61+
val ClassDef(_, _, tparams, _) = resetLocalAttrs(cdef.duplicate)
62+
val tparamsInvariant = tparams.map(tparam => copyTypeDef(tparam)(mods = tparam.mods &~ (COVARIANT | CONTRAVARIANT)))
63+
tparamsInvariant
8864
}
8965

9066
/** The return value of an unapply method of a case class C[Ts]
@@ -150,7 +126,7 @@ trait Unapplies extends ast.TreeDSL {
150126
/** The apply method corresponding to a case class
151127
*/
152128
def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef): DefDef = {
153-
val tparams = cdef.tparams map copyUntypedInvariant
129+
val tparams = constrTparamsInvariant(cdef)
154130
val cparamss = constrParamss(cdef)
155131
def classtpe = classType(cdef, tparams)
156132
atPos(cdef.pos.focus)(
@@ -166,7 +142,7 @@ trait Unapplies extends ast.TreeDSL {
166142
/** The unapply method corresponding to a case class
167143
*/
168144
def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = {
169-
val tparams = cdef.tparams map copyUntypedInvariant
145+
val tparams = constrTparamsInvariant(cdef)
170146
val method = constrParamss(cdef) match {
171147
case xs :: _ if xs.nonEmpty && isRepeatedParamType(xs.last.tpt) => nme.unapplySeq
172148
case _ => nme.unapply
@@ -221,7 +197,7 @@ trait Unapplies extends ast.TreeDSL {
221197
treeCopy.ValDef(vd, Modifiers(flags), vd.name, tpt, rhs)
222198
}
223199

224-
val tparams = cdef.tparams map copyUntypedInvariant
200+
val tparams = constrTparamsInvariant(cdef)
225201
val paramss = classParamss match {
226202
case Nil => Nil
227203
case ps :: pss =>

0 commit comments

Comments
 (0)