@@ -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 that is
199
+ * either
200
+ * - in a typer state that is not yet committed into the one of the current context `ctx`, or
201
+ * - has been retracted from its typestate because oif a failed operation.
200
202
* This is necessary to avoid "orphan" TypeParamRefs that are referred to from
201
203
* type variables in the typed arguments, but that are not registered in the
202
- * current constraint. A test case is pos/t1756.scala.
204
+ * current constraint. Test cases are pos/t1756.scala and pos/i3538 .scala.
203
205
* @return True if all arguments have types (in particular, no types were forgotten).
204
206
*/
205
207
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} " )
208
+ evalState foreachBinding { (arg, tstateConstr ) =>
209
+ if ((tstateConstr._1. uncommittedAncestor.constraint `ne` ctx.typerState.constraint) ||
210
+ tstateConstr._2.isRetracted) {
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