Skip to content

Commit 25ee6fc

Browse files
author
AlexSikia
committed
Adapt instance of TreeTypeMap to map trees recursively
Solves an issue involving return values not being specialized. Test `return_specialization` illustrates this.
1 parent 7650895 commit 25ee6fc

File tree

8 files changed

+68
-35
lines changed

8 files changed

+68
-35
lines changed

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ object Trees {
109109
*/
110110
val uniqueId = {
111111
nextId += 1
112-
/*if (nextId == 651)
113-
println("asdsad")*/
112+
if (nextId == 72)
113+
println("asdsad")
114114
//assert(nextId != 214, this)
115115
nextId
116116
}

src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ object Symbols {
344344

345345
type ThisName <: Name
346346
private[this] var _id: Int = nextId
347-
/*if (_id == 651) {
347+
if (_id == 16651) {
348348
println("plop")
349-
}*/
349+
}
350350
//assert(_id != 30214)
351351

352352
/** The unique id of this symbol */

src/dotty/tools/dotc/transform/TypeSpecializer.scala

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
102102
(implicit ctx: Context): List[Symbol] = {
103103
val newSym =
104104
ctx.newSymbol(decl.owner, (decl.name + names.mkString).toTermName,
105-
decl.flags | Flags.Synthetic, poly.instantiate(instantiations.toList))
105+
decl.flags | Flags.Synthetic,poly.instantiate(instantiations.toList))
106+
//poly.derivedPolyType(poly.paramNames, poly.paramBounds,
107+
// poly.instantiate(instantiations.toList)))
106108
val map = newSymbolMap.getOrElse(decl, mutable.HashMap.empty)
107109
map.put(instantiations, newSym)
108110
newSymbolMap.put(decl, map)
@@ -150,26 +152,39 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
150152
def specialize(decl : Symbol): List[Tree] = {
151153
if (newSymbolMap.contains(decl)) {
152154
val declSpecs = newSymbolMap(decl)
155+
153156
val newSyms = declSpecs.values.toList
154157
val instantiations = declSpecs.keys.toArray
155158
var index = -1
156159
println(s"specializing ${tree.symbol} for $origTParams")
157-
newSyms.map { newSym =>
158-
index += 1
159-
polyDefDef(newSym.asTerm, { tparams => vparams => {
160-
assert(tparams.isEmpty)
161-
new TreeTypeMap(
162-
typeMap = _
163-
.substDealias(origTParams, instantiations(index))
164-
.subst(origVParams, vparams.flatten.map(_.tpe)),
165-
oldOwners = tree.symbol :: Nil,
166-
newOwners = newSym :: Nil
167-
).transform(tree.rhs)
168-
}})
169-
}
160+
/*val attempted = newSyms.zip(*/newSyms.map { newSym =>
161+
index += 1
162+
polyDefDef(newSym.asTerm, { tparams => vparams => {
163+
//assert(tparams.isEmpty)
164+
165+
val tmap: (Tree => Tree) = _ match {
166+
case Return(t, from) if from.symbol == tree.symbol => Return(t, ref(newSym))
167+
case t: TypeApply => transformTypeApply(t)
168+
case t => t
169+
}
170+
171+
new TreeTypeMap(
172+
treeMap = tmap,
173+
typeMap = _
174+
.substDealias(origTParams, instantiations(index))
175+
.subst(origVParams, vparams.flatten.map(_.tpe))
176+
,
177+
oldOwners = tree.symbol :: Nil,
178+
newOwners = newSym :: Nil
179+
).transform(tree.rhs)
180+
}
181+
})
182+
}//)
183+
//attempted.filterNot(a => failedSpec.contains(a._1)).map(_._2)
170184
} else Nil
171185
}
172-
Thicket(tree :: specialize(tree.symbol))
186+
val specialized_trees = specialize(tree.symbol)
187+
Thicket(tree :: specialized_trees)
173188
case _ => tree
174189
}
175190
}
@@ -206,4 +221,16 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
206221
} else tree
207222
} else tree
208223
}
209-
}
224+
}
225+
226+
/**
227+
* var failedSpec: List[Symbol] = List()
228+
*
229+
*
230+
* match {
231+
case t if !poly.bounds.contains(t) => {
232+
failedSpec = newSym :: failedSpec
233+
t
234+
}
235+
case t => t
236+
*/

test/dotc/tests.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,19 @@ class tests extends CompilerTest {
207207
208208
val javaDir = "./tests/pos/java-interop/"
209209
@Test def java_all = compileFiles(javaDir, twice)
210-
*/
211210
212-
//@Test def specialization = compileFile(specialDir, "specialization")//, specialise)
213-
//@Test def mutual_spec = compileFile(specialDir, "mutual_specialization")
211+
*/
212+
//@Test def specialization = compileFile(specialDir, "specialization")
213+
//@Test def mutual_spec = compileFile(specialDir, "mutual_specialization", List("-Xprint:all"))
214214
//@Test def return_spec = compileFile(specialDir, "return_specialization")
215-
//@Test def nothing_spec = compileFile(specialDir, "nothing_specialization")
216-
//@Test def method_in_class_spec = compileFile(specialDir, "method_in_class_specialization")
217-
//@Test def method_in_method_spec = compileFile(specialDir, "method_in_method_specialization", List("-Xprint:all"))
218-
@Test def type_check_spec = compileFile(specialDir, "type_check_specialization")
219-
//@Test def bounds_spec = compileFile(specialDir, "bounds_specialization", List("-Xprint:all"))
220-
//@Test def multi_spec = compileFile(specialDir, "multi_specialization", List("-Xprint:all"))
221-
//@Test def pos_spec_all = compileFiles(specialDir)
215+
// @Test def nothing_spec = compileFile(specialDir, "nothing_specialization")
216+
// @Test def method_in_class_spec = compileFile(specialDir, "method_in_class_specialization")
217+
// @Test def method_in_method_spec = compileFile(specialDir, "method_in_method_specialization")
218+
// @Test def pos_type_check = compileFile(specialDir, "type_test")
219+
// @Test def bounds_spec = compileFile(specialDir, "bounds_specialization")
220+
// @Test def multi_spec = compileFile(specialDir, "multi_specialization")
221+
// @Test def pos_spec_all = compileFiles(specialDir)
222+
@Test def pos_this_specialization = compileFile(specialDir, "this_specialization", List("-Xprint:specialize"))
222223

223224
//@Test def mini_method = compileFiles(miniMethodDir)//, List("-Xprint:all"))
224225
//@Test def mini_more = compileFiles(miniMoreDir)//, List("-Xprint:all"))
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object return_specialization {
2-
def qwa[@specialized T](a: (String, String) => T, b: T): T = {
3-
if(a ne this) return a("1", "2")
2+
def qwa[@specialized(Int) T](a: (T, T) => T, b: T): T = {
3+
if(a ne this) return a(b, b)
44
else b
55
}
66
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
sealed abstract class Foo[@specialized +A] {
2+
def bop[@specialized B >: A]: Foo[B] = new Bar[B](this)
3+
}
4+
5+
case class Bar[@specialized a](tl: Foo[a]) extends Foo[a]

tests/pos/specialization/type_check_specialization.scala

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object type_test {
2+
def typeTest(i: Char): Unit = i.isInstanceOf[Int]
3+
}

0 commit comments

Comments
 (0)