Skip to content

Conversation

@retronym
Copy link
Member

@retronym retronym commented Nov 5, 2020

Make annotation typechecking lazier

Now that Typer.stabilize ends up checking for @uncheckedStable annotations to support defs's as stable paths, new opportunities arise for cyclic errors.

This PR reduces the likelihood of cycles by typechecking the only core of an annotation (not the full application to the annotation arguments) to determine its type symbol.

pos/unchecked-stable-cyclic-error.scala test case started to fail since #8338 with:

|-- object Test BYVALmode-EXPRmode (site: package <empty>)
|    |-- super APPSELmode-EXPRmode-POLYmode-QUALmode (silent: <init> in Test)
|    |    |-- this EXPRmode (silent: <init> in Test)
|    |    |    \-> Test.type
|    |    \-> Test.type
|    |-- def foo BYVALmode-EXPRmode (site: object Test)
|    |    |-- attr EXPRmode (site: method foo in Test)
|    |    |    |-- Int TYPEmode (site: method attr in Test)
|    |    |    |    \-> Int
|    |    |    |-- new anno APPSELmode-BYVALmode-EXPRmode-FUNmode-POLYmode (site: object Test)
|    |    |    |    |-- new anno APPSELmode-EXPRmode-POLYmode-QUALmode (site: object Test)
|    |    |    |    |    |-- anno FUNmode-TYPEmode (site: object Test)
|    |    |    |    |    |    \-> anno
|    |    |    |    |    \-> anno
|    |    |    |    \-> (a: Any): anno
|    |    |    |-- (a: Any): anno : pt=anno EXPRmode (site: value <local Test> in Test)
|    |    |    |    |-- foo : pt=Any BYVALmode-EXPRmode (site: value <local Test> in Test)
|    |    |    |    |    caught scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving method foo: while typing foo
/Users/jz/code/scala/sandbox/test.scala:7: error: recursive method foo needs result type
  @anno(foo) def attr: Int = foo
        ^
|    |    |    |    \-> anno

Another variant, pos/annotation-cycle.scala, fails only on 2.12.x (after the backport of #8338). Backporting this fix makes that test start passing on 2.12.x.

References scala/bug#12216 (which will be fixed after this is backported to 2.12.x)

Fixes scala/bug#11870

@scala-jenkins scala-jenkins added this to the 2.13.5 milestone Nov 5, 2020
@retronym retronym force-pushed the topic/extra-lazy-annotation-info branch 3 times, most recently from 2abc534 to db2b8f6 Compare November 5, 2020 03:10
@retronym retronym requested a review from lrytz November 5, 2020 03:11
@retronym retronym force-pushed the topic/extra-lazy-annotation-info branch from db2b8f6 to a61e4fe Compare November 5, 2020 03:12
Now that `Typer.stabilize` ends up checking for `@uncheckedStable`
annotations to support defs's as stable paths, new opportunities
arise for cyclic errors.

This PR reduces the likelihood of cycles by typechecking the only core of
an annotation (_not_ the full application to the annotation arguments)
to determine its type symbol.

pos/unchecked-stable-cyclic-error.scala test case started to fail
since scala#8338 with:

```
|-- object Test BYVALmode-EXPRmode (site: package <empty>)
|    |-- super APPSELmode-EXPRmode-POLYmode-QUALmode (silent: <init> in Test)
|    |    |-- this EXPRmode (silent: <init> in Test)
|    |    |    \-> Test.type
|    |    \-> Test.type
|    |-- def foo BYVALmode-EXPRmode (site: object Test)
|    |    |-- attr EXPRmode (site: method foo in Test)
|    |    |    |-- Int TYPEmode (site: method attr in Test)
|    |    |    |    \-> Int
|    |    |    |-- new anno APPSELmode-BYVALmode-EXPRmode-FUNmode-POLYmode (site: object Test)
|    |    |    |    |-- new anno APPSELmode-EXPRmode-POLYmode-QUALmode (site: object Test)
|    |    |    |    |    |-- anno FUNmode-TYPEmode (site: object Test)
|    |    |    |    |    |    \-> anno
|    |    |    |    |    \-> anno
|    |    |    |    \-> (a: Any): anno
|    |    |    |-- (a: Any): anno : pt=anno EXPRmode (site: value <local Test> in Test)
|    |    |    |    |-- foo : pt=Any BYVALmode-EXPRmode (site: value <local Test> in Test)
|    |    |    |    |    caught scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving method foo: while typing foo
/Users/jz/code/scala/sandbox/test.scala:7: error: recursive method foo needs result type
  @anno(foo) def attr: Int = foo
        ^
|    |    |    |    \-> anno
```

Another variant, pos/annotation-cycle.scala, fails only on 2.12.x
(after the backport of scala#8338). Backporting this fix makes that test
start passing on 2.12.x.
@retronym retronym force-pushed the topic/extra-lazy-annotation-info branch from a61e4fe to 9d9635d Compare November 5, 2020 06:04
@lrytz
Copy link
Member

lrytz commented Nov 5, 2020

@retronym see also #9144 where I had some reservations about building more stuff on top of LazyAnnotationInfo - though your patch here looks small enough. Can you add the test case for scala/bug#11870 from there?

@retronym
Copy link
Member Author

retronym commented Nov 5, 2020

@lrytz Test case added.

@retronym retronym force-pushed the topic/extra-lazy-annotation-info branch from c8d27c2 to 1d5c0ad Compare November 5, 2020 23:44
Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

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

LGTM otherwise. The main differences to #9144 are:

  • Here we have ExtraLazyAnnotationInfo extends LazyAnnotationInfo, where the other PR did QualifierTypedAnnotationInfo extends AnnotationInfo. This requires fewer overrides.
  • Here, typing the qualifier / annotation symbol is lazy, in the other PR it's done eagerly during Namer.

@retronym retronym force-pushed the topic/extra-lazy-annotation-info branch from 1d5c0ad to 2408bad Compare November 9, 2020 06:09
@retronym retronym modified the milestones: 2.13.5, 2.13.4 Nov 9, 2020
@lrytz lrytz merged commit a7d63b9 into scala:2.13.x Nov 9, 2020
retronym added a commit to retronym/scala that referenced this pull request Nov 10, 2020
Now that `Typer.stabilize` ends up checking for `@uncheckedStable`
annotations to support defs's as stable paths, new opportunities
arise for cyclic errors.

This PR reduces the likelihood of cycles by typechecking the only core of
an annotation (_not_ the full application to the annotation arguments)
to determine its type symbol.

pos/unchecked-stable-cyclic-error.scala test case started to fail
since scala#8338 with:

```
|-- object Test BYVALmode-EXPRmode (site: package <empty>)
|    |-- super APPSELmode-EXPRmode-POLYmode-QUALmode (silent: <init> in Test)
|    |    |-- this EXPRmode (silent: <init> in Test)
|    |    |    \-> Test.type
|    |    \-> Test.type
|    |-- def foo BYVALmode-EXPRmode (site: object Test)
|    |    |-- attr EXPRmode (site: method foo in Test)
|    |    |    |-- Int TYPEmode (site: method attr in Test)
|    |    |    |    \-> Int
|    |    |    |-- new anno APPSELmode-BYVALmode-EXPRmode-FUNmode-POLYmode (site: object Test)
|    |    |    |    |-- new anno APPSELmode-EXPRmode-POLYmode-QUALmode (site: object Test)
|    |    |    |    |    |-- anno FUNmode-TYPEmode (site: object Test)
|    |    |    |    |    |    \-> anno
|    |    |    |    |    \-> anno
|    |    |    |    \-> (a: Any): anno
|    |    |    |-- (a: Any): anno : pt=anno EXPRmode (site: value <local Test> in Test)
|    |    |    |    |-- foo : pt=Any BYVALmode-EXPRmode (site: value <local Test> in Test)
|    |    |    |    |    caught scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving method foo: while typing foo
/Users/jz/code/scala/sandbox/test.scala:7: error: recursive method foo needs result type
  @anno(foo) def attr: Int = foo
        ^
|    |    |    |    \-> anno
```

Another variant, pos/annotation-cycle.scala, fails only on 2.12.x
(after the backport of scala#8338). Backporting this fix makes that test
start passing on 2.12.x.

Backports scala#9302
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.

2.13.1 scalac StackOverflowError when annotation argument references the annottee

3 participants