Skip to content

Commit 771d4c4

Browse files
authored
Merge pull request #4165 from dotty-staging/change-avoid-missing-param
Avoid "missing parameter type" error when checking `isMatchedBy`
2 parents 9a9e984 + 3889333 commit 771d4c4

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)