@@ -244,6 +244,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
244244 var context = context0
245245 def context1 = context
246246
247+ // for use with silent type checking to when we can't have results with undetermined type params
248+ // note that this captures the context var
249+ val isMonoContext = (_ : Any ) => context.undetparams.isEmpty
250+
247251 def dropExistential (tp : Type ): Type = tp match {
248252 case ExistentialType (tparams, tpe) =>
249253 new SubstWildcardMap (tparams).apply(tp)
@@ -2888,20 +2892,31 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
28882892
28892893 // If we're typing `(a1: T1, ..., aN: TN) => m(a1,..., aN)`, where some Ti are not fully defined,
28902894 // type `m` directly (undoing eta-expansion of method m) to determine the argument types.
2895+ // This tree is the result from one of:
2896+ // - manual eta-expansion with named arguments (x => f(x));
2897+ // - wildcard-style eta expansion (`m(_, _,)`);
2898+ // - instantiateToMethodType adapting a tree of method type to a function type using etaExpand.
2899+ //
2900+ // Note that method values are a separate thing (`m _`): they have the idiosyncratic shape
2901+ // of `Typed(expr, Function(Nil, EmptyTree))`
28912902 val ptUnrollingEtaExpansion =
28922903 if (paramsMissingType.nonEmpty && pt != ErrorType ) fun.body match {
2904+ // we can compare arguments and parameters by name because there cannot be a binder between
2905+ // the function's valdefs and the Apply's arguments
28932906 case Apply (meth, args) if (vparams corresponds args) { case (p, Ident (name)) => p.name == name case _ => false } =>
2907+ // We're looking for a method (as indicated by FUNmode in the silent typed below),
2908+ // so let's make sure our expected type is a MethodType
28942909 val methArgs = NoSymbol .newSyntheticValueParams(argpts map { case NoType => WildcardType case tp => tp })
2895- // we're looking for a method (as indicated by FUNmode), so let's make sure our expected type is a MethodType
2896- val methPt = MethodType (methArgs, respt)
2897-
2898- silent(_.typed(meth, mode.forFunMode, methPt)) filter (_ => context.undetparams.isEmpty) map { methTyped =>
2910+ silent(_.typed(meth, mode.forFunMode, MethodType (methArgs, respt))) filter (isMonoContext) map { methTyped =>
28992911 // if context.undetparams is not empty, the method was polymorphic,
29002912 // so we need the missing arguments to infer its type. See #871
29012913 val funPt = normalize(methTyped.tpe) baseType FunctionClass (numVparams)
29022914 // println(s"typeUnEtaExpanded $meth : ${methTyped.tpe} --> normalized: $funPt")
29032915
2904- if (isFunctionType(funPt) && isFullyDefined(funPt)) funPt
2916+ // If we are sure this function type provides all the necesarry info, so that we won't have
2917+ // any undetermined argument types, go ahead an recurse below (`typedFunction(fun, mode, ptUnrollingEtaExpansion)`)
2918+ // and rest assured we won't end up right back here (and keep recursing)
2919+ if (isFunctionType(funPt) && funPt.typeArgs.iterator.take(numVparams).forall(isFullyDefined)) funPt
29052920 else null
29062921 } orElse { _ => null }
29072922 case _ => null
0 commit comments