@@ -1994,68 +1994,76 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1994
1994
}
1995
1995
}
1996
1996
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)
2043
2010
}
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)
2055
2016
}
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 ] =>
2057
2065
val arity =
2058
- if (defn.isFunctionType(ptNorm) )
2066
+ if (functionExpected )
2059
2067
if (! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none))
2060
2068
// if method type is fully defined, but expected type is not,
2061
2069
// 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
2156
2164
// typr.println(TypeComparer.explained(implicit ctx => tree.tpe <:< pt))
2157
2165
adaptToSubType(wtp)
2158
2166
}
2159
- }
2167
+ }}
2168
+
2160
2169
/** Adapt an expression of constant type to a different constant type `tpe`. */
2161
2170
def adaptConstant (tree : Tree , tpe : ConstantType ): Tree = {
2162
2171
def lit = Literal (tpe.value).withPos(tree.pos)
0 commit comments