@@ -321,21 +321,30 @@ trait TypeAssigner {
321
321
case pt : PolyType =>
322
322
val paramNames = pt.paramNames
323
323
if (hasNamedArg(args)) {
324
- val argMap = new mutable.HashMap [Name , Type ]
324
+ // Type arguments which are specified by name (immutable after this first loop)
325
+ val namedArgMap = new mutable.HashMap [Name , Type ]
325
326
for (NamedArg (name, arg) <- args)
326
- if (argMap .contains(name))
327
+ if (namedArgMap .contains(name))
327
328
ctx.error(" duplicate name" , arg.pos)
328
329
else if (! paramNames.contains(name))
329
330
ctx.error(s " undefined parameter name, required: ${paramNames.mkString(" or " )}" , arg.pos)
330
331
else
331
- argMap(name) = arg.tpe
332
+ namedArgMap(name) = arg.tpe
333
+
334
+ // Holds indexes of non-named typed arguments in paramNames
332
335
val gapBuf = new mutable.ListBuffer [Int ]
333
- def nextPoly = {
334
- val idx = gapBuf.length
336
+ def nextPoly ( idx : Int ) = {
337
+ val newIndex = gapBuf.length
335
338
gapBuf += idx
336
- PolyParam (pt, idx)
339
+ // Re-index unassigned type arguments that remain after transformation
340
+ PolyParam (pt, newIndex)
341
+ }
342
+
343
+ // Type parameters after naming assignment, conserving paramNames order
344
+ val normArgs : List [Type ] = paramNames.zipWithIndex.map { case (pname, idx) =>
345
+ namedArgMap.getOrElse(pname, nextPoly(idx))
337
346
}
338
- val normArgs = paramNames.map(pname => argMap.getOrElse(pname, nextPoly))
347
+
339
348
val transform = new TypeMap {
340
349
def apply (t : Type ) = t match {
341
350
case PolyParam (`pt`, idx) => normArgs(idx)
@@ -347,19 +356,20 @@ trait TypeAssigner {
347
356
else {
348
357
val gaps = gapBuf.toList
349
358
pt.derivedPolyType(
350
- gaps.map(paramNames.filterNot(argMap.contains) ),
359
+ gaps.map(paramNames),
351
360
gaps.map(idx => transform(pt.paramBounds(idx)).bounds),
352
361
resultType1)
353
362
}
354
363
}
355
364
else {
356
365
val argTypes = args.tpes
357
- if (sameLength(argTypes, paramNames)|| ctx.phase.prev.relaxedTyping) pt.instantiate(argTypes)
366
+ if (sameLength(argTypes, paramNames) || ctx.phase.prev.relaxedTyping) pt.instantiate(argTypes)
358
367
else wrongNumberOfArgs(fn.tpe, " type " , pt.paramNames.length, tree.pos)
359
368
}
360
369
case _ =>
361
370
errorType(i " ${err.exprStr(fn)} does not take type parameters " , tree.pos)
362
371
}
372
+
363
373
tree.withType(ownType)
364
374
}
365
375
@@ -383,8 +393,8 @@ trait TypeAssigner {
383
393
384
394
def assignType (tree : untpd.Closure , meth : Tree , target : Tree )(implicit ctx : Context ) =
385
395
tree.withType(
386
- if (target.isEmpty) meth.tpe.widen.toFunctionType(tree.env.length)
387
- else target.tpe)
396
+ if (target.isEmpty) meth.tpe.widen.toFunctionType(tree.env.length)
397
+ else target.tpe)
388
398
389
399
def assignType (tree : untpd.CaseDef , body : Tree )(implicit ctx : Context ) =
390
400
tree.withType(body.tpe)
0 commit comments