SI-8010 Help to track down a corrupt Scope.

75 views
Skip to first unread message

Jason Zaugg

unread,
Nov 26, 2013, 2:29:43 AM11/26/13
to scala-i...@googlegroups.com
I'm tracing a bizarre regression in Erasure. I found the change that triggered it, but I think the real issue is somewhere else.

This rather low-level scope walking code in erasure:

private def checkNoDeclaredDoubleDefs(base: Symbol) {
  val decls = base.info.decls
  var e = decls.elems
  while (e ne null) {
    if (e.sym.isTerm) {
      var e1 = decls lookupNextEntry e
      while (e1 ne null) {
        if (sameTypeAfterErasure(e.sym, e1.sym))
          doubleDefError(new SymbolPair(base, e.sym, e1.sym))

        e1 = decls lookupNextEntry e1
      }
    }
    e = e.next
  }
}

... runs into a situation where `e eq e2`.

Below, I show the internal structure of `decls`, and the internal structure of a new scope with the same elements (_1 and _2 respectively.) In both of these scopes, decls.toList does not return duplicates.

Is this Scope indeed corrupt? What invariant is broken? I would like to add `Scope.validate()` and call that after any Scope mutation (though that might be too expensive to leave enabled) to determine from whence the corruption stems.

Thanks,

-jason

Inline image 1
image.png

Jason Zaugg

unread,
Nov 26, 2013, 4:32:43 AM11/26/13
to scala-i...@googlegroups.com
On Tue, Nov 26, 2013 at 8:29 AM, Jason Zaugg <jza...@gmail.com> wrote:
I'm tracing a bizarre regression in Erasure. I found the change that triggered it, but I think the real issue is somewhere else.

This rather low-level scope walking code in erasure:

private def checkNoDeclaredDoubleDefs(base: Symbol) {
  val decls = base.info.decls
  var e = decls.elems
  while (e ne null) {
    if (e.sym.isTerm) {
      var e1 = decls lookupNextEntry e
      while (e1 ne null) {
        if (sameTypeAfterErasure(e.sym, e1.sym))
          doubleDefError(new SymbolPair(base, e.sym, e1.sym))

        e1 = decls lookupNextEntry e1
      }
    }
    e = e.next
  }
}

Okay. Take a deep breath. Maybe sit down. Ready?

Looks like calling `info` during this Scope iteration is triggering the ExplicitOuter info transformer, which "makes all super accessors and modules in traits non-private, mangling their names.". This name change necessitates a rehashing of the owning scope, which I suspect is enough to corrupt the ScopeEntry-s being traversed in `checkNoDeclaredDoubleDefs`.

Changing the order that the symbols infos are forced to `e1`, then `e`, which was how things were before the regression, masks the problem in this instance.

Does this analysis sound plausible?

What can be done about this?
 - add `exitingPostErasure(decls.foreach(_.info))` before iterating. 
 - as suggested by a nearby comment `TODO - adapt SymbolPairs so it can be used here`, and centralize our defences
image.png

Adriaan Moors

unread,
Nov 26, 2013, 2:00:10 PM11/26/13
to scala-i...@googlegroups.com
Sheeeeeeeit, as Clay would say.

Sounds all too plausible to me. Is there a way to verify by detecting re-entrance?
(And throw a ConcurrentModificationException?)


--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

image.png

Jason Zaugg

unread,
Nov 26, 2013, 4:55:44 PM11/26/13
to scala-i...@googlegroups.com
On Tue, Nov 26, 2013 at 8:00 PM, Adriaan Moors <adr...@typesafe.com> wrote:
Sheeeeeeeit, as Clay would say.

Sounds all too plausible to me. Is there a way to verify by detecting re-entrance?
(And throw a ConcurrentModificationException?)

I half considered that, but wan't exactly sure how to go about it. We have very little by way of encapsulation when it comes to iteration of scopes, so there isn't a single point to enforce this.

I went for eager forcing of the infos and a big fat comment in:


In that PR, I mention why OverridingPairs hasn't seen this problem (yet).

-jason 
Reply all
Reply to author
Forward
0 new messages