Skip to content
Snippets Groups Projects
Commit b166dee3 authored by Etienne Kneuss's avatar Etienne Kneuss
Browse files

Base for canBeSubtypeOf

parent 2f62cb98
No related branches found
No related tags found
No related merge requests found
...@@ -11,29 +11,75 @@ import Trees._ ...@@ -11,29 +11,75 @@ import Trees._
import Extractors._ import Extractors._
object TypeTreeOps { object TypeTreeOps {
def canBeSubtypeOf(tpe: TypeTree, freeParams: Seq[TypeParameterDef], stpe: TypeTree): Option[Seq[TypeParameter]] = { def canBeSubtypeOf(tpe: TypeTree, freeParams: Seq[TypeParameter], stpe: TypeTree): Option[Map[TypeParameter, TypeTree]] = {
def unify(res: Seq[Option[Map[TypeParameter, TypeTree]]]): Option[Map[TypeParameter, TypeTree]] = {
if (res.forall(_.isDefined)) {
var result = Map[TypeParameter, TypeTree]()
for (Some(m) <- res) {
result ++= m
}
Some(result)
} else {
None
}
}
if (freeParams.isEmpty) { if (freeParams.isEmpty) {
if (isSubtypeOf(tpe, stpe)) { if (isSubtypeOf(tpe, stpe)) {
Some(Nil) Some(Map())
} else { } else {
None None
} }
} else { } else {
// TODO (tpe, stpe) match {
None case (tp1: TypeParameter, t) =>
} if (freeParams contains tp1) {
} Some(Map(tp1 -> t))
} else if (tp1 == t) {
Some(Map())
} else {
None
}
def bestRealType(t: TypeTree) : TypeTree = t match { case (ct1: ClassType, ct2: ClassType) =>
case c: CaseClassType => val rt1 = ct1.root
c.classDef.parent match { val rt2 = ct2.root
case None =>
c
if (rt1.classDef == rt2.classDef) {
unify((rt1.tps zip rt2.tps).map { case (tp1, tp2) =>
canBeSubtypeOf(tp1, freeParams, tp2)
})
} else {
None
}
case (_: TupleType, _: TupleType) |
(_: SetType, _: SetType) |
(_: MapType, _: MapType) |
(_: FunctionType, _: FunctionType) =>
val NAryType(ts1, _) = tpe
val NAryType(ts2, _) = stpe
case Some(p) => unify((ts1 zip ts2).map { case (tp1, tp2) =>
instantiateType(p, (c.classDef.tparams zip c.tps).toMap) canBeSubtypeOf(tp1, freeParams, tp2)
})
case (t1, t2) =>
if (t1 == t2) {
Some(Map())
} else {
None
}
} }
}
}
def bestRealType(t: TypeTree) : TypeTree = t match {
case (c: CaseClassType) => c.root
case NAryType(tps, builder) => builder(tps.map(bestRealType)) case NAryType(tps, builder) => builder(tps.map(bestRealType))
} }
......
...@@ -151,6 +151,8 @@ object TypeTrees { ...@@ -151,6 +151,8 @@ object TypeTrees {
lazy val fieldsTypes = fields.map(_.tpe) lazy val fieldsTypes = fields.map(_.tpe)
lazy val root = parent.getOrElse(this)
lazy val parent = classDef.parent.map { lazy val parent = classDef.parent.map {
pct => instantiateType(pct, (classDef.tparams zip tps).toMap) match { pct => instantiateType(pct, (classDef.tparams zip tps).toMap) match {
case act: AbstractClassType => act case act: AbstractClassType => act
......
...@@ -130,10 +130,12 @@ case object CEGIS extends Rule("CEGIS") { ...@@ -130,10 +130,12 @@ case object CEGIS extends Rule("CEGIS") {
false false
} }
if (!isRecursiveCall && isNotSynthesizable) { if (!isRecursiveCall && isNotSynthesizable) {
canBeSubtypeOf(fd.returnType, fd.tparams, t) match { val free = fd.tparams.map(_.tp)
case Some(tps) => canBeSubtypeOf(fd.returnType, free, t) match {
Some(fd.typed(tps)) case Some(tpsMap) =>
Some(fd.typed(free.map(tp => tpsMap.getOrElse(tp, tp))))
case None => case None =>
None None
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment