@@ -67,7 +67,7 @@ object ProtoTypes {
67
67
case _ =>
68
68
true
69
69
}
70
- if (! res) ctx.typerState.constraint = savedConstraint
70
+ if (! res) ctx.typerState.resetConstraintTo( savedConstraint)
71
71
res
72
72
}
73
73
}
@@ -183,8 +183,8 @@ object ProtoTypes {
183
183
/** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */
184
184
private [this ] var myTypedArg : SimpleIdentityMap [untpd.Tree , Tree ] = SimpleIdentityMap .Empty
185
185
186
- /** A map recording the typer states in which arguments stored in myTypedArg were typed */
187
- private [this ] var evalState : SimpleIdentityMap [untpd.Tree , TyperState ] = SimpleIdentityMap .Empty
186
+ /** A map recording the typer states and constraints in which arguments stored in myTypedArg were typed */
187
+ private [this ] var evalState : SimpleIdentityMap [untpd.Tree , ( TyperState , Constraint ) ] = SimpleIdentityMap .Empty
188
188
189
189
def isMatchedBy (tp : Type )(implicit ctx : Context ) =
190
190
typer.isApplicable(tp, Nil , typedArgs, resultType)
@@ -195,17 +195,19 @@ object ProtoTypes {
195
195
196
196
override def notApplied = WildcardType
197
197
198
- /** Forget the types of any arguments that have been typed producing a constraint in a
199
- * typer state that is not yet committed into the one of the current context `ctx`.
198
+ /** Forget the types of any arguments that have been typed producing a constraint
199
+ * - that is in a typer state that is not yet committed into the one of the current context `ctx`,
200
+ * - or that has been retracted from its typestate because oif a failed operation.
200
201
* This is necessary to avoid "orphan" TypeParamRefs that are referred to from
201
202
* type variables in the typed arguments, but that are not registered in the
202
- * current constraint. A test case is pos/t1756.scala.
203
+ * current constraint. Test cases are pos/t1756.scala and pos/i3538 .scala.
203
204
* @return True if all arguments have types (in particular, no types were forgotten).
204
205
*/
205
206
def allArgTypesAreCurrent ()(implicit ctx : Context ): Boolean = {
206
- evalState foreachBinding { (arg, tstate) =>
207
- if (tstate.uncommittedAncestor.constraint ne ctx.typerState.constraint) {
208
- typr.println(i " need to invalidate $arg / ${myTypedArg(arg)}, ${tstate.constraint}, current = ${ctx.typerState.constraint}" )
207
+ evalState foreachBinding { (arg, tstateConstr) =>
208
+ if ((tstateConstr._1.uncommittedAncestor.constraint `ne` ctx.typerState.constraint) ||
209
+ tstateConstr._2.isRetracted) {
210
+ typr.println(i " need to invalidate $arg / ${myTypedArg(arg)}, ${tstateConstr._2}, current = ${ctx.typerState.constraint}" )
209
211
myTypedArg = myTypedArg.remove(arg)
210
212
evalState = evalState.remove(arg)
211
213
}
@@ -219,7 +221,7 @@ object ProtoTypes {
219
221
targ = typerFn(arg)
220
222
if (! ctx.reporter.hasPending) {
221
223
myTypedArg = myTypedArg.updated(arg, targ)
222
- evalState = evalState.updated(arg, ctx.typerState)
224
+ evalState = evalState.updated(arg, ( ctx.typerState, ctx.typerState.constraint) )
223
225
}
224
226
}
225
227
targ
0 commit comments