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
StackOverflowError in typer with AnnotatedType #10081
Comments
Imported From: https://issues.scala-lang.org/browse/SI-10081?orig=1 |
@retronym said: Something like this avoids the problem: scala/scala@2.12.x...retronym:ticket/10081 Not sure if that changes semantics at all (ie, if any programs have fewer members in the implicit scope after this change). |
Julien Richard-Foy (julienrf) said: |
@SethTisue said: |
Julien Richard-Foy (julienrf) said: |
@lrytz said (edited on Mar 16, 2017 8:53:57 AM UTC): |
@lrytz said: |
When the implicit scope is constructed an initial pruning phase attempts to discard implicit members which it is believed would later be rejected as ambiguous. Members of a companion are discarded if they can be reached via more than one prefix, on the assumption that being visible via two or more paths means that the multiple values must conflict with one another. However, this does not take into account the possibility that the implicit members might depend on the prefix in a way which renders them non-ambiguous. This scenario is illustrated in scala/bug#4947 and scala/bug#5340. This PR address that by only pruning implicits which are independent of the prefix. Whilst this PR tries to stay as close as possible to the current behaviour, I believe that it would be desirable to drop the early pruning of even the prefix-independent implicits. If we do that then we get improved error messages reporting ambiguity rather the ambiguous members being silently ignored which leads to otherwise unexplained failures of implicit resolution. For instance in the case of `test/files/neg/t5340.scala` which currently reports, ``` t5340.scala:15: error: type mismatch; found : Quux[MyApp.r.E,MyApp.s.E] required: Int (new Quux[r.E, s.E]): Int // fails due to pre-stripping implicits which ^ one error found ``` we would get the following report, ``` t5340.scala:15: error: type mismatch; found : Quux[MyApp.r.E,MyApp.s.E] required: Int Note that implicit conversions are not applicable because they are ambiguous: both method conv in object E of type [T, U](b: Quux[T,U])Int and method conv in object E of type [T, U](b: Quux[T,U])Int are possible conversion functions from Quux[MyApp.r.E,MyApp.s.E] to Int (new Quux[r.E, s.E]): Int // fails due to pre-stripping implicits which ^ one error found ``` Which is clearly more informative (even if also a little baffling). I think that ambiguity via multiple paths is sufficiently rare that the performance benefits of this early pruning are likely to minimal and not enough to outweigh improved error messages. Because this change can result in a symbol _legitimately_ being revisited, via a different prefix, we need to change the way that the a pruned path is represented. Instead of using empty lists, as introduced in scala#5951 (which fixes scala/bug#10081) we use explicit sentinels to mark that a symbol has been visited at a given prefix yielding no additional implicits. Testing this yielded scala/bug#10425 which appears to be a regression relative to 2.12.x. That's also fixed in this PR.
When the implicit scope is constructed an initial pruning phase attempts to discard implicit members which it is believed would later be rejected as ambiguous. Members of a companion are discarded if they can be reached via more than one prefix, on the assumption that being visible via two or more paths means that the multiple values must conflict with one another. However, this does not take into account the possibility that the implicit members might depend on the prefix in a way which renders them non-ambiguous. This scenario is illustrated in scala/bug#4947 and scala/bug#5340. This PR address that by only pruning implicits which are independent of the prefix. Whilst this PR tries to stay as close as possible to the current behaviour, I believe that it would be desirable to drop the early pruning of even the prefix-independent implicits. If we do that then we get improved error messages reporting ambiguity rather the ambiguous members being silently ignored which leads to otherwise unexplained failures of implicit resolution. For instance in the case of `test/files/neg/t5340.scala` which currently reports, ``` t5340.scala:15: error: type mismatch; found : Quux[MyApp.r.E,MyApp.s.E] required: Int (new Quux[r.E, s.E]): Int // fails due to pre-stripping implicits which ^ one error found ``` we would get the following report, ``` t5340.scala:15: error: type mismatch; found : Quux[MyApp.r.E,MyApp.s.E] required: Int Note that implicit conversions are not applicable because they are ambiguous: both method conv in object E of type [T, U](b: Quux[T,U])Int and method conv in object E of type [T, U](b: Quux[T,U])Int are possible conversion functions from Quux[MyApp.r.E,MyApp.s.E] to Int (new Quux[r.E, s.E]): Int // fails due to pre-stripping implicits which ^ one error found ``` Which is clearly more informative (even if also a little baffling). I think that ambiguity via multiple paths is sufficiently rare that the performance benefits of this early pruning are likely to minimal and not enough to outweigh improved error messages. Because this change can result in a symbol _legitimately_ being revisited, via a different prefix, we need to change the way that the a pruned path is represented. Instead of using empty lists, as introduced in scala#5951 (which fixes scala/bug#10081) we use explicit sentinels to mark that a symbol has been visited at a given prefix yielding no additional implicits. Testing this yielded scala/bug#10425 which appears to be a regression relative to 2.12.x. That's also fixed in this PR.
The following code crashes typer:
A is not essential (any type constructor will do), neither is x (any name lookup in "this" suffices) nor unchecked (any annotation does the trick).
The problem appears to be in Implicits.companionImplicitMap (at least that's where it manifests itself), with an endless recursion between getClassParts and getParts, called with types that appear to be the same but not identical. In the reproduction above, the bts(i) as seen in getClassParts are always:
The text was updated successfully, but these errors were encountered: