@@ -212,7 +212,7 @@ object ProtoTypes {
212212 private [this ] var evalState : SimpleIdentityMap [untpd.Tree , (TyperState , Constraint )] = SimpleIdentityMap .Empty
213213
214214 def isMatchedBy (tp : Type )(implicit ctx : Context ) =
215- typer.isApplicable(tp, Nil , typedArgs , resultType)
215+ typer.isApplicable(tp, Nil , unforcedTypedArgs , resultType)
216216
217217 def derivedFunProto (args : List [untpd.Tree ] = this .args, resultType : Type , typer : Typer = this .typer) =
218218 if ((args eq this .args) && (resultType eq this .resultType) && (typer eq this .typer)) this
@@ -240,33 +240,45 @@ object ProtoTypes {
240240 myTypedArg.size == args.length
241241 }
242242
243- private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree )(implicit ctx : Context ): Tree = {
243+ private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean )(implicit ctx : Context ): Tree = {
244244 var targ = myTypedArg(arg)
245245 if (targ == null ) {
246- targ = typerFn(arg)
247- if (! ctx.reporter.hasPending) {
248- myTypedArg = myTypedArg.updated(arg, targ)
249- evalState = evalState.updated(arg, (ctx.typerState, ctx.typerState.constraint))
246+ if (! force && untpd.functionWithUnknownParamType(arg).isDefined)
247+ // If force = false, assume ? rather than reporting an error.
248+ // That way we don't cause a "missing parameter" error in `typerFn(arg)`
249+ targ = arg.withType(WildcardType )
250+ else {
251+ targ = typerFn(arg)
252+ if (! ctx.reporter.hasPending) {
253+ myTypedArg = myTypedArg.updated(arg, targ)
254+ evalState = evalState.updated(arg, (ctx.typerState, ctx.typerState.constraint))
255+ }
250256 }
251257 }
252258 targ
253259 }
254260
255261 /** The typed arguments. This takes any arguments already typed using
256262 * `typedArg` into account.
263+ * @param force if true try to typecheck arguments even if they are functions
264+ * with unknown parameter types - this will then cause a
265+ * "missing parameter type" error
257266 */
258- def typedArgs : List [Tree ] = {
267+ private def typedArgs ( force : Boolean ) : List [Tree ] = {
259268 if (myTypedArgs.size != args.length)
260- myTypedArgs = args.mapconserve(cacheTypedArg(_, typer.typed(_)))
269+ myTypedArgs = args.mapconserve(cacheTypedArg(_, typer.typed(_), force ))
261270 myTypedArgs
262271 }
263272
273+ def typedArgs : List [Tree ] = typedArgs(force = true )
274+ def unforcedTypedArgs : List [Tree ] = typedArgs(force = false )
275+
264276 /** Type single argument and remember the unadapted result in `myTypedArg`.
265277 * used to avoid repeated typings of trees when backtracking.
266278 */
267279 def typedArg (arg : untpd.Tree , formal : Type )(implicit ctx : Context ): Tree = {
268280 val locked = ctx.typerState.ownedVars
269- val targ = cacheTypedArg(arg, typer.typedUnadapted(_, formal, locked))
281+ val targ = cacheTypedArg(arg, typer.typedUnadapted(_, formal, locked), force = true )
270282 typer.adapt(targ, formal, locked)
271283 }
272284
0 commit comments