@@ -210,28 +210,38 @@ object ProtoTypes {
210
210
211
211
trait ApplyingProto extends ProtoType
212
212
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
+
213
231
/** A prototype for expressions that appear in function position
214
232
*
215
233
* [](args): resultType
216
234
*/
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 )
218
236
extends UncachedGroundType with ApplyingProto {
219
- private var myTypedArgs : List [Tree ] = Nil
220
-
221
237
override def resultType (implicit ctx : Context ) = resType
222
238
223
- /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */
224
- private 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 var evalState : SimpleIdentityMap [untpd.Tree , (TyperState , Constraint )] = SimpleIdentityMap .Empty
228
-
229
239
def isMatchedBy (tp : Type )(implicit ctx : Context ) =
230
240
typer.isApplicable(tp, Nil , unforcedTypedArgs, resultType)
231
241
232
242
def derivedFunProto (args : List [untpd.Tree ] = this .args, resultType : Type , typer : Typer = this .typer) =
233
243
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)
235
245
236
246
override def notApplied = WildcardType
237
247
@@ -244,19 +254,19 @@ object ProtoTypes {
244
254
* @return True if all arguments have types (in particular, no types were forgotten).
245
255
*/
246
256
def allArgTypesAreCurrent ()(implicit ctx : Context ): Boolean = {
247
- evalState foreachBinding { (arg, tstateConstr) =>
257
+ state. evalState foreachBinding { (arg, tstateConstr) =>
248
258
if ((tstateConstr._1.uncommittedAncestor.constraint `ne` ctx.typerState.constraint) ||
249
259
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)
253
263
}
254
264
}
255
- myTypedArg .size == args.length
265
+ state.typedArg .size == args.length
256
266
}
257
267
258
268
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)
260
270
if (targ == null ) {
261
271
if (! force && untpd.functionWithUnknownParamType(arg).isDefined)
262
272
// If force = false, assume ? rather than reporting an error.
@@ -270,8 +280,8 @@ object ProtoTypes {
270
280
// typerstate if there are no errors. If we also omitted the next two lines
271
281
// when warning were emitted, `pos/t1756.scala` would fail when run with -feature.
272
282
// 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))
275
285
}
276
286
}
277
287
}
@@ -285,9 +295,9 @@ object ProtoTypes {
285
295
* "missing parameter type" error
286
296
*/
287
297
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
291
301
}
292
302
293
303
def typedArgs : List [Tree ] = typedArgs(force = true )
@@ -306,24 +316,19 @@ object ProtoTypes {
306
316
* @pre `arg` has been typed before
307
317
*/
308
318
def typeOfArg (arg : untpd.Tree )(implicit ctx : Context ): Type =
309
- myTypedArg(arg).tpe
310
-
311
- private var myTupled : Type = NoType
319
+ state.typedArg(arg).tpe
312
320
313
321
/** 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 {
315
323
case pt : FunProto =>
316
324
pt
317
325
case _ =>
318
- myTupled = new FunProto (untpd.Tuple (args) :: Nil , resultType, typer)
326
+ state.tupled = new FunProto (untpd.Tuple (args) :: Nil , resultType)( typer)
319
327
tupled
320
328
}
321
329
322
330
/** 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 var toDrop : Boolean = false
331
+ def isTupled : Boolean = state.tupled.isInstanceOf [FunProto ]
327
332
328
333
/** Cancel the application of this prototype. This can happen for a nullary
329
334
* application `f()` if `f` refers to a symbol that exists both in parameterless
@@ -333,10 +338,10 @@ object ProtoTypes {
333
338
*/
334
339
def markAsDropped () = {
335
340
assert(args.isEmpty)
336
- toDrop = true
341
+ state. toDrop = true
337
342
}
338
343
339
- def isDropped : Boolean = toDrop
344
+ def isDropped : Boolean = state. toDrop
340
345
341
346
override def toString = s " FunProto( ${args mkString " ," } => $resultType) "
342
347
@@ -350,23 +355,15 @@ object ProtoTypes {
350
355
351
356
override def withContext (newCtx : Context ) =
352
357
if (newCtx `eq` ctx) this
353
- else {
354
- val result = new FunProto (args, resType, typer)(newCtx)
355
- result.myTypedArgs = myTypedArgs
356
- result.myTypedArg = myTypedArg
357
- result.evalState = evalState
358
- result.myTupled = myTupled
359
- result.toDrop = toDrop
360
- result
361
- }
358
+ else new FunProto (args, resType)(typer, state)(newCtx)
362
359
}
363
360
364
361
365
362
/** A prototype for expressions that appear in function position
366
363
*
367
364
* [](args): resultType, where args are known to be typed
368
365
*/
369
- class FunProtoTyped (args : List [tpd.Tree ], resultType : Type , typer : Typer )(implicit ctx : Context ) extends FunProto (args, resultType, typer)(ctx) {
366
+ class FunProtoTyped (args : List [tpd.Tree ], resultType : Type )( typer : Typer )(implicit ctx : Context ) extends FunProto (args, resultType)( typer)(ctx) {
370
367
override def typedArgs = args
371
368
override def withContext (ctx : Context ) = this
372
369
}
@@ -405,7 +402,7 @@ object ProtoTypes {
405
402
}
406
403
407
404
class UnapplyFunProto (argType : Type , typer : Typer )(implicit ctx : Context ) extends FunProto (
408
- untpd.TypedSplice (dummyTreeOfType(argType))(ctx) :: Nil , WildcardType , typer)
405
+ untpd.TypedSplice (dummyTreeOfType(argType))(ctx) :: Nil , WildcardType )( typer)
409
406
410
407
/** A prototype for expressions [] that are type-parameterized:
411
408
*
0 commit comments