@@ -67,7 +67,7 @@ object ProtoTypes {
6767 case _ =>
6868 true
6969 }
70- if (! res) ctx.typerState.constraint = savedConstraint
70+ if (! res) ctx.typerState.resetConstraintTo( savedConstraint)
7171 res
7272 }
7373 }
@@ -183,8 +183,8 @@ object ProtoTypes {
183183 /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */
184184 private [this ] var myTypedArg : SimpleIdentityMap [untpd.Tree , Tree ] = SimpleIdentityMap .Empty
185185
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
188188
189189 def isMatchedBy (tp : Type )(implicit ctx : Context ) =
190190 typer.isApplicable(tp, Nil , typedArgs, resultType)
@@ -195,17 +195,19 @@ object ProtoTypes {
195195
196196 override def notApplied = WildcardType
197197
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.
200201 * This is necessary to avoid "orphan" TypeParamRefs that are referred to from
201202 * 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.
203204 * @return True if all arguments have types (in particular, no types were forgotten).
204205 */
205206 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}" )
209211 myTypedArg = myTypedArg.remove(arg)
210212 evalState = evalState.remove(arg)
211213 }
@@ -219,7 +221,7 @@ object ProtoTypes {
219221 targ = typerFn(arg)
220222 if (! ctx.reporter.hasPending) {
221223 myTypedArg = myTypedArg.updated(arg, targ)
222- evalState = evalState.updated(arg, ctx.typerState)
224+ evalState = evalState.updated(arg, ( ctx.typerState, ctx.typerState.constraint) )
223225 }
224226 }
225227 targ
0 commit comments