@@ -53,7 +53,6 @@ import config.MigrationVersion
53
53
import transform .CheckUnused .OriginalName
54
54
55
55
import scala .annotation .constructorOnly
56
- import dotty .tools .dotc .ast .desugar .PolyFunctionApply
57
56
58
57
object Typer {
59
58
@@ -1948,7 +1947,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1948
1947
untpd.InLambdaTypeTree (isResult = true , (tsyms, vsyms) =>
1949
1948
mt.resultType.substParams(mt, vsyms.map(_.termRef)).substParams(poly, tsyms.map(_.typeRef)))
1950
1949
val desugared @ Block (List (defdef), _) = desugar.makeClosure(tparams, inferredVParams, body, resultTpt, tree.span)
1951
- defdef.putAttachment(PolyFunctionApply , () )
1950
+ defdef.putAttachment(desugar. PolyFunctionApply , List .empty )
1952
1951
typed(desugared, pt)
1953
1952
else
1954
1953
val msg =
@@ -1957,7 +1956,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1957
1956
errorTree(EmptyTree , msg, tree.srcPos)
1958
1957
case _ =>
1959
1958
val desugared @ Block (List (defdef), _) = desugar.makeClosure(tparams, vparams, body, untpd.TypeTree (), tree.span)
1960
- defdef.putAttachment(PolyFunctionApply , () )
1959
+ defdef.putAttachment(desugar. PolyFunctionApply , List .empty )
1961
1960
typed(desugared, pt)
1962
1961
end typedPolyFunctionValue
1963
1962
@@ -3585,30 +3584,57 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3585
3584
case xtree => typedUnnamed(xtree)
3586
3585
3587
3586
val unsimplifiedType = result.tpe
3588
- simplify(result, pt, locked)
3589
- result .tpe.stripTypeVar match
3587
+ val result1 = simplify(result, pt, locked)
3588
+ result1 .tpe.stripTypeVar match
3590
3589
case e : ErrorType if ! unsimplifiedType.isErroneous => errorTree(xtree, e.msg, xtree.srcPos)
3591
- case _ => result
3590
+ case _ => result1
3592
3591
catch case ex : TypeError =>
3593
3592
handleTypeError(ex)
3594
3593
}
3595
3594
}
3596
3595
3596
+ private def pushDownDeferredEvidenceParams (tpe : Type , params : List [untpd.ValDef ], span : Span )(using Context ): Type = tpe.dealias match {
3597
+ case tpe : MethodType =>
3598
+ MethodType (tpe.paramNames)(paramNames => tpe.paramInfos, _ => pushDownDeferredEvidenceParams(tpe.resultType, params, span))
3599
+ case tpe : PolyType =>
3600
+ PolyType (tpe.paramNames)(paramNames => tpe.paramInfos, _ => pushDownDeferredEvidenceParams(tpe.resultType, params, span))
3601
+ case tpe : RefinedType =>
3602
+ // TODO(kπ): Doesn't seem right, but the PolyFunction ends up being a refinement
3603
+ RefinedType (pushDownDeferredEvidenceParams(tpe.parent, params, span), tpe.refinedName, pushDownDeferredEvidenceParams(tpe.refinedInfo, params, span))
3604
+ case tpe @ AppliedType (tycon, args) if defn.isFunctionType(tpe) && args.size > 1 =>
3605
+ AppliedType (tpe.tycon, args.init :+ pushDownDeferredEvidenceParams(args.last, params, span))
3606
+ case tpe =>
3607
+ val paramNames = params.map(_.name)
3608
+ val paramTpts = params.map(_.tpt)
3609
+ val paramsErased = params.map(_.mods.flags.is(Erased ))
3610
+ val ctxFunction = desugar.makeContextualFunction(paramTpts, paramNames, untpd.TypedSplice (TypeTree (tpe.dealias)), paramsErased).withSpan(span)
3611
+ typed(ctxFunction).tpe
3612
+ }
3613
+
3614
+ private def addDownDeferredEvidenceParams (tree : Tree , pt : Type )(using Context ): (Tree , Type ) = {
3615
+ tree.getAttachment(desugar.PolyFunctionApply ) match
3616
+ case Some (params) if params.nonEmpty =>
3617
+ tree.removeAttachment(desugar.PolyFunctionApply )
3618
+ val tpe = pushDownDeferredEvidenceParams(tree.tpe, params, tree.span)
3619
+ TypeTree (tpe).withSpan(tree.span) -> tpe
3620
+ case _ => tree -> pt
3621
+ }
3622
+
3597
3623
/** Interpolate and simplify the type of the given tree. */
3598
- protected def simplify (tree : Tree , pt : Type , locked : TypeVars )(using Context ): tree.type =
3599
- if ! tree.denot.isOverloaded then // for overloaded trees: resolve overloading before simplifying
3600
- if ! tree.tpe.widen.isInstanceOf [MethodOrPoly ] // wait with simplifying until method is fully applied
3601
- || tree.isDef // ... unless tree is a definition
3624
+ protected def simplify (tree : Tree , pt : Type , locked : TypeVars )(using Context ): Tree =
3625
+ val (tree1, pt1) = addDownDeferredEvidenceParams(tree, pt)
3626
+ if ! tree1.denot.isOverloaded then // for overloaded trees: resolve overloading before simplifying
3627
+ if ! tree1.tpe.widen.isInstanceOf [MethodOrPoly ] // wait with simplifying until method is fully applied
3628
+ || tree1.isDef // ... unless tree is a definition
3602
3629
then
3603
- interpolateTypeVars(tree, pt , locked)
3604
- val simplified = tree .tpe.simplified
3605
- if ! MatchType .thatReducesUsingGadt(tree .tpe) then // needs a GADT cast. i15743
3630
+ interpolateTypeVars(tree1, pt1 , locked)
3631
+ val simplified = tree1 .tpe.simplified
3632
+ if ! MatchType .thatReducesUsingGadt(tree1 .tpe) then // needs a GADT cast. i15743
3606
3633
tree.overwriteType(simplified)
3607
- tree
3634
+ tree1
3608
3635
3609
3636
protected def makeContextualFunction (tree : untpd.Tree , pt : Type )(using Context ): Tree = {
3610
3637
val defn .FunctionOf (formals, _, true ) = pt.dropDependentRefinement: @ unchecked
3611
- println(i " make contextual function $tree / $pt" )
3612
3638
val paramNamesOrNil = pt match
3613
3639
case RefinedType (_, _, rinfo : MethodType ) => rinfo.paramNames
3614
3640
case _ => Nil
0 commit comments