Skip to content

Commit a989de8

Browse files
committed
Improve treatment of typedArgs
1 parent 5d8725d commit a989de8

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

compiler/src/dotty/tools/dotc/core/TyperState.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,8 @@ class TyperState(previous: TyperState /* | Null */) {
144144
Stats.record("typerState.commit")
145145
val targetState = ctx.typerState
146146
assert(isCommittable)
147-
targetState.constraint =
148-
if (targetState.constraint eq previousConstraint) constraint
149-
else targetState.constraint & (constraint, otherHasErrors = reporter.errorsReported)
147+
if (targetState.constraint eq previousConstraint) targetState.constraint = constraint
148+
else targetState.mergeConstraintWith(this)
150149
constraint foreachTypeVar { tvar =>
151150
if (tvar.owningState.get eq this) tvar.owningState = new WeakReference(targetState)
152151
}
@@ -156,6 +155,9 @@ class TyperState(previous: TyperState /* | Null */) {
156155
isCommitted = true
157156
}
158157

158+
def mergeConstraintWith(that: TyperState)(implicit ctx: Context): Unit =
159+
constraint = constraint & (that.constraint, otherHasErrors = that.reporter.errorsReported)
160+
159161
/** Make type variable instances permanent by assigning to `inst` field if
160162
* type variable instantiation cannot be retracted anymore. Then, remove
161163
* no-longer needed constraint entries.

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ object ProtoTypes {
244244
* [](args): resultType
245245
*/
246246
case class FunProto(args: List[untpd.Tree], resType: Type)(typer: Typer,
247-
override val isContextual: Boolean, state: FunProtoState = new FunProtoState)(implicit ctx: Context)
247+
override val isContextual: Boolean, state: FunProtoState = new FunProtoState)(implicit val ctx: Context)
248248
extends UncachedGroundType with ApplyingProto with FunOrPolyProto {
249249
override def resultType(implicit ctx: Context): Type = resType
250250

@@ -298,13 +298,26 @@ object ProtoTypes {
298298

299299
/** The typed arguments. This takes any arguments already typed using
300300
* `typedArg` into account.
301+
*
302+
* Arguments are typechecked in the typerState where the FunProto was created.
303+
* However, any constraint changes are also propagated to the currently passed
304+
* context.
305+
*
301306
*/
302-
def unforcedTypedArgs: List[Tree] =
307+
def unforcedTypedArgs(implicit ctx: Context): List[Tree] =
303308
if (state.typedArgs.size == args.length) state.typedArgs
304309
else {
305-
val args1 = args.mapconserve(cacheTypedArg(_, typer.typed(_), force = false))
306-
if (!args1.exists(arg => isUndefined(arg.tpe))) state.typedArgs = args1
307-
args1
310+
val prevConstraint = this.ctx.typerState.constraint
311+
312+
try {
313+
implicit val ctx = this.ctx
314+
val args1 = args.mapconserve(cacheTypedArg(_, typer.typed(_), force = false))
315+
if (!args1.exists(arg => isUndefined(arg.tpe))) state.typedArgs = args1
316+
args1
317+
}
318+
finally
319+
if (this.ctx.typerState.constraint ne prevConstraint)
320+
ctx.typerState.mergeConstraintWith(this.ctx.typerState)
308321
}
309322

310323
/** Type single argument and remember the unadapted result in `myTypedArg`.
@@ -372,7 +385,7 @@ object ProtoTypes {
372385
* [](args): resultType, where args are known to be typed
373386
*/
374387
class FunProtoTyped(args: List[tpd.Tree], resultType: Type)(typer: Typer, isContextual: Boolean)(implicit ctx: Context) extends FunProto(args, resultType)(typer, isContextual)(ctx) {
375-
override def unforcedTypedArgs: List[tpd.Tree] = args
388+
override def unforcedTypedArgs(implicit ctx: Context): List[tpd.Tree] = args
376389
override def withContext(ctx: Context): FunProtoTyped = this
377390
}
378391

0 commit comments

Comments
 (0)