Skip to content

Commit

Permalink
Handle context function arguments in overloading resolution (#16511)
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 authored Dec 15, 2022
2 parents 4d44638 + e84c6ee commit ca5a264
Show file tree
Hide file tree
Showing 3 changed files with 22 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
6 changes: 4 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,9 @@ 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 = untpd.isContextualClosure(tree))
case Match(EmptyTree, _) =>
defn.PartialFunctionClass.typeRef.appliedTo(defn.AnyType :: defn.NothingType :: Nil)
case _ =>
Expand Down Expand Up @@ -2232,7 +2234,7 @@ trait Applications extends Compatibility {
false
val commonFormal =
if (isPartial) defn.PartialFunctionOf(commonParamTypes.head, WildcardType)
else defn.FunctionOf(commonParamTypes, WildcardType)
else defn.FunctionOf(commonParamTypes, WildcardType, isContextual = untpd.isContextualClosure(arg))
overload.println(i"pretype arg $arg with expected type $commonFormal")
if (commonParamTypes.forall(isFullyDefined(_, ForceDegree.flipBottom)))
withMode(Mode.ImplicitsEnabled) {
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 ca5a264

Please sign in to comment.