Skip to content

Survive NoType when erasing method result types #15439

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 1 commit into from
Jun 15, 2022

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jun 14, 2022

Fixes #15377

@odersky
Copy link
Contributor Author

odersky commented Jun 14, 2022

How I fixed it:

I first verified that the second example produced an error and what the error was: A qualifier of a select was Nothing so no member could be found.

I then looked at the crash and instrumented the situation before it happened. It was in TypeErasure:

      eraseResult(tp.resultType) match {
        case rt: MethodType =>
          tp.derivedLambdaType(names ++ rt.paramNames, formals ++ rt.paramInfos, rt.resultType)
        case rt =>
          tp.derivedLambdaType(names, formals, rt)

In fact, rt was NoType since it was a selection with a prefix of type Nothing. I then searched where the type was produced, which was in getStaticForwarderGenericSignature in BCCodeHelpers, which was called in turn by addForwarder.

addForwarder adds static forwarders to modules, and it does not matter if we skip a forwarder. So I tried to
prevent forwarder generation when the erased result type was Nothing. That worked, but what if we have a similar problem in the method argument types? So I thought it was better to prevent forwarder generation if the method type itself did not exist, and for this I needed the additional case in TypeErasure.

        case NoType =>
          // Can happen if we smuggle in a Nothing in the qualifier. Normally we prevent that
          // in Checking.checkMembersOK, but compiler-generated code can bypass this test.
          // See i15377.scala for a test case.
          NoType

It turned out that this check was good enough since addForwarder already avoids generation if the returned type is NoType.

@odersky odersky merged commit 2b596c1 into scala:main Jun 15, 2022
@odersky odersky deleted the fix-15377 branch June 15, 2022 10:32
@Kordyjan Kordyjan added this to the 3.2.0 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nothing and dependent types interplay: assertion failed in the compiler
4 participants