Skip to content

Early return from resolveOverloaded in case arguments are erroneous #10985

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 13, 2021

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jan 4, 2021

Fixes #9344
Fixes #10983

This was more involved than I anticipated. I originally thought we could use isErroneous to flag types as not fit for inference.
But it turned out that was not exactly what we needed, and that in fact we need another predicate unusableForInference instead. This work also uncovered a failure to correctly treat parameter-dependent using clauses with defaults, which has
been fixed as well.

It seems isErroneous forces too much. cats fails in mysterious ways if it is called in resolveOverloaded,
even if it always returns false. This commit uses an error detector instead that does not go via an accumulator,
so that we have more control what gets visited.
We had a problem in handling using clauses that were both parameter dependent
and had default parameters. Example:

    trait A:
      type X

    f(using a: A = defaultA, b: a.X)

If implicit search fails for `A`, we should search the second parameter with
`defaultA.X` as type. We searched instead with an error type (i.e. the type of
the missing argument for A). Sine error types are compatible with everything,
any implicit candidate would match. In the original test i5427 we had just one
closest nested candidate that was the right one, but once we add another
candidate with a different type next to the first one the test fails.
If the searched-for type has errors, fail implicit search immediately.
Error types match everything, so we risk traversing many implicit
candidates for nothing.

This change uncovered the problem with parameter-dependent using
clauses with default arguments that was fixed in the last commit.
There are two concepts that were quite close but not exactly the same:

 - isErroneous, used if a type has errors in any part of it. Usually tested to
   not show a type with errors in it in diagnostics.
 - unusableForInference, used if a type (or its alias) has errors that make the
   type too undiscriminating for overloading resolution or implicit search.

Previously, we only used isErroneous in error diagnstics. Using it also for disabling
implicit search and resolutions ran into problems. Hence, the new predicate
unusableForInference.
Copy link
Member

@bishabosha bishabosha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

*/
def unusableForInference(using Context): Boolean = widenDealias match
case AppliedType(tycon, args) => tycon.unusableForInference || args.exists(_.unusableForInference)
case RefinedType(parent, _, rinfo) => parent.unusableForInference || rinfo.unusableForInference
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be a case for RecType?

@odersky odersky merged commit 626b24a into scala:master Jan 13, 2021
@odersky odersky deleted the fix-#9344 branch January 13, 2021 11:06
@Kordyjan Kordyjan added this to the 3.0.0 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dotty Repl OOM's on one-liner input Compiler "hangs" for 1+ minutes on a one line input.
3 participants