Skip to content

Commit

Permalink
Handle context function arguments in overloading resolution
Browse files Browse the repository at this point in the history
Fixes #16506

We now handle the cases where an argument of an overloaded method is
a context closure. The closure must be given implicitly. It cannot be
inferred since at the time where the argument is typed, there is no expected
expected type to expand it to a context closure.
  • Loading branch information
odersky committed Dec 13, 2022
1 parent c3097af commit 069ac2c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,10 @@ object desugar {
val param = makeSyntheticParameter(
tpt =
if params.exists(_.tpt.isEmpty) then TypeTree()
else Tuple(params.map(_.tpt)))
else Tuple(params.map(_.tpt)),
flags =
if params.nonEmpty && params.head.mods.is(Given) then SyntheticTermParam | Given
else SyntheticTermParam)
def selector(n: Int) =
if (isGenericTuple) Apply(Select(refOfDef(param), nme.apply), Literal(Constant(n)))
else Select(refOfDef(param), nme.selectorName(n))
Expand Down
10 changes: 8 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,12 @@ trait Applications extends Compatibility {
/** The shape of given tree as a type; cannot handle named arguments. */
def typeShape(tree: untpd.Tree): Type = tree match {
case untpd.Function(args, body) =>
defn.FunctionOf(args map Function.const(defn.AnyType), typeShape(body))
defn.FunctionOf(
args map Function.const(defn.AnyType),
typeShape(body),
isContextual = args match
case (param: untpd.ValDef) :: _ => param.mods.is(Given)
case _ => false)
case Match(EmptyTree, _) =>
defn.PartialFunctionClass.typeRef.appliedTo(defn.AnyType :: defn.NothingType :: Nil)
case _ =>
Expand Down Expand Up @@ -2032,7 +2037,8 @@ trait Applications extends Compatibility {
if isDetermined(alts2) then alts2
else
record("resolveOverloaded.narrowedByShape", alts2.length)
pretypeArgs(alts2, pt)
if args.exists(untpd.isFunctionWithUnknownParamType) then
pretypeArgs(alts2, pt)
narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)

case pt @ PolyProto(targs1, pt1) =>
Expand Down
14 changes: 14 additions & 0 deletions tests/pos/i16506.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import scala.annotation.targetName

trait Ctx

def foo(f: Ctx => Int) = ???

@targetName("fooContextual")
def foo(f: Ctx ?=> Int) = ???

def bar1 = foo(ctx => 123)
def bar2 = foo((ctx: Ctx) => 123)
def bar3 = foo(ctx ?=> 123)
def bar4 = foo((ctx: Ctx) ?=> 123)
// def bar5 = foo(123) does not work

0 comments on commit 069ac2c

Please sign in to comment.