@@ -210,28 +210,38 @@ object ProtoTypes {
210210
211211 trait ApplyingProto extends ProtoType
212212
213+ class FunProtoState {
214+
215+ /** The list of typed arguments, if all arguments are typed */
216+ var typedArgs : List [Tree ] = Nil
217+
218+ /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */
219+ var typedArg : SimpleIdentityMap [untpd.Tree , Tree ] = SimpleIdentityMap .Empty
220+
221+ /** A map recording the typer states and constraints in which arguments stored in myTypedArg were typed */
222+ var evalState : SimpleIdentityMap [untpd.Tree , (TyperState , Constraint )] = SimpleIdentityMap .Empty
223+
224+ /** The tupled version of this prototype, if it has been computed */
225+ var tupled : Type = NoType
226+
227+ /** If true, the application of this prototype was canceled. */
228+ var toDrop : Boolean = false
229+ }
230+
213231 /** A prototype for expressions that appear in function position
214232 *
215233 * [](args): resultType
216234 */
217- case class FunProto (args : List [untpd.Tree ], resType : Type , typer : Typer )(implicit ctx : Context )
235+ case class FunProto (args : List [untpd.Tree ], resType : Type )( typer : Typer , state : FunProtoState = new FunProtoState )(implicit ctx : Context )
218236 extends UncachedGroundType with ApplyingProto {
219- private [this ] var myTypedArgs : List [Tree ] = Nil
220-
221237 override def resultType (implicit ctx : Context ) = resType
222238
223- /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */
224- private [this ] var myTypedArg : SimpleIdentityMap [untpd.Tree , Tree ] = SimpleIdentityMap .Empty
225-
226- /** A map recording the typer states and constraints in which arguments stored in myTypedArg were typed */
227- private [this ] var evalState : SimpleIdentityMap [untpd.Tree , (TyperState , Constraint )] = SimpleIdentityMap .Empty
228-
229239 def isMatchedBy (tp : Type )(implicit ctx : Context ) =
230240 typer.isApplicable(tp, Nil , unforcedTypedArgs, resultType)
231241
232242 def derivedFunProto (args : List [untpd.Tree ] = this .args, resultType : Type , typer : Typer = this .typer) =
233243 if ((args eq this .args) && (resultType eq this .resultType) && (typer eq this .typer)) this
234- else new FunProto (args, resultType, typer)
244+ else new FunProto (args, resultType)( typer)
235245
236246 override def notApplied = WildcardType
237247
@@ -244,19 +254,19 @@ object ProtoTypes {
244254 * @return True if all arguments have types (in particular, no types were forgotten).
245255 */
246256 def allArgTypesAreCurrent ()(implicit ctx : Context ): Boolean = {
247- evalState foreachBinding { (arg, tstateConstr) =>
257+ state. evalState foreachBinding { (arg, tstateConstr) =>
248258 if ((tstateConstr._1.uncommittedAncestor.constraint `ne` ctx.typerState.constraint) ||
249259 tstateConstr._2.isRetracted) {
250- typr.println(i " need to invalidate $arg / ${myTypedArg (arg)}, ${tstateConstr._2}, current = ${ctx.typerState.constraint}" )
251- myTypedArg = myTypedArg .remove(arg)
252- evalState = evalState.remove(arg)
260+ typr.println(i " need to invalidate $arg / ${state.typedArg (arg)}, ${tstateConstr._2}, current = ${ctx.typerState.constraint}" )
261+ state.typedArg = state.typedArg .remove(arg)
262+ state. evalState = state. evalState.remove(arg)
253263 }
254264 }
255- myTypedArg .size == args.length
265+ state.typedArg .size == args.length
256266 }
257267
258268 private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean )(implicit ctx : Context ): Tree = {
259- var targ = myTypedArg (arg)
269+ var targ = state.typedArg (arg)
260270 if (targ == null ) {
261271 if (! force && untpd.functionWithUnknownParamType(arg).isDefined)
262272 // If force = false, assume ? rather than reporting an error.
@@ -270,8 +280,8 @@ object ProtoTypes {
270280 // typerstate if there are no errors. If we also omitted the next two lines
271281 // when warning were emitted, `pos/t1756.scala` would fail when run with -feature.
272282 // It would produce an orphan type parameter for CI when pickling.
273- myTypedArg = myTypedArg .updated(arg, targ)
274- evalState = evalState.updated(arg, (ctx.typerState, ctx.typerState.constraint))
283+ state.typedArg = state.typedArg .updated(arg, targ)
284+ state. evalState = state. evalState.updated(arg, (ctx.typerState, ctx.typerState.constraint))
275285 }
276286 }
277287 }
@@ -285,9 +295,9 @@ object ProtoTypes {
285295 * "missing parameter type" error
286296 */
287297 private def typedArgs (force : Boolean ): List [Tree ] = {
288- if (myTypedArgs .size != args.length)
289- myTypedArgs = args.mapconserve(cacheTypedArg(_, typer.typed(_), force))
290- myTypedArgs
298+ if (state.typedArgs .size != args.length)
299+ state.typedArgs = args.mapconserve(cacheTypedArg(_, typer.typed(_), force))
300+ state.typedArgs
291301 }
292302
293303 def typedArgs : List [Tree ] = typedArgs(force = true )
@@ -306,24 +316,19 @@ object ProtoTypes {
306316 * @pre `arg` has been typed before
307317 */
308318 def typeOfArg (arg : untpd.Tree )(implicit ctx : Context ): Type =
309- myTypedArg(arg).tpe
310-
311- private [this ] var myTupled : Type = NoType
319+ state.typedArg(arg).tpe
312320
313321 /** The same proto-type but with all arguments combined in a single tuple */
314- def tupled : FunProto = myTupled match {
322+ def tupled : FunProto = state.tupled match {
315323 case pt : FunProto =>
316324 pt
317325 case _ =>
318- myTupled = new FunProto (untpd.Tuple (args) :: Nil , resultType, typer)
326+ state.tupled = new FunProto (untpd.Tuple (args) :: Nil , resultType)( typer)
319327 tupled
320328 }
321329
322330 /** Somebody called the `tupled` method of this prototype */
323- def isTupled : Boolean = myTupled.isInstanceOf [FunProto ]
324-
325- /** If true, the application of this prototype was canceled. */
326- private [this ] var toDrop : Boolean = false
331+ def isTupled : Boolean = state.tupled.isInstanceOf [FunProto ]
327332
328333 /** Cancel the application of this prototype. This can happen for a nullary
329334 * application `f()` if `f` refers to a symbol that exists both in parameterless
@@ -333,10 +338,10 @@ object ProtoTypes {
333338 */
334339 def markAsDropped () = {
335340 assert(args.isEmpty)
336- toDrop = true
341+ state. toDrop = true
337342 }
338343
339- def isDropped : Boolean = toDrop
344+ def isDropped : Boolean = state. toDrop
340345
341346 override def toString = s " FunProto( ${args mkString " ," } => $resultType) "
342347
@@ -347,15 +352,19 @@ object ProtoTypes {
347352 ta(ta.foldOver(x, typedArgs.tpes), resultType)
348353
349354 override def deepenProto (implicit ctx : Context ) = derivedFunProto(args, resultType.deepenProto, typer)
350- }
351355
356+ override def withContext (newCtx : Context ) =
357+ if (newCtx `eq` ctx) this
358+ else new FunProto (args, resType)(typer, state)(newCtx)
359+ }
352360
353361 /** A prototype for expressions that appear in function position
354362 *
355363 * [](args): resultType, where args are known to be typed
356364 */
357- class FunProtoTyped (args : List [tpd.Tree ], resultType : Type , typer : Typer )(implicit ctx : Context ) extends FunProto (args, resultType, typer)(ctx) {
365+ class FunProtoTyped (args : List [tpd.Tree ], resultType : Type )( typer : Typer )(implicit ctx : Context ) extends FunProto (args, resultType)( typer)(ctx) {
358366 override def typedArgs = args
367+ override def withContext (ctx : Context ) = this
359368 }
360369
361370 /** A prototype for implicitly inferred views:
@@ -392,7 +401,7 @@ object ProtoTypes {
392401 }
393402
394403 class UnapplyFunProto (argType : Type , typer : Typer )(implicit ctx : Context ) extends FunProto (
395- untpd.TypedSplice (dummyTreeOfType(argType))(ctx) :: Nil , WildcardType , typer)
404+ untpd.TypedSplice (dummyTreeOfType(argType))(ctx) :: Nil , WildcardType )( typer)
396405
397406 /** A prototype for expressions [] that are type-parameterized:
398407 *
0 commit comments