diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index ec23b8fe77dc..f17889b9bbfd 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1897,13 +1897,19 @@ trait Applications extends Compatibility { } /** The type of alternative `alt` after instantiating its first parameter - * clause with `argTypes`. + * clause with `argTypes`. In addition, if the resulting type is a PolyType + * and `typeArgs` matches its parameter list, instantiate the result with `typeArgs`. */ - def skipParamClause(argTypes: List[Type])(alt: TermRef): Type = + def skipParamClause(argTypes: List[Type], typeArgs: List[Type])(alt: TermRef): Type = def skip(tp: Type): Type = tp match { case tp: PolyType => - val rt = skip(tp.resultType) - if (rt.exists) tp.derivedLambdaType(resType = rt) else rt + skip(tp.resultType) match + case NoType => + NoType + case rt: PolyType if typeArgs.length == rt.paramInfos.length => + tp.derivedLambdaType(resType = rt.instantiate(typeArgs)) + case rt => + tp.derivedLambdaType(resType = rt).asInstanceOf[PolyType].flatten case tp: MethodType => tp.instantiate(argTypes) case _ => @@ -1926,9 +1932,14 @@ trait Applications extends Compatibility { else val deepPt = pt.deepenProto deepPt match + case pt @ FunProto(_, PolyProto(targs, resType)) => + // try to narrow further with snd argument list and following type params + resolveMapped(candidates, + skipParamClause(pt.typedArgs().tpes, targs.tpes), resType) case pt @ FunProto(_, resType: FunOrPolyProto) => // try to narrow further with snd argument list - resolveMapped(candidates, skipParamClause(pt.typedArgs().tpes), resType) + resolveMapped(candidates, + skipParamClause(pt.typedArgs().tpes, Nil), resType) case _ => // prefer alternatives that need no eta expansion val noCurried = alts.filter(!resultIsMethod(_)) @@ -1974,7 +1985,7 @@ trait Applications extends Compatibility { None } val mapped = reverseMapping.map(_._1) - overload.println(i"resolve mapped: $mapped") + overload.println(i"resolve mapped: ${mapped.map(_.widen)}%, % with $pt") resolveOverloaded(mapped, pt).map(reverseMapping.toMap) /** Try to typecheck any arguments in `pt` that are function values missing a diff --git a/tests/pos/i11358.scala b/tests/pos/i11358.scala new file mode 100644 index 000000000000..aa246a45fba4 --- /dev/null +++ b/tests/pos/i11358.scala @@ -0,0 +1,14 @@ +object Test: + + def test1: IArray[Int] = IArray(1, 2) +++ IArray(2, 3) + def test2: IArray[Int] = IArray(1, 2) +++ List(2, 3) + def test3 = +++[Int](IArray(1, 2))(IArray(2, 3)) + def test4 = +++[Int](IArray(1, 2))(List(2, 3)) + def test5: IArray[Int] = IArray(1, 2).+++[Int](IArray(2, 3)) + def test6: IArray[Int] = IArray(1, 2).+++[Int](List(2, 3)) + def test7 = +++(IArray(1, 2))[Int](IArray(2, 3)) + def test8 = +++(IArray(1, 2))[Int](List(2, 3)) + + extension [A: reflect.ClassTag](arr: IArray[A]) + def +++[B >: A: reflect.ClassTag](suffix: IArray[B]): IArray[B] = ??? + def +++[B >: A: reflect.ClassTag](suffix: IterableOnce[B]): IArray[B] = ???