Skip to content
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

Fix #12128: Add test #12592

Merged
merged 3 commits into from
Jun 2, 2021
Merged

Fix #12128: Add test #12592

merged 3 commits into from
Jun 2, 2021

Conversation

liufengyun
Copy link
Contributor

@liufengyun liufengyun commented May 25, 2021

Fix #12128: Add test

When we are reading a new definition from tasty and setting info of
a symbol in readNewDef:

      sym.info = methodType(paramss, resType)

The line above will reach TreeChecker.transformSym:

      assert(symd.signature == initial.signature

At the time, the symd is not yet completed. Getting signature of the
denotation will force the symbol and trigger completion of the info,
which reaches the PositionTree in readIndexedDef.

@liufengyun liufengyun marked this pull request as ready for review May 25, 2021 12:58
@liufengyun liufengyun requested a review from griggt May 26, 2021 08:11
compiler/src/dotty/tools/dotc/transform/TreeChecker.scala Outdated Show resolved Hide resolved
@@ -0,0 +1,30 @@
trait Context: // Dummy scala.reflect.macros.Context
Copy link
Contributor

@griggt griggt May 31, 2021

Choose a reason for hiding this comment

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

This regression test using the dummy scala.reflect.macros.Context for some reason does not trigger the issue reported in #12128. It passes when compiled with 3.0.0 (aside from the cyclic reference while unpickling if -Ycheck is specified).

So, I have manually verified that the issue is fixed, but the test passes even without the new init checker from #12495 in place. 😕

It's the end of my day here, but I can probably find time to investigate this tomorrow if needed.

Edit: I notice you had the same observation: #12128 (comment)

For 3.0.0-RC2, the dependence on scala-reflect seems to be essential. If that's replaced with a dummy definition, things work fine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This regression test using the dummy scala.reflect.macros.Context for some reason does not trigger the issue reported in #12128.
So, I have manually verified that the issue is fixed

Thanks for checking that. I intended to add the original example as a test, but as it depends on scala-reflect, which makes it difficult to do so --- creating a dummy Context seems to be the closest thing that can be done.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have some (mostly complete) changes that I believe will make the test case work properly without the dependency on scala-reflect. I'll finish and push them in the morning.

Copy link
Contributor

Choose a reason for hiding this comment

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

Considering the regression test consists of three components:

(a) Reflect_1 (as a stand-in for scala-reflect)
(b) Macro_2 (as a stand-in for munit)
(c) Test_3 (user code)

the key to reproduce the issue in #12128 is to compile these separately, with

  • the output from (a) on the classpath while compiling (b)
  • the output from (b) on the classpath while compiling (c)
  • the output from (a) not on the classpath while compiling (c)

In the real-world case of #12128, this situation occurs because MUnit has a Provided dependency on scala-reflect:
https://github.com/scalameta/munit/blob/d592d71f8360f1eaae2f19c1d582b75fe5d44714/build.sbt#L178-L182

I have rebased (to resolve conflicts) and pushed a commit which modifies the testing to meet the above requirements.

Incidentally, #12128 seems to have been fixed both by #12484 (for the old init checker) and #12495 (the new init checker).

@@ -91,7 +91,7 @@ class TreeChecker extends Phase with SymTransformer {
// until erasure, see the comment above `Compiler#phases`.
if (ctx.phaseId <= erasurePhase.id) {
val initial = symd.initial
assert(symd.signature == initial.signature,
assert(symd == initial || symd.signature == initial.signature,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert(symd == initial || symd.signature == initial.signature,
assert((symd eq initial) || symd.signature == initial.signature,

Nitpick: is reference equality more appropriate here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, using eq is a good idea, semantically they are the same for Dotty. BTW, we usually use backquote for non-symbolic infix operators.

@@ -0,0 +1,30 @@
trait Context: // Dummy scala.reflect.macros.Context
Copy link
Contributor

Choose a reason for hiding this comment

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

I have some (mostly complete) changes that I believe will make the test case work properly without the dependency on scala-reflect. I'll finish and push them in the morning.

liufengyun and others added 3 commits June 1, 2021 15:13
When we are reading a new definition from tasty and setting `info` of
a symbol in `readNewDef`:

          sym.info = methodType(paramss, resType)

The line above will reach `TreeChecker.transformSym`:

          assert(symd.signature == initial.signature

At the time, the `symd` is not yet completed. Getting signature of the
denotation will force the symbol and trigger completion of the info,
which reaches the `PositionTree` in `readIndexedDef.
To properly reproduce scala#12128, the regression test has some atypical
classpath requirements in addition to separate compilation.
Copy link
Contributor Author

@liufengyun liufengyun left a comment

Choose a reason for hiding this comment

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

Thank you @griggt , LGTM.

I'm wondering if we should keep a copy of the test with normal compilation, as it tests a different stack trace. Or, it has the same stack trace as if compiled normally?

@liufengyun
Copy link
Contributor Author

I'm wondering if we should keep a copy of the test with normal compilation, as it tests a different stack trace. Or, it has the same stack trace as if compiled normally?

Just checked, the modified test still has the same stack trace, so we are good.

@griggt
Copy link
Contributor

griggt commented Jun 2, 2021

I'm wondering if we should keep a copy of the test with normal compilation, as it tests a different stack trace. Or, it has the same stack trace as if compiled normally?

The revised test I pushed (with separate classpaths) gives the following stack trace on 3.0.0:

java.lang.AssertionError: assertion failed: Cyclic reference while unpickling definition at address 188 in unit tests/init/special/i12128/Test_3.scala while compiling tests/init/special/i12128/Test_3.scala
Fatal compiler crash when compiling: tests/init/special/i12128/Test_3.scala:
assertion failed: Cyclic reference while unpickling definition at address 188 in unit tests/init/special/i12128/Test_3.scala
scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readIndexedDef(TreeUnpickler.scala:771)
dotty.tools.dotc.core.tasty.TreeUnpickler$Completer.complete(TreeUnpickler.scala:122)
dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:167)
dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:188)
dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:190)
dotty.tools.dotc.core.Denotations$SingleDenotation.signature(Denotations.scala:610)
dotty.tools.dotc.core.Denotations$SingleDenotation.signature(Denotations.scala:602)
dotty.tools.dotc.transform.TreeChecker.transformSym(TreeChecker.scala:94)
    ....

and this stack trace on 3.0.0 with the TreeChecker fix from this PR:

cannot resolve reference to type c.type.Tree
the classfile defining the type might be missing from the classpath while compiling tests/init/special/i12128/Test_3.scala
Fatal compiler crash when compiling: tests/init/special/i12128/Test_3.scala:
dotty.tools.dotc.core.TypeErasure.dotty$tools$dotc$core$TypeErasure$$sigName(TypeErasure.scala:776)
dotty.tools.dotc.core.TypeErasure$.sigName(TypeErasure.scala:204)
dotty.tools.dotc.core.Signature$.apply(Signature.scala:169)
dotty.tools.dotc.core.Types$MethodOrPoly.computeSignature$1(Types.scala:3394)
dotty.tools.dotc.core.Types$MethodOrPoly.signature(Types.scala:3415)
dotty.tools.dotc.core.Denotations$SingleDenotation.signature(Denotations.scala:612)
dotty.tools.dotc.core.Denotations$SingleDenotation.signature(Denotations.scala:602)
  ....

So I believe we are ok.

@liufengyun liufengyun merged commit 833f5b9 into scala:master Jun 2, 2021
@liufengyun liufengyun deleted the fix-12128 branch June 2, 2021 06:31
@Kordyjan Kordyjan added this to the 3.0.2 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.

Testing unusable with -Ysafe-init
3 participants