@@ -1857,19 +1857,24 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
18571857 case Typed (arg1, _) if untpd.isWildcardStarArg(arg) => refersTo(arg1, param)
18581858 case _ => false
18591859
1860+ def containsParamRef (tree : untpd.Tree , params : List [untpd.ValDef ]): Boolean =
1861+ import dotty .tools .dotc .ast .untpd .existsSubTree
1862+ tree.existsSubTree {
1863+ case Ident (name) => params.exists(_.name == name)
1864+ case _ => false
1865+ }
1866+
18601867 /** If parameter `param` appears exactly once as an argument in `args`,
18611868 * the singleton list consisting of its position in `args`, otherwise `Nil`.
18621869 */
1863- def paramIndices (param : untpd.ValDef , args : List [untpd.Tree ]): List [Int ] = {
1864- def loop (args : List [untpd.Tree ], start : Int ): List [Int ] = args match {
1870+ def paramIndices (param : untpd.ValDef , args : List [untpd.Tree ]): List [Int ] =
1871+ def loop (args : List [untpd.Tree ], start : Int ): List [Int ] = args match
18651872 case arg :: args1 =>
18661873 val others = loop(args1, start + 1 )
18671874 if (refersTo(arg, param)) start :: others else others
18681875 case _ => Nil
1869- }
18701876 val allIndices = loop(args, 0 )
1871- if (allIndices.length == 1 ) allIndices else Nil
1872- }
1877+ if allIndices.length == 1 then allIndices else Nil
18731878
18741879 /** A map from parameter names to unique positions where the parameter
18751880 * appears in the argument list of an application.
@@ -1905,25 +1910,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19051910 fnBody = untpd.TypedSplice (ident1)
19061911 tp.select(nme.apply)
19071912 else NoType
1908- case app @ Apply (expr, args) =>
1913+ case app @ Apply (expr, args) if ! containsParamRef(expr, params) =>
19091914 paramIndex = {
19101915 for (param <- params; idx <- paramIndices(param, args))
19111916 yield param.name -> idx
19121917 }.toMap
1918+ // println(i"paramIndex = $paramIndex, paramIndex.size = ${paramIndex.size}, params.length = ${params.length}")
19131919 if (paramIndex.size == params.length)
19141920 expr match
19151921 case untpd.TypedSplice (expr1) =>
19161922 expr1.tpe
19171923 case _ =>
19181924 val outerCtx = ctx
1919- // Create placeholder symbols for function parameters to shadow outer bindings.
1920- // This ensures that when typing `expr`, references in it won't incorrectly
1921- // resolve to outer scope variables with the same names as the parameters.
1922- val paramSyms = params.map(p =>
1923- newSymbol(ctx.owner, p.name, Flags .Param , WildcardType , coord = p.span))
1924- val nestedCtx = outerCtx.fresh.setNewTyperState().setScope(newScopeWith(paramSyms* ))
1925+ val nestedCtx = outerCtx.fresh.setNewTyperState()
19251926 inContext(nestedCtx) {
1926- val protoArgs = args.map(_.withType(WildcardType ))
1927+ // create a placeholder tree for each prototype argument
1928+ val protoArgs = args.map(arg => untpd.TypedSplice (TypeTree (WildcardType ).withSpan(arg.span)))
19271929 val callProto = FunProto (protoArgs, WildcardType )(this , app.applyKind)
19281930 val expr1 = typedExpr(expr, callProto)
19291931 if nestedCtx.reporter.hasErrors then NoType
0 commit comments