@@ -1994,68 +1994,76 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
19941994 }
19951995 }
19961996
1997- def adaptNoArgs (wtp : Type ): Tree = wtp match {
1998- case wtp : ExprType =>
1999- adaptInterpolated(tree.withType(wtp.resultType), pt)
2000- case wtp : ImplicitMethodType if constrainResult(wtp, followAlias(pt)) =>
2001- val tvarsToInstantiate = tvarsInParams(tree)
2002- wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
2003- val constr = ctx.typerState.constraint
2004- def addImplicitArgs (implicit ctx : Context ) = {
2005- val errors = new mutable.ListBuffer [() => String ]
2006- def implicitArgError (msg : => String ) = {
2007- errors += (() => msg)
2008- EmptyTree
2009- }
2010- def issueErrors () = {
2011- for (err <- errors) ctx.error(err(), tree.pos.endPos)
2012- tree.withType(wtp.resultType)
2013- }
2014- val args = (wtp.paramNames, wtp.paramInfos).zipped map { (pname, formal) =>
2015- def implicitArgError (msg : String => String ) =
2016- errors += (() => msg(em " parameter $pname of $methodStr" ))
2017- if (errors.nonEmpty) EmptyTree
2018- else inferImplicitArg(formal, implicitArgError, tree.pos.endPos)
2019- }
2020- if (errors.nonEmpty) {
2021- // If there are several arguments, some arguments might already
2022- // have influenced the context, binding variables, but later ones
2023- // might fail. In that case the constraint needs to be reset.
2024- ctx.typerState.constraint = constr
2025-
2026- // If method has default params, fall back to regular application
2027- // where all inferred implicits are passed as named args.
2028- if (tree.symbol.hasDefaultParams) {
2029- val namedArgs = (wtp.paramNames, args).zipped.flatMap { (pname, arg) =>
2030- arg match {
2031- case EmptyTree => Nil
2032- case _ => untpd.NamedArg (pname, untpd.TypedSplice (arg)) :: Nil
2033- }
2034- }
2035- tryEither { implicit ctx =>
2036- typed(untpd.Apply (untpd.TypedSplice (tree), namedArgs), pt)
2037- } { (_, _) =>
2038- issueErrors()
2039- }
2040- } else issueErrors()
2041- }
2042- else adapt(tpd.Apply (tree, args), pt)
1997+ def adaptImplicitMethod (wtp : ImplicitMethodType ): Tree = {
1998+ val tvarsToInstantiate = tvarsInParams(tree)
1999+ wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
2000+ val constr = ctx.typerState.constraint
2001+ def addImplicitArgs (implicit ctx : Context ) = {
2002+ val errors = new mutable.ListBuffer [() => String ]
2003+ def implicitArgError (msg : => String ) = {
2004+ errors += (() => msg)
2005+ EmptyTree
2006+ }
2007+ def issueErrors () = {
2008+ for (err <- errors) ctx.error(err(), tree.pos.endPos)
2009+ tree.withType(wtp.resultType)
20432010 }
2044- addImplicitArgs(argCtx(tree))
2045- case wtp : MethodType if ! pt.isInstanceOf [SingletonType ] =>
2046- // Follow proxies and approximate type paramrefs by their upper bound
2047- // in the current constraint in order to figure out robustly
2048- // whether an expected type is some sort of function type.
2049- def underlyingApplied (tp : Type ): Type = tp.stripTypeVar match {
2050- case tp : RefinedType => tp
2051- case tp : AppliedType => tp
2052- case tp : TypeParamRef => underlyingApplied(ctx.typeComparer.bounds(tp).hi)
2053- case tp : TypeProxy => underlyingApplied(tp.superType)
2054- case _ => tp
2011+ val args = (wtp.paramNames, wtp.paramInfos).zipped map { (pname, formal) =>
2012+ def implicitArgError (msg : String => String ) =
2013+ errors += (() => msg(em " parameter $pname of $methodStr" ))
2014+ if (errors.nonEmpty) EmptyTree
2015+ else inferImplicitArg(formal, implicitArgError, tree.pos.endPos)
20552016 }
2056- val ptNorm = underlyingApplied(pt)
2017+ if (errors.nonEmpty) {
2018+ // If there are several arguments, some arguments might already
2019+ // have influenced the context, binding variables, but later ones
2020+ // might fail. In that case the constraint needs to be reset.
2021+ ctx.typerState.constraint = constr
2022+
2023+ // If method has default params, fall back to regular application
2024+ // where all inferred implicits are passed as named args.
2025+ if (tree.symbol.hasDefaultParams) {
2026+ val namedArgs = (wtp.paramNames, args).zipped.flatMap { (pname, arg) =>
2027+ arg match {
2028+ case EmptyTree => Nil
2029+ case _ => untpd.NamedArg (pname, untpd.TypedSplice (arg)) :: Nil
2030+ }
2031+ }
2032+ tryEither { implicit ctx =>
2033+ typed(untpd.Apply (untpd.TypedSplice (tree), namedArgs), pt)
2034+ } { (_, _) =>
2035+ issueErrors()
2036+ }
2037+ } else issueErrors()
2038+ }
2039+ else adapt(tpd.Apply (tree, args), pt)
2040+ }
2041+ addImplicitArgs(argCtx(tree))
2042+ }
2043+
2044+ // Follow proxies and approximate type paramrefs by their upper bound
2045+ // in the current constraint in order to figure out robustly
2046+ // whether an expected type is some sort of function type.
2047+ def underlyingApplied (tp : Type ): Type = tp.stripTypeVar match {
2048+ case tp : RefinedType => tp
2049+ case tp : AppliedType => tp
2050+ case tp : TypeParamRef => underlyingApplied(ctx.typeComparer.bounds(tp).hi)
2051+ case tp : TypeProxy => underlyingApplied(tp.superType)
2052+ case _ => tp
2053+ }
2054+
2055+ def adaptNoArgs (wtp : Type ): Tree = {
2056+ val ptNorm = underlyingApplied(pt)
2057+ val functionExpected = defn.isFunctionType(ptNorm)
2058+ wtp match {
2059+ case wtp : ExprType =>
2060+ adaptInterpolated(tree.withType(wtp.resultType), pt)
2061+ case wtp : ImplicitMethodType
2062+ if constrainResult(wtp, followAlias(pt)) || ! functionExpected =>
2063+ adaptImplicitMethod(wtp)
2064+ case wtp : MethodType if ! pt.isInstanceOf [SingletonType ] =>
20572065 val arity =
2058- if (defn.isFunctionType(ptNorm) )
2066+ if (functionExpected )
20592067 if (! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none))
20602068 // if method type is fully defined, but expected type is not,
20612069 // prioritize method parameter types as parameter types of the eta-expanded closure
@@ -2156,7 +2164,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
21562164 // typr.println(TypeComparer.explained(implicit ctx => tree.tpe <:< pt))
21572165 adaptToSubType(wtp)
21582166 }
2159- }
2167+ }}
2168+
21602169 /** Adapt an expression of constant type to a different constant type `tpe`. */
21612170 def adaptConstant (tree : Tree , tpe : ConstantType ): Tree = {
21622171 def lit = Literal (tpe.value).withPos(tree.pos)
0 commit comments