Skip to content

Commit 3468fa5

Browse files
committed
Add Recheckers
1 parent e7eb856 commit 3468fa5

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ object Printers {
3838
val pickling = noPrinter
3939
val quotePickling = noPrinter
4040
val plugins = noPrinter
41+
val recheckr = noPrinter
4142
val refcheck = noPrinter
4243
val simplify = noPrinter
4344
val staging = noPrinter
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package dotty.tools
2+
package dotc
3+
package transform
4+
5+
import core.*
6+
import Symbols.*, Contexts.*, Types.*, ContextOps.*, Decorators.*, SymDenotations.*
7+
import Flags.*
8+
import Phases.Phase
9+
import DenotTransformers.IdentityDenotTransformer
10+
import ast.*
11+
import typer.ProtoTypes.*
12+
import config.Printers.recheckr
13+
14+
class Recheck extends Phase, IdentityDenotTransformer:
15+
thisPhase =>
16+
17+
import ast.tpd.*
18+
19+
def preRecheckPhase = this.prev.asInstanceOf[PreRecheck]
20+
21+
def run(using Context): Unit =
22+
val refiner = newRechecker()
23+
val unit = ctx.compilationUnit
24+
recheckr.println(i"recheck types of $unit")
25+
newRechecker().check()
26+
27+
def newRechecker()(using Context): Rechecker = Rechecker(ctx)
28+
29+
class Rechecker(ictx: Context):
30+
val ta = ictx.typeAssigner
31+
32+
extension (sym: Symbol) def updateInfo(newInfo: Type)(using Context): Unit =
33+
sym.copySymDenotation().installAfter(thisPhase) // reset
34+
sym.copySymDenotation(
35+
info = newInfo,
36+
initFlags =
37+
if newInfo.isInstanceOf[LazyType] then sym.flags &~ Touched
38+
else sym.flags
39+
).installAfter(preRecheckPhase)
40+
41+
def recheckIdent(tree: Ident)(using Context): Type =
42+
ta.ensureAccessible(tree.symbol.namedType, superAccess = false, tree.srcPos)
43+
44+
def recheckSelect(tree: Select, pt: Type)(using Context): Type = tree match
45+
case Select(qual, name) =>
46+
val superAccess = qual.isInstanceOf[Super]
47+
val qualType = recheck(qual, WildcardType)
48+
val pre = ta.maybeSkolemizePrefix(qualType, name)
49+
val mbr = qualType.findMember(name, pre)
50+
assert(ta.reallyExists(mbr))
51+
val rawType = qualType.select(name, mbr)
52+
ta.accessibleType(rawType, superAccess)
53+
54+
def recheckBind(tree: Bind, pt: Type)(using Context): Type = tree match
55+
case Bind(name, body) =>
56+
val bodyType = recheck(body, pt)
57+
tree.symbol.updateInfo(pt & bodyType)
58+
tree.tpe
59+
60+
def recheckLabeled(tree: Labeled)(using Context): Type = tree match
61+
case Labeled(bind, expr) =>
62+
recheck(bind, WildcardType)
63+
val info = bind.symbol.info
64+
recheck(expr, info)
65+
info
66+
67+
def recheckValDef(tree: ValDef, sym: Symbol)(using Context): Type = ???
68+
def recheckDefDef(tree: DefDef, sym: Symbol)(using Context): Type = ???
69+
def recheckTypeDef(tree: TypeDef, sym: Symbol)(using Context): Type = ???
70+
def recheckClassDef(tree: TypeDef, sym: ClassSymbol)(using Context): Type = ???
71+
72+
def recheckApply(tree: Apply, pt: Type)(using Context): Type = ???
73+
def recheckThis(tree: This)(using Context): Type = ???
74+
def recheckTypeApply(tree: TypeApply, pt: Type)(using Context): Type = ???
75+
def recheckLiteral(tree: Literal)(using Context): Type = ???
76+
def recheckNew(tree: New, pt: Type)(using Context): Type = ???
77+
def recheckTyped(tree: Typed, pt: Type)(using Context): Type = ???
78+
def recheckAssign(tree: Assign, pt: Type)(using Context): Type = ???
79+
def recheckBlock(tree: Block, pt: Type)(using Context): Type = ???
80+
def recheckIf(tree: If, pt: Type)(using Context): Type = ???
81+
def recheckClosure(tree: Closure, pt: Type)(using Context): Type = ???
82+
def recheckMatch(tree: Match, pt: Type)(using Context): Type = ???
83+
def recheckReturn(tree: Return)(using Context): Type = ???
84+
def recheckWhileDo(tree: WhileDo)(using Context): Type = ???
85+
def recheckTry(tree: Try, pt: Type)(using Context): Type = ???
86+
def recheckSuper(tree: Super, pt: Type)(using Context): Type = ???
87+
def recheckSeqLiteral(tree: SeqLiteral, pt: Type)(using Context): Type = ???
88+
def recheckInlined(tree: Inlined, pt: Type)(using Context): Type = ???
89+
def recheckTypeTree(tree: TypeTree, pt: Type)(using Context): Type = ???
90+
def recheckPackageDef(tree: PackageDef)(using Context): Type = ???
91+
92+
/** Typecheck tree without adapting it, returning a recheck tree.
93+
* @param initTree the unrecheck tree
94+
* @param pt the expected result type
95+
* @param locked the set of type variables of the current typer state that cannot be interpolated
96+
* at the present time
97+
*/
98+
def recheck(tree: Tree, pt: Type)(using Context): Type =
99+
100+
def recheckNamed(tree: NameTree, pt: Type)(using Context): Type =
101+
val sym = tree.symbol
102+
tree match
103+
case tree: Ident => recheckIdent(tree)
104+
case tree: Select => recheckSelect(tree, pt)
105+
case tree: Bind => recheckBind(tree, pt)
106+
case tree: ValDef =>
107+
if tree.isEmpty then NoType
108+
else recheckValDef(tree, sym)(using ctx.localContext(tree, sym))
109+
case tree: DefDef =>
110+
recheckDefDef(tree, sym)(using ctx.localContext(tree, sym))
111+
case tree: TypeDef =>
112+
if tree.isClassDef then
113+
recheckClassDef(tree, sym.asClass)(using ctx.localContext(tree, sym))
114+
else
115+
recheckTypeDef(tree, sym)(using ctx.localContext(tree, sym).setNewScope)
116+
case tree: Labeled => recheckLabeled(tree)
117+
118+
def recheckUnnamed(tree: Tree, pt: Type): Type = tree match
119+
case tree: Apply => recheckApply(tree, pt)
120+
case tree: This => recheckThis(tree)
121+
case tree: TypeApply => recheckTypeApply(tree, pt)
122+
case tree: Literal => recheckLiteral(tree)
123+
case tree: New => recheckNew(tree, pt)
124+
case tree: Typed => recheckTyped(tree, pt)
125+
case tree: Assign => recheckAssign(tree, pt)
126+
case tree: Block => recheckBlock(tree, pt)(using ctx.fresh.setNewScope)
127+
case tree: If => recheckIf(tree, pt)
128+
case tree: Closure => recheckClosure(tree, pt)
129+
case tree: Match => recheckMatch(tree, pt)
130+
case tree: Return => recheckReturn(tree)
131+
case tree: WhileDo => recheckWhileDo(tree)
132+
case tree: Try => recheckTry(tree, pt)
133+
case tree: Super => recheckSuper(tree, pt)
134+
case tree: SeqLiteral => recheckSeqLiteral(tree, pt)
135+
case tree: Inlined => recheckInlined(tree, pt)
136+
case tree: TypeTree => recheckTypeTree(tree, pt)
137+
case tree: PackageDef => recheckPackageDef(tree)
138+
139+
try
140+
val result = tree match
141+
case tree: NameTree => recheckNamed(tree, pt)
142+
case tree => recheckUnnamed(tree, pt)
143+
checkConforms(result, pt, tree)
144+
result
145+
catch case ex: Exception =>
146+
println(i"error while rechecking $tree")
147+
throw ex
148+
end recheck
149+
150+
def checkConforms(tpe: Type, pt: Type, tree: Tree)(using Context): Unit = tree match
151+
case tree: DefTree =>
152+
case _ => ???
153+
154+
def check()(using Context): Unit =
155+
val unit = ictx.compilationUnit
156+
recheck(unit.tpdTree, WildcardType)
157+
158+
end Rechecker
159+
end Recheck

0 commit comments

Comments
 (0)