@@ -381,65 +381,74 @@ trait TypeAssigner {
381
381
}
382
382
383
383
def assignType (tree : untpd.TypeApply , fn : Tree , args : List [Tree ])(implicit ctx : Context ): TypeApply = {
384
- val ownType = fn.tpe.widen match {
384
+ def fail = tree.withType(errorType(err.takesNoParamsStr(fn, " type " ), tree.pos))
385
+ fn.tpe.widen match {
385
386
case pt : TypeLambda =>
386
- val paramNames = pt.paramNames
387
- if (hasNamedArg(args)) {
388
- val paramBoundsByName = paramNames.zip(pt.paramInfos).toMap
389
-
390
- // Type arguments which are specified by name (immutable after this first loop)
391
- val namedArgMap = new mutable.HashMap [Name , Type ]
392
- for (NamedArg (name, arg) <- args)
393
- if (namedArgMap.contains(name))
394
- ctx.error(DuplicateNamedTypeParameter (name), arg.pos)
395
- else if (! paramNames.contains(name))
396
- ctx.error(UndefinedNamedTypeParameter (name, paramNames), arg.pos)
397
- else
398
- namedArgMap(name) = arg.tpe
399
-
400
- // Holds indexes of non-named typed arguments in paramNames
401
- val gapBuf = new mutable.ListBuffer [Int ]
402
- def nextPoly (idx : Int ) = {
403
- val newIndex = gapBuf.length
404
- gapBuf += idx
405
- // Re-index unassigned type arguments that remain after transformation
406
- pt.paramRefs(newIndex)
407
- }
387
+ tree.withType {
388
+ val paramNames = pt.paramNames
389
+ if (hasNamedArg(args)) {
390
+ val paramBoundsByName = paramNames.zip(pt.paramInfos).toMap
391
+
392
+ // Type arguments which are specified by name (immutable after this first loop)
393
+ val namedArgMap = new mutable.HashMap [Name , Type ]
394
+ for (NamedArg (name, arg) <- args)
395
+ if (namedArgMap.contains(name))
396
+ ctx.error(DuplicateNamedTypeParameter (name), arg.pos)
397
+ else if (! paramNames.contains(name))
398
+ ctx.error(UndefinedNamedTypeParameter (name, paramNames), arg.pos)
399
+ else
400
+ namedArgMap(name) = arg.tpe
401
+
402
+ // Holds indexes of non-named typed arguments in paramNames
403
+ val gapBuf = new mutable.ListBuffer [Int ]
404
+ def nextPoly (idx : Int ) = {
405
+ val newIndex = gapBuf.length
406
+ gapBuf += idx
407
+ // Re-index unassigned type arguments that remain after transformation
408
+ pt.paramRefs(newIndex)
409
+ }
408
410
409
- // Type parameters after naming assignment, conserving paramNames order
410
- val normArgs : List [Type ] = paramNames.zipWithIndex.map { case (pname, idx) =>
411
- namedArgMap.getOrElse(pname, nextPoly(idx))
412
- }
411
+ // Type parameters after naming assignment, conserving paramNames order
412
+ val normArgs : List [Type ] = paramNames.zipWithIndex.map { case (pname, idx) =>
413
+ namedArgMap.getOrElse(pname, nextPoly(idx))
414
+ }
413
415
414
- val transform = new TypeMap {
415
- def apply (t : Type ) = t match {
416
- case TypeParamRef (`pt`, idx) => normArgs(idx)
417
- case _ => mapOver(t)
416
+ val transform = new TypeMap {
417
+ def apply (t : Type ) = t match {
418
+ case TypeParamRef (`pt`, idx) => normArgs(idx)
419
+ case _ => mapOver(t)
420
+ }
421
+ }
422
+ val resultType1 = transform(pt.resultType)
423
+ if (gapBuf.isEmpty) resultType1
424
+ else {
425
+ val gaps = gapBuf.toList
426
+ pt.derivedLambdaType(
427
+ gaps.map(paramNames),
428
+ gaps.map(idx => transform(pt.paramInfos(idx)).bounds),
429
+ resultType1)
418
430
}
419
431
}
420
- val resultType1 = transform(pt.resultType)
421
- if (gapBuf.isEmpty) resultType1
422
432
else {
423
- val gaps = gapBuf.toList
424
- pt.derivedLambdaType(
425
- gaps.map(paramNames),
426
- gaps.map(idx => transform(pt.paramInfos(idx)).bounds),
427
- resultType1)
433
+ val argTypes = args.tpes
434
+ if (sameLength(argTypes, paramNames)) pt.instantiate(argTypes)
435
+ else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.pos)
428
436
}
429
437
}
430
- else {
431
- val argTypes = args.tpes
432
- if (sameLength(argTypes, paramNames)) pt.instantiate(argTypes)
433
- else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.pos)
434
- }
435
438
case err : ErrorType =>
436
- err
439
+ tree.withType(err)
440
+ case ref : TermRef if ref.isOverloaded =>
441
+ val disambiguated = ref.denot.suchThat(_.info.isInstanceOf [PolyType ])
442
+ if (disambiguated.exists) {
443
+ val fn1 = fn.withType(ref.withDenot(disambiguated))
444
+ val tree1 = untpd.cpy.TypeApply (tree)(fn1, args)
445
+ assignType(tree1, fn1, args)
446
+ }
447
+ else fail
437
448
case _ =>
438
449
// println(i"bad type: $fn: ${fn.symbol} / ${fn.symbol.isType} / ${fn.symbol.info}") // DEBUG
439
- errorType(err.takesNoParamsStr(fn, " type " ), tree.pos)
450
+ fail
440
451
}
441
-
442
- tree.withType(ownType)
443
452
}
444
453
445
454
def assignType (tree : untpd.Typed , tpt : Tree )(implicit ctx : Context ): Typed =
0 commit comments