Skip to content

Commit 44f56f7

Browse files
committed
Fix scala#7778: infer parameter type for contextual functions
Given a contextual function of the form (using x1, ..., xN) => f If `f` is a contextual function type of the form `(T1, ..., TN) ?=> T`, then give the type `T1` to `x1` and so on.
1 parent af37d64 commit 44f56f7

File tree

4 files changed

+18
-6
lines changed

4 files changed

+18
-6
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,9 +1336,9 @@ object desugar {
13361336
Function(param :: Nil, Block(vdefs, body))
13371337
}
13381338

1339-
def makeContextualFunction(formals: List[Type], body: Tree, isErased: Boolean)(implicit ctx: Context): Tree = {
1339+
def makeContextualFunction(formals: List[TypeTree], body: Tree, isErased: Boolean)(implicit ctx: Context): Function = {
13401340
val mods = if (isErased) Given | Erased else Given
1341-
val params = makeImplicitParameters(formals.map(TypeTree), mods)
1341+
val params = makeImplicitParameters(formals, mods)
13421342
FunctionWithMods(params, body, Modifiers(mods))
13431343
}
13441344

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
9898
case _ => tree
9999
}
100100

101+
def stripAnnotated(tree: Tree): Tree = tree match {
102+
case Annotated(arg, _) => arg
103+
case _ => tree
104+
}
105+
101106
/** The number of arguments in an application */
102107
def numArgs(tree: Tree): Int = unsplice(tree) match {
103108
case Apply(fn, args) => numArgs(fn) + args.length

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ object ProtoTypes {
598598
*/
599599
private def wildApprox(tp: Type, theMap: WildApproxMap, seen: Set[TypeParamRef], internal: Set[TypeLambda])(using Context): Type = tp match {
600600
case tp: NamedType => // default case, inlined for speed
601-
val isPatternBoundTypeRef = tp.isInstanceOf[TypeRef] && tp.symbol.is(Flags.Case) && !tp.symbol.isClass
601+
val isPatternBoundTypeRef = tp.isInstanceOf[TypeRef] && tp.symbol.isPatternBound
602602
if (isPatternBoundTypeRef) WildcardType(tp.underlying.bounds)
603603
else if (tp.symbol.isStatic || (tp.prefix `eq` NoPrefix)) tp
604604
else tp.derivedSelect(wildApprox(tp.prefix, theMap, seen, internal))

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,14 @@ class Typer extends Namer
10571057
* @post: If result exists, `paramIndex` is defined for the name of
10581058
* every parameter in `params`.
10591059
*/
1060-
lazy val calleeType: Type = fnBody match {
1060+
lazy val calleeType: Type = untpd.stripAnnotated(fnBody) match {
1061+
case ident: Ident if isContextual =>
1062+
val tp = typedIdent(ident, WildcardType).tpe.widen
1063+
if defn.isContextFunctionType(tp) && params.size == defn.functionArity(tp)
1064+
then
1065+
paramIndex = params.map(_.name).zipWithIndex.toMap
1066+
tp.select(nme.apply)
1067+
else NoType
10611068
case app @ Apply(expr, args) =>
10621069
paramIndex = {
10631070
for (param <- params; idx <- paramIndices(param, args))
@@ -2450,9 +2457,9 @@ class Typer extends Namer
24502457

24512458
protected def makeContextualFunction(tree: untpd.Tree, pt: Type)(using Context): Tree = {
24522459
val defn.FunctionOf(formals, _, true, _) = pt.dropDependentRefinement
2453-
val ifun = desugar.makeContextualFunction(formals, tree, defn.isErasedFunctionType(pt))
2460+
val ifun = desugar.makeContextualFunction(formals.map(_ => untpd.TypeTree()), tree, defn.isErasedFunctionType(pt))
24542461
typr.println(i"make contextual function $tree / $pt ---> $ifun")
2455-
typed(ifun, pt)
2462+
typedFunctionValue(ifun, pt)
24562463
}
24572464

24582465
/** Typecheck and adapt tree, returning a typed tree. Parameters as for `typedUnadapted` */

0 commit comments

Comments
 (0)