Skip to content

Commit ebe1ceb

Browse files
committed
Bring back the restriction for requiring value parameters in poly function type definitions
1 parent c71c71c commit ebe1ceb

File tree

3 files changed

+13
-38
lines changed

3 files changed

+13
-38
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

-2
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ object desugar {
514514
case Nil =>
515515
params :: Nil
516516

517-
// TODO(kπ) is this enough? SHould this be a TreeTraverse-thing?
518517
def pushDownEvidenceParams(tree: Tree): Tree = tree match
519518
case Function(params, body) =>
520519
cpy.Function(tree)(params, pushDownEvidenceParams(body))
@@ -527,7 +526,6 @@ object desugar {
527526
makeContextualFunction(paramTpts, paramNames, tree, paramsErased).withSpan(tree.span)
528527

529528
if meth.hasAttachment(PolyFunctionApply) then
530-
// meth.removeAttachment(PolyFunctionApply)
531529
if ctx.mode.is(Mode.Type) then
532530
cpy.DefDef(meth)(tpt = meth.tpt.withAttachment(PolyFunctionApply, params))
533531
else

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

-2
Original file line numberDiff line numberDiff line change
@@ -1761,8 +1761,6 @@ object Parsers {
17611761
getFunction(body) match
17621762
case Some(f) =>
17631763
PolyFunction(tparams, body)
1764-
case None if tparams.exists(_.rhs.isInstanceOf[ContextBounds]) =>
1765-
PolyFunction(tparams, body)
17661764
case None =>
17671765
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
17681766
Ident(nme.ERROR.toTypeName)

compiler/src/dotty/tools/dotc/typer/Typer.scala

+13-34
Original file line numberDiff line numberDiff line change
@@ -3588,6 +3588,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
35883588
}
35893589
}
35903590

3591+
/** Push down the deferred evidence parameters up until the result type is not
3592+
* a method type, poly type or a function type
3593+
*/
35913594
private def pushDownDeferredEvidenceParams(tpe: Type, params: List[untpd.ValDef], span: Span)(using Context): Type = tpe.dealias match {
35923595
case tpe: MethodType =>
35933596
tpe.derivedLambdaType(tpe.paramNames, tpe.paramInfos, pushDownDeferredEvidenceParams(tpe.resultType, params, span))
@@ -3609,46 +3612,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36093612
typed(ctxFunction).tpe
36103613
}
36113614

3612-
private def extractTopMethodTermParams(tpe: Type)(using Context): (List[TermName], List[Type]) = tpe match {
3613-
case tpe: MethodType =>
3614-
tpe.paramNames -> tpe.paramInfos
3615-
case tpe: RefinedType if defn.isFunctionType(tpe.parent) =>
3616-
extractTopMethodTermParams(tpe.refinedInfo)
3617-
case _ =>
3618-
Nil -> Nil
3619-
}
3620-
3621-
private def removeTopMethodTermParams(tpe: Type)(using Context): Type = tpe match {
3622-
case tpe: MethodType =>
3623-
tpe.resultType
3624-
case tpe: RefinedType if defn.isFunctionType(tpe.parent) =>
3625-
tpe.derivedRefinedType(tpe.parent, tpe.refinedName, removeTopMethodTermParams(tpe.refinedInfo))
3626-
case tpe: AppliedType if defn.isFunctionType(tpe) =>
3627-
tpe.args.last
3628-
case _ =>
3629-
tpe
3630-
}
3631-
3632-
private def healToPolyFunctionType(tree: Tree)(using Context): Tree = tree match {
3633-
case defdef: DefDef if defdef.name == nme.apply && defdef.paramss.forall(_.forall(_.symbol.flags.is(TypeParam))) && defdef.paramss.size == 1 =>
3634-
val (names, types) = extractTopMethodTermParams(defdef.tpt.tpe)
3635-
val newTpe = removeTopMethodTermParams(defdef.tpt.tpe)
3636-
val newParams = names.lazyZip(types).map((name, tpe) => SyntheticValDef(name, TypeTree(tpe), flags = SyntheticTermParam))
3637-
val newDefDef = cpy.DefDef(defdef)(paramss = defdef.paramss ++ List(newParams), tpt = untpd.TypeTree(newTpe))
3638-
val nestedCtx = ctx.fresh.setNewTyperState()
3639-
typed(newDefDef)(using nestedCtx)
3640-
case _ => tree
3641-
}
3642-
3615+
/** If the tree has a `PolyFunctionApply` attachment, add the deferred
3616+
* evidence parameters as the last argument list before the result type. This
3617+
* follows aliases, so the following two types will be expanded to (up to the
3618+
* context bound encoding):
3619+
* type CmpWeak[X] = X => Boolean
3620+
* type Comparer2Weak = [X: Ord] => X => CmpWeak[X]
3621+
* ===>
3622+
* type CmpWeak[X] = X => Boolean type Comparer2Weak = [X] => X => X ?=>
3623+
* Ord[X] => Boolean
3624+
*/
36433625
private def addDeferredEvidenceParams(tree: Tree, pt: Type)(using Context): (Tree, Type) = {
36443626
tree.getAttachment(desugar.PolyFunctionApply) match
36453627
case Some(params) if params.nonEmpty =>
36463628
tree.removeAttachment(desugar.PolyFunctionApply)
36473629
val tpe = pushDownDeferredEvidenceParams(tree.tpe, params, tree.span)
36483630
TypeTree(tpe).withSpan(tree.span) -> tpe
3649-
// case Some(params) if params.isEmpty =>
3650-
// println(s"tree: $tree")
3651-
// healToPolyFunctionType(tree) -> pt
36523631
case _ => tree -> pt
36533632
}
36543633

0 commit comments

Comments
 (0)