-
Bug
-
Resolution: Fixed
-
P3
-
9-repo-kulla
-
None
>
> - the updates of corralled snippets seems to happen at the wrong time - this could lead to chain of symbols that are not usable:
>
> -> class D extends E { }
> | Added class D, however, it cannot be referenced until class E is declared
>
> -> class E { D d; }
> | Added class E, however, it cannot be referenced until class D is declared
>
> I guess what happens here is that, since the decision on whether to corral or not is based on the fact that we can compile cleanly , here we run into troubles. The first snippet obviously cannot be compiled cleanly, so it's corralled; the second one cannot compile cleanly because the first one is not 'defined' - so you get another resolution error and another corralled snippet. Unfortunately, the two snippets taken together form a legal source. Btw, I think the current behavior is preventing stuff like this:
>
> -> class A extends B { }
> | Added class A, however, it cannot be referenced until class B is declared
>
> -> class B extends A { }
> | Added class B, however, it cannot be referenced until class A is declared
>
> from looping forever in Eval.declare; perhaps the code could be made more robust by looking explicitly for update loops (i.e. this can be done by keeping a stack of all the updated snippets and see if we encounter the same snippet twice).
>
> - on update loops - I guess it is indeed possible to have loops, even with current corralling limitations (by exploiting redefinition):
>
> -> class Outer { class Inner extends Foo { } }
> | Added class Outer, however, it cannot be referenced until class Foo is declared
>
> -> class Foo { }
> | Added class Foo
>
> -> class Foo extends Outer { }
>
> Update loop check logic is in order I think. Also, interestingly - I'm not able to stop the REPL once I get into such a loop. Actually, later I found out it doesn't loop forever - I guess eventually it runs out of stack (after several minutes) and exits saying this:
>
> | Replaced class Foo
> | Update overwrote class Foo
>
>
> Which seems bogus anyway - given there's cyclic inheritance (no error is reported!).
>
Oy!
Wrapped snippets are compiled one at a time -- simple and clean, but that fails in this case. One problem is that the set of updates is not known before compilation. If a new snippet is or causes an update to an existing snippet its dependencies need only be updated in the case that redefinition fails. Redefinition usually succeeds, and certainly does for the false positive updates. I think the initial snippet and set of updates will need to be recompiled as full sets in each iteration, at least in the case of failure.
> - the updates of corralled snippets seems to happen at the wrong time - this could lead to chain of symbols that are not usable:
>
> -> class D extends E { }
> | Added class D, however, it cannot be referenced until class E is declared
>
> -> class E { D d; }
> | Added class E, however, it cannot be referenced until class D is declared
>
> I guess what happens here is that, since the decision on whether to corral or not is based on the fact that we can compile cleanly , here we run into troubles. The first snippet obviously cannot be compiled cleanly, so it's corralled; the second one cannot compile cleanly because the first one is not 'defined' - so you get another resolution error and another corralled snippet. Unfortunately, the two snippets taken together form a legal source. Btw, I think the current behavior is preventing stuff like this:
>
> -> class A extends B { }
> | Added class A, however, it cannot be referenced until class B is declared
>
> -> class B extends A { }
> | Added class B, however, it cannot be referenced until class A is declared
>
> from looping forever in Eval.declare; perhaps the code could be made more robust by looking explicitly for update loops (i.e. this can be done by keeping a stack of all the updated snippets and see if we encounter the same snippet twice).
>
> - on update loops - I guess it is indeed possible to have loops, even with current corralling limitations (by exploiting redefinition):
>
> -> class Outer { class Inner extends Foo { } }
> | Added class Outer, however, it cannot be referenced until class Foo is declared
>
> -> class Foo { }
> | Added class Foo
>
> -> class Foo extends Outer { }
>
> Update loop check logic is in order I think. Also, interestingly - I'm not able to stop the REPL once I get into such a loop. Actually, later I found out it doesn't loop forever - I guess eventually it runs out of stack (after several minutes) and exits saying this:
>
> | Replaced class Foo
> | Update overwrote class Foo
>
>
> Which seems bogus anyway - given there's cyclic inheritance (no error is reported!).
>
Oy!
Wrapped snippets are compiled one at a time -- simple and clean, but that fails in this case. One problem is that the set of updates is not known before compilation. If a new snippet is or causes an update to an existing snippet its dependencies need only be updated in the case that redefinition fails. Redefinition usually succeeds, and certainly does for the false positive updates. I think the initial snippet and set of updates will need to be recompiled as full sets in each iteration, at least in the case of failure.
- duplicates
-
JDK-8081796 JShell API: Infinite loop in redeclare by cross reference
-
- Closed
-
- relates to
-
JDK-8282160 JShell circularly-required classes cannot be defined
-
- Resolved
-