Skip to content

Compilation order dependencies in compileStdLib #5433

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

Closed
milessabin opened this issue Nov 12, 2018 · 20 comments
Closed

Compilation order dependencies in compileStdLib #5433

milessabin opened this issue Nov 12, 2018 · 20 comments

Comments

@milessabin
Copy link
Contributor

Running testCompilation locally fails for me (Linux, Oracle JDK 1.8.0_192) due to what appears to be a compilation order dependency in compileStdLib. This isn't normally visible in CI runs, presumably due to platform dependency of the compilation order. Sorting the sources, as done in #5432 causes local and CI builds to fail in the same way.

@milessabin milessabin changed the title Compilation order dependencies in compileStdLib Compilation order dependencies in compileStdLib Nov 12, 2018
@milessabin
Copy link
Contributor Author

After updating I no longer see a local failure unless I explicitly sort the sources, so local and CI appear to be on a par now.

I've attempted to minimize the problem and come up with the following,

dotc -language:Scala2 -d local/classes \
  scala2-library/src/library/scala/collection/IterableViewLike.scala \
  scala2-library/src/library/scala/collection/SeqViewLike.scala \
  scala2-library/src/library/scala/collection/TraversableViewLike.scala \
  scala2-library/src/library/scala/collection/immutable/Stream.scala

Compiling the three ViewLikes on their own, or the Stream on it's own completes successfully.

However, with all four the compiler crashes with,

***** missing reference, looking for Transformed/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Transformed/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for AbstractTransformed/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to AbstractTransformed/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for EmptyView/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to EmptyView/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Forced/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Forced/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Sliced/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Sliced/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Mapped/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Mapped/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for FlatMapped/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to FlatMapped/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Appended/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Appended/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Filtered/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Filtered/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for TakenWhile/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to TakenWhile/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for DroppedWhile/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to DroppedWhile/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Zipped/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Zipped/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for ZippedAll/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to ZippedAll/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Reversed/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Reversed/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Patched/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Patched/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).
***** missing reference, looking for Prepended/T in trait SeqViewLike
decls = Scope{ ... }
Bad symbolic reference. A signature in /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class)
refers to Prepended/T in trait scala.collection.SeqViewLike which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling /home/miles/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.7.jar(scala/collection/immutable/StreamViewLike.class).

@smarter
Copy link
Member

smarter commented Nov 22, 2018

This seems like a different issue: to compile Stream we unpickle StreamViewLike from a Scala 2 classfile, which then tries to find some symbol in SeqViewLike that we're also trying to compile. This sort of Dotty->Scala2->Dotty dependency chain is not something that should ever happen in a real project (that is, until we make Scala 2 use Dotty as a backend) so we shouldn't try to make it work.

If you add StreamViewLike to the list of files you're compiling, do you still get a crash ?

@milessabin
Copy link
Contributor Author

This sort of Dotty->Scala2->Dotty dependency chain is not something that should ever happen in a real project (that is, until we make Scala 2 use Dotty as a backend) so we shouldn't try to make it work.

Perhaps. But then removing any source file from the full compileStdLib set is going to involve unpickling the missing items from the Scala 2 classpath. If that's the case then it looks like any attempt to minimize the original problem will change the nature of the issue.

@milessabin
Copy link
Contributor Author

If you add StreamViewLike to the list of files you're compiling, do you still get a crash ?

No it doesn't.

@smarter
Copy link
Member

smarter commented Nov 22, 2018

If that's the case then it looks like any attempt to minimize the original problem will change the nature of the issue.

One way around that would be to first change the top level package (easiest way to do it is to add "package foo" at the top of every file) then do the minimization.

@milessabin
Copy link
Contributor Author

One way around that would be to first change the top level package (easiest way to do it is to add "package foo" at the top of every file) then do the minimization.

TBQH, that's what I think the full test really ought to be.

@smarter
Copy link
Member

smarter commented Nov 22, 2018

Well we do need to test the actual standard library as we would compile it as part of the bootstrapping process, but since we're moving to the 2.13 library anyway, it'd make sense to import the sources of the 2.12 library in the dotty repo, add an extra top package, and make it a regular test.

@allanrenucci
Copy link
Contributor

Reduced to 4 files:

dotc -Ycheck:all -language:Scala2 scala2-library/src/library/scala/collection/IterableViewLike.scala scala2-library/src/library/scala/collection/SeqViewLike.scala scala2-library/src/library/scala/collection/TraversableViewLike.scala scala2-library/src/library/scala/collection/mutable/IndexedSeqView.scala

@allanrenucci
Copy link
Contributor

And here is a single file reproduction:

package scala.collection

trait IterableViewLike[+A, +Coll, +This <: IterableView[A, Coll] with IterableViewLike[A, Coll, This]]
     extends TraversableView[A, Coll] {

  trait TransformedI[+B] extends IterableView[B, Coll] with super.TransformedT[B]
}

trait SeqViewLike[+A, +Coll, +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]]
  extends IterableView[A, Coll] with IterableViewLike[A, Coll, This] {

  trait TransformedS[+B] extends SeqView[B, Coll] with super.TransformedI[B]
  abstract class AbstractTransformedS[+B] extends Seq[B] with super[IterableViewLike].TransformedI[B] with TransformedS[B]
}

trait TraversableViewLike[+A, +Coll, +This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]] {

  trait TransformedT[+B] extends TraversableView[B, Coll]
}

trait IndexedSeqView[A, +Coll] extends IndexedSeq[A]
                                with IndexedSeqOptimized[A, IndexedSeqView[A, Coll]]
                                with SeqView[A, Coll]
                                with SeqViewLike[A, Coll, IndexedSeqView[A, Coll]] {

  trait TransformedX[B] extends IndexedSeqView[B, Coll] with super.TransformedS[B]
  abstract class AbstractTransformedX[B] extends super.AbstractTransformedS[B] with TransformedX[B]
}

@smarter
Copy link
Member

smarter commented Dec 12, 2018

Minimization:

import scala.collection._

abstract class ATS[B] extends Seq[B]

trait ISV[A, +Coll] extends IndexedSeq[A]
                       with IndexedSeqOptimized[A, ISV[A, Coll]] {
  abstract class Fail[B] extends ATS[B] with ISV[B, Coll]
}

@smarter
Copy link
Member

smarter commented Dec 12, 2018

@allanrenucci Your reproduction (and my minimization) both fail to compile using scalac with:

i5433.scala:5: error: overriding method newBuilder in trait TraversableLike of type => scala.collection.mutable.Builder[A,ISV[A,Coll]];
 method newBuilder in trait GenericTraversableTemplate of type => scala.collection.mutable.Builder[A,IndexedSeq[A]] has incompatible type
trait ISV[A, +Coll] extends IndexedSeq[A]
      ^
one error found

So they're not actually valid reproduction of the original problem, but point to a separate issue in Dotty (missing check in RefChecks)

@smarter
Copy link
Member

smarter commented Dec 12, 2018

Here's a minimization that:

  • Crashes with a Ycheck failure after ResolveSuper with dotty
  • Compiles with scalac
  • ... but also crashes at runtime with a ClassCastException when compiled with scalac. Indicating that scalac is also miscompiling that code (the crash only happens when we call super.foo):
class X
class Y extends X

trait A[+T] {
  def foo: T = null.asInstanceOf[T]
}

trait B extends A[X] {
  override def foo: X = new X
}

trait C extends A[Y] {
  override def foo: Y = new Y
  super.foo
}

class Fail extends B with C

object Test {
  def main(args: Array[String]): Unit = {
    new Fail // ClassCastException: X cannot be cast to Y
  }
}

@adriaanm is this a known issue ? ^

@smarter
Copy link
Member

smarter commented Dec 12, 2018

To elaborate, the problem is that the call to super.foo in C creates an abstract super-accessor in C like this:

def C$$super$foo: Y

which is then implemented in Fail as:

def C$$super$foo: Y = super[B].foo

which does not typecheck since the result type of B#foo is X, not Y.

Looking at the spec for super-calls, I don't think this situation was ever considered.

@smarter
Copy link
Member

smarter commented Dec 12, 2018

Note that I checked and scala/scala#7439 doesn't save us here.

@smarter
Copy link
Member

smarter commented Dec 12, 2018

I think the correct thing to do here would be for C$$super$foo in Fail to be implemented as:

def C$$super$foo: Y = super[A[Y]].foo

That is, pick the first element in the linearization order that typechecks, so super[B].foo is out.

@Blaisorblade
Copy link
Contributor

@smarter just showed me this and it looks pretty scary... with the current runtime semantics for superaccessors, super.foo in B should have type Any in the latest example.

It's not obvious what would be a good fix.

Strictly speaking, a more accurate type would be a (not-yet-existing) super.T (that is, what T was in the superclass found by linearization), but to get anything from that you'd have to add constraints to super.T.

That is, pick the first element in the linearization order that typechecks, so super[B].foo is out.

That seems sound, but it seems a concerning chance in semantics for this case, tho it might be OK in practice.

smarter added a commit to dotty-staging/dotty that referenced this issue Dec 12, 2018
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).
smarter added a commit to dotty-staging/dotty that referenced this issue Dec 12, 2018
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.

This seems like it should be clarified to indicate that the member m'
may be found not only in "the actual supertype" (defined elsewhere) but
in any supertype of the actual supertype.
@odersky
Copy link
Contributor

odersky commented Dec 13, 2018

I think the correct thing to do here would be for C$$super$foo in Fail to be implemented as:

def C$$super$foo: Y = super[A[Y]].foo

That is, pick the first element in the linearization order that typechecks, so super[B].foo is out.

My first reaction would be to still make this a super[B].foo but then recognize and report the type error. Silently going to a different super if types do not work out seems too dangerous.

@smarter
Copy link
Member

smarter commented Dec 13, 2018

I don't have strong feelings either way, but emitting an error here means that implementation details (which traits need what kind of super-accessors) affect how traits can be composed, and since users don't fully control the linearization order they might be stuck, e.g. writing:

class Fail extends B with A[Y] with C

doesn't help. A will still be before B in the linearization. So user code might suddenly break because a library added a super-call somewhere, with no way to fix the breakage without changing the library as far as I can tell.

@smarter
Copy link
Member

smarter commented Dec 13, 2018

Thankfully it looks like the 2.13 library doesn't need many super-accessors, it could still be useful to review all the super. calls in traits that could be super[X]., if only because the later is likely to be faster /cc @szeiger

allanrenucci pushed a commit to dotty-staging/dotty that referenced this issue Dec 14, 2018
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.

This seems like it should be clarified to indicate that the member m'
may be found not only in "the actual supertype" (defined elsewhere) but
in any supertype of the actual supertype.
@Blaisorblade
Copy link
Contributor

@odersky’s idea might be the least bad here.

So user code might suddenly break because a library added a super-call somewhere, with no way to fix the breakage without changing the library as far as I can tell.

That’s a good point and an annoying failure of separate typechecking. But we already fail this sort of guarantee to some extent: in some cases you cannot reliably mix together traits from independent maintainers. If later both add a method with the same name, you’re stuck. In some scenarios that’s even more annoying. If you use the cake pattern with interfaces, you can have two “module interfaces” that compose together, and two “implementations” that don’t link together because of such extra methods.

This is still a very annoying pitfall. What I don’t get is how was the impact so low nobody knew?

smarter added a commit to smarter/dotty that referenced this issue Jan 6, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.

This seems like it should be clarified to indicate that the member m'
may be found not only in "the actual supertype" (defined elsewhere) but
in any supertype of the actual supertype.
odersky pushed a commit to odersky/dotty that referenced this issue Jan 11, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.

This seems like it should be clarified to indicate that the member m'
may be found not only in "the actual supertype" (defined elsewhere) but
in any supertype of the actual supertype.
odersky pushed a commit to dotty-staging/dotty that referenced this issue Jan 11, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems to have the same bug (but at least in Dotty this
is detected by -Ycheck:all).

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.

This seems like it should be clarified to indicate that the member m'
may be found not only in "the actual supertype" (defined elsewhere) but
in any supertype of the actual supertype.
smarter added a commit to smarter/dotty that referenced this issue Feb 28, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems had the same bug (but at least in Dotty this is
detected by -Ycheck:all), now fixed based on the logic in this PR by
scala/scala#7641.

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.
smarter added a commit to dotty-staging/dotty that referenced this issue Feb 28, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems had the same bug (but at least in Dotty this is
detected by -Ycheck:all), now fixed based on the logic in this PR by
scala/scala#7641.

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.
smarter added a commit to dotty-staging/dotty that referenced this issue Feb 28, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems had the same bug (but at least in Dotty this is
detected by -Ycheck:all), now fixed based on the logic in this PR by
scala/scala#7641.

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.
smarter added a commit to dotty-staging/dotty that referenced this issue Mar 2, 2019
Relying on `matchingDenotation` is not enough as demonstrated by
i5433.scala: in `Fail`, `B#foo` matches `C$$super$foo`
but it cannot implement it since `X` is a supertype of `Y`

Note that scalac seems had the same bug (but at least in Dotty this is
detected by -Ycheck:all), now fixed based on the logic in this PR by
scala/scala#7641.

For reference, here's what the spec says on resolving super accessors:

  A reference super.m refers statically to a method or type m in the
  least proper supertype of the innermost template containing the
  reference. It evaluates to the member m′ in the actual supertype of that
  template which is equal to m or which overrides m.
@smarter smarter closed this as completed in 5cebc76 Mar 5, 2019
smarter added a commit that referenced this issue Mar 5, 2019
Fix #5433: check that the implemented super-accessor is valid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants