@@ -2879,8 +2879,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
28792879 silent(_.typed(fn, mode.forFunMode, pt)) filter (_ => context.undetparams.isEmpty) map { fn1 =>
28802880 // if context.undetparams is not empty, the function was polymorphic,
28812881 // so we need the missing arguments to infer its type. See #871
2882- // println("typing eta "+fun+":"+fn1.tpe+"/"+context.undetparams)
28832882 val ftpe = normalize(fn1.tpe) baseType FunctionClass (numVparams)
2883+ // println(s"typeUnEtaExpanded $fn : ${fn1.tpe} (unwrapped $fun) --> normalized: $ftpe")
2884+
28842885 if (isFunctionType(ftpe) && isFullyDefined(ftpe)) ftpe
28852886 else NoType
28862887 } orElse { _ => NoType }
@@ -4365,28 +4366,35 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
43654366 case _ => tp
43664367 }
43674368
4368- def expectingFunctionMatchingFormals (formals : List [Symbol ]) =
4369- isFunctionType(pt) || samMatchesFunctionBasedOnArity(samOf(pt), formals)
4370-
4371- def typedEta (expr1 : Tree ): Tree = expr1.tpe match {
4372- case TypeRef (_, ByNameParamClass , _) =>
4373- val expr2 = Function (List (), expr1) setPos expr1.pos
4374- new ChangeOwnerTraverser (context.owner, expr2.symbol).traverse(expr2)
4375- typed1(expr2, mode, pt)
4376- case NullaryMethodType (restpe) =>
4377- val expr2 = Function (List (), expr1) setPos expr1.pos
4378- new ChangeOwnerTraverser (context.owner, expr2.symbol).traverse(expr2)
4379- typed1(expr2, mode, pt)
4380- case PolyType (_, MethodType (formals, _)) =>
4381- if (expectingFunctionMatchingFormals(formals)) expr1
4382- else adapt(expr1, mode, checkArity(expr1)(functionTypeWildcard(formals.length)))
4383- case MethodType (formals, _) =>
4384- if (expectingFunctionMatchingFormals(formals)) expr1
4385- else adapt(expr1, mode, checkArity(expr1)(functionTypeWildcard(formals.length)))
4369+
4370+ /** Eta expand an expression like `m _`, where `m` denotes a method or a by-name argument
4371+ *
4372+ * The spec says:
4373+ * The expression `$e$ _` is well-formed if $e$ is of method type or if $e$ is a call-by-name parameter.
4374+ * (1) If $e$ is a method with parameters, `$e$ _` represents $e$ converted to a function type
4375+ * by [eta expansion](#eta-expansion).
4376+ * (2) If $e$ is a parameterless method or call-by-name parameter of type `=>$T$`, `$e$ _` represents
4377+ * the function of type `() => $T$`, which evaluates $e$ when it is applied to the empty parameterlist `()`.
4378+ */
4379+ def typedEta (methodValue : Tree ): Tree = methodValue.tpe match {
4380+ case tp@ (MethodType (_, _) | PolyType (_, MethodType (_, _))) => // (1)
4381+ val formals = tp.params
4382+ if (isFunctionType(pt) || samMatchesFunctionBasedOnArity(samOf(pt), formals)) methodValue
4383+ else adapt(methodValue, mode, checkArity(methodValue)(functionTypeWildcard(formals.length)))
4384+
4385+ case TypeRef (_, ByNameParamClass , _) | NullaryMethodType (_) => // (2)
4386+ val pos = methodValue.pos
4387+ // must create it here to change owner (normally done by typed's typedFunction)
4388+ val funSym = context.owner.newAnonymousFunctionValue(pos)
4389+ new ChangeOwnerTraverser (context.owner, funSym) traverse methodValue
4390+
4391+ typed(Function (List (), methodValue) setSymbol funSym setPos pos, mode, pt)
4392+
43864393 case ErrorType =>
4387- expr1
4394+ methodValue
4395+
43884396 case _ =>
4389- UnderscoreEtaError (expr1 )
4397+ UnderscoreEtaError (methodValue )
43904398 }
43914399
43924400 def tryTypedArgs (args : List [Tree ], mode : Mode ): Option [List [Tree ]] = {
@@ -4430,7 +4438,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
44304438 case Annotated (_, r) => treesInResult(r)
44314439 case If (_, t, e) => treesInResult(t) ++ treesInResult(e)
44324440 case Try (b, catches, _) => treesInResult(b) ++ catches
4433- case Typed (r, Function (Nil , EmptyTree )) => treesInResult(r)
4441+ case Typed (r, Function (Nil , EmptyTree )) => treesInResult(r) // a method value
44344442 case Select (qual, name) => treesInResult(qual)
44354443 case Apply (fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult)
44364444 case TypeApply (fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult)
@@ -5070,11 +5078,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
50705078 // because `expr` might contain nested macro calls (see SI-6673)
50715079 //
50725080 // Note: apparently `Function(Nil, EmptyTree)` is the secret parser marker
5073- // which means trailing underscore.
5081+ // which means trailing underscore -- denoting a method value. See makeMethodValue in TreeBuilder .
50745082 case Typed (expr, Function (Nil , EmptyTree )) =>
50755083 typed1(suppressMacroExpansion(expr), mode, pt) match {
50765084 case macroDef if treeInfo.isMacroApplication(macroDef) => MacroEtaError (macroDef)
5077- case exprTyped => typedEta(checkDead(exprTyped ))
5085+ case methodValue => typedEta(checkDead(methodValue ))
50785086 }
50795087 case Typed (expr, tpt) =>
50805088 val tpt1 = typedType(tpt, mode) // type the ascribed type first
0 commit comments