Skip to content

Commit 704d1e1

Browse files
committed
Move normalization and comparison logic to the E-Graph
1 parent 92b0bc2 commit 704d1e1

File tree

10 files changed

+535
-571
lines changed

10 files changed

+535
-571
lines changed

compiler/src/dotty/tools/dotc/qualified_types/EGraph.scala

Lines changed: 400 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package dotty.tools.dotc.qualified_types
2+
3+
import dotty.tools.dotc.core.Contexts.Context
4+
import dotty.tools.dotc.core.Hashable.Binders
5+
import dotty.tools.dotc.core.Names.Designator
6+
import dotty.tools.dotc.core.Names.Name
7+
import dotty.tools.dotc.core.StdNames.nme
8+
import dotty.tools.dotc.core.StdNames.tpnme
9+
import dotty.tools.dotc.core.Symbols.Symbol
10+
import dotty.tools.dotc.core.Types.{
11+
CachedProxyType,
12+
ConstantType,
13+
MethodType,
14+
NamedType,
15+
NoPrefix,
16+
SingletonType,
17+
TermRef,
18+
ThisType,
19+
Type
20+
}
21+
22+
// xs.forall(x == 2) <=> xs.forall(x == 2)
23+
24+
enum ENode:
25+
import ENode.*
26+
27+
case Atom(tp: SingletonType)
28+
case New(clazz: ENode)
29+
case Select(qual: ENode, member: Symbol)
30+
case Apply(fn: ENode, args: List[ENode])
31+
case OpApply(fn: ENode.Op, args: List[ENode])
32+
case TypeApply(fn: ENode, args: List[Type])
33+
case Lambda(paramTps: List[Type], retTp: Type, body: ENode)
34+
35+
override def toString(): String =
36+
this match
37+
case Atom(tp) => typeToString(tp)
38+
case New(clazz) => s"new $clazz"
39+
case Select(qual, member) => s"$qual.${designatorToString(member)}"
40+
case Apply(fn, args) => s"$fn(${args.mkString(", ")})"
41+
case OpApply(op, args) => s"(${args.mkString(op.operatorString())})"
42+
case TypeApply(fn, args) => s"$fn[${args.map(typeToString).mkString(", ")}]"
43+
case Lambda(paramTps, retTp, body) =>
44+
s"(${paramTps.map(typeToString).mkString(", ")}): ${{ typeToString(retTp) }} => $body"
45+
46+
object ENode:
47+
private def typeToString(tp: Type): String =
48+
tp match
49+
case tp: NamedType =>
50+
val prefixString = if isEmptyPrefix(tp.prefix) then "" else typeToString(tp.prefix) + "."
51+
prefixString + designatorToString(tp.designator)
52+
case tp: ConstantType =>
53+
tp.value.value.toString
54+
case tp: ThisType =>
55+
typeToString(tp.tref) + ".this"
56+
case _ =>
57+
tp.toString
58+
59+
private def isEmptyPrefix(tp: Type): Boolean =
60+
tp match
61+
case tp: NoPrefix.type =>
62+
true
63+
case tp: ThisType =>
64+
tp.tref.designator match
65+
case d: Symbol => d.lastKnownDenotation.name.toTermName == nme.EMPTY_PACKAGE
66+
case _ => false
67+
case _ => false
68+
69+
private def designatorToString(d: Designator): String =
70+
d match
71+
case d: Symbol => d.lastKnownDenotation.name.toString
72+
case _ => d.toString
73+
74+
enum Op:
75+
case IntSum
76+
case IntProduct
77+
case LongSum
78+
case LongProduct
79+
case Equal
80+
case Not
81+
case And
82+
case Or
83+
case LessThan
84+
85+
def operatorString(): String =
86+
this match
87+
case IntSum => "+"
88+
case IntProduct => "*"
89+
case LongSum => "+"
90+
case LongProduct => "*"
91+
case Equal => "=="
92+
case Not => "!"
93+
case And => "&&"
94+
case Or => "||"
95+
case LessThan => "<"
96+
97+
/** Reference to the argument of an [[ENode.Lambda]].
98+
*
99+
* @param index 
100+
* Debruijn index of the argument, starting from 0
101+
* @param underyling
102+
* Underlying type of the argument
103+
*/
104+
final case class ArgRefType(index: Int, underlying: Type) extends CachedProxyType, SingletonType:
105+
override def underlying(using Context): Type = underlying
106+
override def computeHash(bs: Binders): Int = doHash(bs, index, underlying)

compiler/src/dotty/tools/dotc/qualified_types/QualifierComparer.scala

Lines changed: 0 additions & 112 deletions
This file was deleted.

0 commit comments

Comments
 (0)