Skip to content
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

Replace symbol traversal with tree traversal when finding top level experimentals #21827

Merged
merged 3 commits into from
Nov 14, 2024

Conversation

jchyb
Copy link
Contributor

@jchyb jchyb commented Oct 22, 2024

Fixes #21802, as suggested by #21802 (comment)

As an aside, in #20409 (which included the changes that are being addressed here) a sbt-scripted test for a crash was added - however I was not able to make that error reproduce, even when hardcoding older scala version there (3.5.0-RC1-bin-20240515-177b489-NIGHTLY). I was able to reproduce the error in a separate sbt build with the same scala version (so there is probably some difference in how things are loaded between a sbt-scripted test and a regular sbt build). No idea how that could be fixed, but I did test those now changes here in that separate repository to confirm there is no regression for that test.

@jchyb jchyb marked this pull request as ready for review October 23, 2024 10:19
@jchyb jchyb requested a review from smarter October 23, 2024 10:19
else if isNonExperimentalTopLevelDefinition(sym) then
sym :: Nil
else Nil
def nonExperimentalTopLevelDefs(): Iterator[Symbol] =
Copy link
Member

Choose a reason for hiding this comment

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

I see this isn't new, but I would prefer to return the List here instead of an Iterator, because Iterator is too easy to misuse (e.g. printing its content to debug it will break it), and we can just directly iterate on the List anyway.

Comment on lines 816 to 817
case defdef: tpd.DefDef => addIfExperimental(defdef.symbol)
case valdef: tpd.ValDef => addIfExperimental(valdef.symbol)
Copy link
Member

Choose a reason for hiding this comment

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

Can be:

Suggested change
case defdef: tpd.DefDef => addIfExperimental(defdef.symbol)
case valdef: tpd.ValDef => addIfExperimental(valdef.symbol)
case mdef: tpd.ValOrDefDef => addIfExperimental(mdef.symbol)

case defdef: tpd.DefDef => addIfExperimental(defdef.symbol)
case valdef: tpd.ValDef => addIfExperimental(valdef.symbol)
case typeDef @ tpd.TypeDef(_, temp: Template) if typeDef.symbol.isPackageObject =>
super.apply(x, temp.body)
Copy link
Member

Choose a reason for hiding this comment

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

Why super.apply? Shouldn't this be just apply to pick up top-level defs?

case valdef: tpd.ValDef => addIfExperimental(valdef.symbol)
case typeDef @ tpd.TypeDef(_, temp: Template) if typeDef.symbol.isPackageObject =>
super.apply(x, temp.body)
case typeDef @ tpd.TypeDef(_, Template(_, _, _, _)) => addIfExperimental(typeDef.symbol)
Copy link
Member

Choose a reason for hiding this comment

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

What about a TypeDef which does not have a Template (type alias / abstract type) ? They should also be marked experimental.
I think that there should be a case after the two TypeDef(_, Template(...)) cases like:

            case mdef: tpd.MemberfDef => addIfExperimental(mdef.symbol)

and then you can remove the Val/DefDef cases too.

@smarter
Copy link
Member

smarter commented Oct 23, 2024

Since I'm not sure we test this, it'd be good to pick a random project and check that if we add the -experimental flag, we generate the same tasty content before and after this change, to make sure we're not missing anything.

@dwijnand dwijnand changed the title Replace symbol travelsal with tree traversal when finding top level experimentals Replace symbol traversal with tree traversal when finding top level experimentals Oct 25, 2024
@jchyb
Copy link
Contributor Author

jchyb commented Oct 28, 2024

Thank you for the review and suggestions! I have applied review comments and prepared and run a tasty output comparison script between the output using the previous implementation and a new one. I've run it on the output of gears. I did find one inconsistency this way - for package objects a ValDef with that symbol can be produced which in the previous implementation would not be annotated, and in the new one would, so I removed that (with the additional case with ValDef if isPackageObject)

@jchyb jchyb requested a review from smarter October 28, 2024 13:53
@jchyb jchyb assigned smarter and unassigned jchyb Oct 28, 2024
@jchyb
Copy link
Contributor Author

jchyb commented Nov 14, 2024

@smarter Just realized I forgot to tag you in the message above. Let me know if you would like me to test this PR somewhere else too, or if we are good to go

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

for package objects a ValDef with that symbol can be produced which in the previous implementation would not be annotated, and in the new one would, so I removed that (with the additional case with ValDef if isPackageObject)

Thanks for checking this. It sounds like this was actually a bug in the old implementation and the new behavior is better? So I think we don't need the additional case.

@smarter smarter assigned jchyb and unassigned smarter Nov 14, 2024
case tpd.PackageDef(_, contents) => apply(x, contents)
case typeDef @ tpd.TypeDef(_, temp: Template) if typeDef.symbol.isPackageObject =>
apply(x, temp.body)
case vdef: tpd.ValDef if vdef.symbol.isPackageObject => x // ValDef(new PackageObject)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smarter Just to confirm - we want to annotate those ValDefs containing package objects then? I'm hesitant since I don't think that is possible to do by annotating by hand with @experimental (it seems we can't annotate package objects at all), but on the other hand this is indeed a top-level def, which is why I'm asking

Copy link
Member

Choose a reason for hiding this comment

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

You can annotate a packable object defined as object `package` but for those generated for top-level defs there isn't a way to do it indeed. For those it might not matter since you cannot extend them, but it seems more uniform to treat everything the same way and therefore to also annotate them here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure! Thank you for the review!

@jchyb jchyb enabled auto-merge (squash) November 14, 2024 13:53
@jchyb jchyb merged commit 11d4295 into scala:main Nov 14, 2024
29 checks passed
@jchyb jchyb deleted the fix-21802 branch November 14, 2024 15:32
KacperFKorban pushed a commit to dotty-staging/dotty that referenced this pull request Nov 20, 2024
…xperimentals (scala#21827)

Aims to fix stale symbol errors caused by the symbol traversal after suspending by a macro
@WojciechMazur WojciechMazur added this to the 3.6.3 milestone Nov 25, 2024
KacperFKorban pushed a commit to dotty-staging/dotty that referenced this pull request Nov 29, 2024
…xperimentals (scala#21827)

Aims to fix stale symbol errors caused by the symbol traversal after suspending by a macro
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.

Enabling -experimental introduces compiler crash in transparent inline macro
3 participants