@@ -43,7 +43,9 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
43
43
override def widenSkolems = true
44
44
45
45
def run (using Context ): Unit =
46
- newRechecker().checkUnit(ctx.compilationUnit)
46
+ val rechecker = newRechecker()
47
+ rechecker.reinferAll.traverse(ctx.compilationUnit.tpdTree)
48
+ rechecker.checkUnit(ctx.compilationUnit)
47
49
48
50
def newRechecker ()(using Context ): Rechecker
49
51
@@ -63,36 +65,41 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
63
65
else sym.flags
64
66
).installAfter(preRecheckPhase)
65
67
66
- /** Hooks to be overridden */
67
- protected def transformType (tp : Type , inferred : Boolean )(using Context ): Type = tp
68
-
69
- def enterDef (stat : Tree )(using Context ): Unit =
70
- val sym = stat.symbol
71
- val info1 = stat match
72
- case stat : ValOrDefDef if stat.tpt.isInstanceOf [InferredTypeTree ] =>
73
- stat match
74
- case stat : DefDef => // enter paramss early since result type refers to them
75
- stat.paramss.foreach(_.foreach(enterDef))
76
- case _ =>
77
- def integrateRT (restp : Type , info : Type , psymss : List [List [Symbol ]]): Type = info match
78
- case info : MethodOrPoly =>
79
- info.derivedLambdaType(resType =
80
- integrateRT(restp.subst(psymss.head, info.paramRefs), info.resType, psymss.tail))
81
- case info : ExprType =>
82
- info.derivedExprType(resType = restp)
83
- case _ =>
84
- restp
85
- integrateRT(recheck(stat.tpt), sym.info, sym.paramSymss)
86
- case _ =>
87
- sym.info
88
- val info2 = transformType(info1, inferred = stat.isInstanceOf [Bind ])
89
- recheckr.println(i " update info $sym: ${sym.info} --> $info1 --> $info2" )
90
- sym.updateInfo(info2)
91
-
92
68
extension (tpe : Type ) def rememberFor (tree : Tree )(using Context ): Unit =
93
69
if (tpe ne tree.tpe) && ! tree.hasAttachment(RecheckedType ) then
94
70
tree.putAttachment(RecheckedType , tpe)
95
71
72
+ def knownType (tree : Tree ) =
73
+ tree.attachmentOrElse(RecheckedType , tree.tpe)
74
+
75
+ def reinfer (tp : Type )(using Context ): Type = tp
76
+
77
+ object reinferAll extends TreeTraverser :
78
+ def traverse (tree : Tree )(using Context ) =
79
+ traverseChildren(tree)
80
+ tree match
81
+ case tree : InferredTypeTree =>
82
+ reinfer(tree.tpe).rememberFor(tree)
83
+ case tree : ValOrDefDef if tree.tpt.isInstanceOf [InferredTypeTree ] =>
84
+ val sym = tree.symbol
85
+ def integrateRT (restp : Type , info : Type , psymss : List [List [Symbol ]]): Type = info match
86
+ case info : MethodOrPoly =>
87
+ info.derivedLambdaType(resType =
88
+ integrateRT(restp.subst(psymss.head, info.paramRefs), info.resType, psymss.tail))
89
+ case info : ExprType =>
90
+ info.derivedExprType(resType = restp)
91
+ case _ =>
92
+ restp
93
+ if ! sym.isConstructor then
94
+ val info1 = integrateRT(knownType(tree.tpt), sym.info, sym.paramSymss)
95
+ recheckr.println(i " update info $sym: ${sym.info} --> $info1" )
96
+ sym.updateInfo(info1)
97
+ case tree : Bind =>
98
+ val sym = tree.symbol
99
+ sym.updateInfo(reinfer(sym.info))
100
+ case _ =>
101
+ end reinferAll
102
+
96
103
def constFold (tree : Tree , tp : Type )(using Context ): Type =
97
104
val tree1 = tree.withType(tp)
98
105
val tree2 = ConstFold (tree1)
@@ -115,7 +122,6 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
115
122
116
123
def recheckBind (tree : Bind , pt : Type )(using Context ): Type = tree match
117
124
case Bind (name, body) =>
118
- enterDef(tree)
119
125
recheck(body, pt)
120
126
val sym = tree.symbol
121
127
if sym.isType then sym.typeRef else sym.info
@@ -131,9 +137,6 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
131
137
sym.termRef
132
138
133
139
def recheckDefDef (tree : DefDef , sym : Symbol )(using Context ): Type =
134
- if ! tree.tpt.isInstanceOf [InferredTypeTree ] then
135
- // otherwise paramss were already entered
136
- tree.paramss.foreach(_.foreach(enterDef))
137
140
val rhsCtx = linkConstructorParams(sym)
138
141
if ! tree.rhs.isEmpty && ! sym.isInlineMethod && ! sym.isEffectivelyErased then
139
142
inContext(rhsCtx) { recheck(tree.rhs, recheck(tree.tpt)) }
@@ -256,12 +259,7 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
256
259
seqLitType(tree, TypeComparer .lub(declaredElemType :: elemTypes))
257
260
258
261
def recheckTypeTree (tree : TypeTree )(using Context ): Type =
259
- tree.getAttachment(RecheckedType ) match
260
- case Some (tp) => tp
261
- case None =>
262
- val tp = transformType(tree.tpe, tree.isInstanceOf [InferredTypeTree ])
263
- tp.rememberFor(tree)
264
- tp
262
+ knownType(tree)
265
263
266
264
def recheckAnnotated (tree : Annotated )(using Context ): Type =
267
265
tree.tpe match
@@ -278,7 +276,6 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
278
276
NoType
279
277
280
278
def recheckStats (stats : List [Tree ])(using Context ): Unit =
281
- stats.foreach(enterDef)
282
279
stats.foreach(recheck(_))
283
280
284
281
/** Recheck tree without adapting it, returning its new type.
0 commit comments