Skip to content

Fix #2677: Several fixes involving super selection #2768

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 8 commits into from
Jun 20, 2017

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jun 15, 2017

This was much harder than I thought. In the end, there are several fixes that interact in interesting ways with each other.

  1. We fix the way baseclasses are computed in AndTypes.
  2. We fix the way members of supertypes are computed.
  3. We keep the order of operands of a & invariant.

The problems in (1) and (3) conspired to cancel each other out. So once I fixed (1) the problem caused by (3) became apparent, but in a very indirect way. Details are in the commit message of
0f708eb.

odersky added 4 commits June 15, 2017 12:23
List union is clearly wrong, as it is simply the same as ++.
It used to return the joint denotation, but the correct
answer is the denotation of the symbol in the joint denotation
as seen from the super prefix.
@OlivierBlanvillain
Copy link
Contributor

OlivierBlanvillain commented Jun 15, 2017

Failure reproduced on my machine with sbt dotty-bootstrapped/vulpix t1751

Testing ../tests/pos-java-interop/t1751
scala.MatchError: Typed(SeqLiteral(List(),TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,lang)),Class), java$lang$Class$$T, TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing), TypeRef(ThisType(TypeRef(NoPrefix,scala)),Any))))]),TypeTree[RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,scala)),<repeated>), scala$<repeated>$$T0, TypeAlias(TypeVar(ParamRef(scala$Array$apply$$T) -> RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,lang)),Class), java$lang$Class$$T, TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing), TypeRef(ThisType(TypeRef(NoPrefix,scala)),Any)))), 1))]) (of class dotty.tools.dotc.ast.Trees$Typed)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitArgument(DottyBackendInterface.scala:237)
        at dotty.tools.backend.jvm.DottyBackendInterface.$anonfun$31(DottyBackendInterface.scala:279)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:392)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitArgument(DottyBackendInterface.scala:279)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitAssocs$$anonfun$2(DottyBackendInterface.scala:315)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:733)
        at scala.collection.immutable.List.foreach(List.scala:392)
        at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:732)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitAssocs(DottyBackendInterface.scala:315)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitAnnotations$$anonfun$5(DottyBackendInterface.scala:308)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:733)
        at scala.collection.immutable.List.foreach(List.scala:392)
        at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:732)
        at dotty.tools.backend.jvm.DottyBackendInterface.emitAnnotations(DottyBackendInterface.scala:309)
        at scala.tools.nsc.backend.jvm.BCodeHelpers$BCAnnotGen.emitAnnotations(BCodeHelpers.scala:282)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.initJClass(BCodeSkelBuilder.scala:161)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:102)
        at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.visit(GenBCode.scala:199)
        at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.run(GenBCode.scala:152)
        at dotty.tools.backend.jvm.GenBCodePipeline.buildAndSendToDisk(GenBCode.scala:367)
        at dotty.tools.backend.jvm.GenBCodePipeline.run(GenBCode.scala:333)
        at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:54)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$2(Phases.scala:283)
        at scala.collection.immutable.List.map(List.scala:284)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:285)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$1(Run.scala:82)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
        at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
        at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:90)
        at scala.compat.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
        at dotty.tools.dotc.util.Stats$.monitorHeartBeat(Stats.scala:76)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:95)
        at dotty.tools.dotc.Run.compileSources(Run.scala:64)
        at dotty.tools.dotc.Run.compile(Run.scala:48)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:26)
        at dotty.tools.vulpix.ParallelTesting$$anon$20.doCompile$$anonfun$1(ParallelTesting.scala:367)
        at dotty.tools.vulpix.ParallelTesting$$anon$20.ntimes$$anonfun$1(ParallelTesting.scala:362)
        at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)
        at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)
        at scala.collection.immutable.Range.foreach(Range.scala:160)
        at scala.collection.TraversableOnce$class.foldLeft(TraversableOnce.scala:157)
        at scala.collection.AbstractTraversable.foldLeft(Traversable.scala:104)
        at scala.collection.TraversableOnce$class.$div$colon(TraversableOnce.scala:151)
        at scala.collection.AbstractTraversable.$div$colon(Traversable.scala:104)
        at dotty.tools.vulpix.ParallelTesting$$anon$20.ntimes(ParallelTesting.scala:362)
        at dotty.tools.vulpix.ParallelTesting$$anon$20.doCompile(ParallelTesting.scala:369)
        at dotty.tools.dotc.Driver.process(Driver.scala:124)
        at dotty.tools.dotc.Driver.process(Driver.scala:93)
        at dotty.tools.vulpix.ParallelTesting$Test.compile(ParallelTesting.scala:377)
        at dotty.tools.vulpix.ParallelTesting$PosTest$$anon$17.$anonfun$131(ParallelTesting.scala:444)
        at scala.collection.immutable.List.map(List.scala:288)
        at dotty.tools.vulpix.ParallelTesting$PosTest$$anon$17.checkTestSource$$anonfun$2(ParallelTesting.scala:445)
        at scala.compat.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
        at dotty.tools.vulpix.ParallelTesting$Test.tryCompile(ParallelTesting.scala:311)
        at dotty.tools.vulpix.ParallelTesting$PosTest$$anon$17.checkTestSource(ParallelTesting.scala:464)
        at dotty.tools.vulpix.ParallelTesting$Test$LoggedRunnable.run(ParallelTesting.scala:212)
        at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Error while emitting A2_1.scala
Typed(SeqLiteral(List(),TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,lang)),Class), java$lang$Class$$T, TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing), TypeRef(ThisType(TypeRef(NoPrefix,scala)),Any))))]),TypeTree[RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,scala)),<repeated>), scala$<repeated>$$T0, TypeAlias(TypeVar(ParamRef(scala$Array$apply$$T) -> RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,lang)),Class), java$lang$Class$$T, TypeBounds(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing), TypeRef(ThisType(TypeRef(NoPrefix,scala)),Any)))), 1))]) (of class dotty.tools.dotc.ast.Trees$Typed)
-- [E006] Unbound Identifier Error: /home/olivier/workspace/dotty/compiler/../tests/pos-java-interop/t1751/A1_2.scala:1:28
1 |@SuiteClasses(Array(classOf[A2]))
  |                            ^^
  |                            not found: type A2
[error] Test dotty.tools.dotc.CompilationTests.posTwice failed: java.lang.AssertionError: Expected no errors when compiling, but found: 2, took 2.121 sec
[error]     at dotty.tools.vulpix.ParallelTesting$CompilationTest.checkCompile(ParallelTesting.scala:845)
[error]     at dotty.tools.dotc.CompilationTests.posTwice(CompilationTests.scala:139)
[error]     ...

@odersky
Copy link
Contributor Author

odersky commented Jun 16, 2017

The problem is we need to know in what order the files for dotc itself were compiled. Unfortunately it's that order that makes a difference between a compiler that works and a compiler that crashes. Can you pull that out of the logs on your machine?

We previously could get the following:

Given:

    class A
    trait B extends A
    trait C extends A

Then

    (A & B) & C

simplified to

    C & B

This is usually not a problem, *except* for typing super calls, where we pick
the symbol of the right operand. The problem was masked because due to the wrong
computation of base classes for AndTypes, we always ended up picking the leftmost
symbol in a joint denotation instead of the rightmost one. So we got a double swap!

The problem is reproducible in the test case. It originally manifested itself only
in the bootstrap, and only under a particular order of compiling files, which was
exercised by the CI but initially not by my local setup. The summary of the problem is as follows:

ElimRepeated has the structure of ER in the test case. Because of
the problem, a super call in `transform` of `ElimRepeated` went to `InfoTransformers` instead
of `AnnotationTransformers`. Consequently, the elim repeated transform was not done on
annotations, which led to backend crashes of the bootstrapped compiler for those annotations
that had repeated arguments. It took me two full days to get to the bottom of this.
Must rank right at the top of the list of hard-to-find bugs for me.

Note: It would seem logical to apply a similar technique to OrTypes. But this currently fails some tests. Need to investigate later.
@odersky odersky changed the title WIP Another partial fix of #2677 Fix #2677: Several fixes involving super selection Jun 16, 2017
@odersky odersky requested a review from smarter June 16, 2017 17:12
class Context
implicit val ctx: Context

f(2) // OK
Copy link
Member

Choose a reason for hiding this comment

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

The definition of f appears to be missing from this test.

else
if (bcs1set contains bc2)
if (bc2.is(Trait)) bc2 :: recur(bcs2rest)
else bcs2rest
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be bcs2 ? Otherwise we miss bc2 even though it's contained in the baseclasses of both operands

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

LGTM, but it seems like we really need more tests exercising the base classes of an OrType :)

@odersky odersky merged commit ea582a7 into scala:master Jun 20, 2017
@allanrenucci allanrenucci deleted the fix-@2677-2 branch December 14, 2017 19:19
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.

3 participants