Skip to content

[Scala3] Add support for handling unapplys in NamingPhase#5198

Merged
adkian-sifive merged 13 commits intomainfrom
adkian-sifive/scala3-namingphase-support-unapply
Feb 26, 2026
Merged

[Scala3] Add support for handling unapplys in NamingPhase#5198
adkian-sifive merged 13 commits intomainfrom
adkian-sifive/scala3-namingphase-support-unapply

Conversation

@adkian-sifive
Copy link
Copy Markdown
Contributor

Missing feature from #4889

Tried to keep the implementation as logically similar as possible to the Scala 2 version

Contributor Checklist

  • Did you add Scaladoc to every public function/method?
  • Did you add at least one test demonstrating the PR?
  • Did you delete any extraneous printlns/debugging code?
  • Did you specify the type of improvement?
  • Did you add appropriate documentation in docs/src?
  • Did you request a desired merge strategy?
  • Did you add text to be included in the Release Notes for this change?

Type of Improvement

  • Internal or build-related (includes code refactoring/cleanup)

Desired Merge Strategy

  • Squash: The PR will be squashed and merged (choose this if you have no preference).

Release Notes

NamingPhase updated to handle unapplys similar to Scala 2

Reviewer Checklist (only modified by reviewer)

  • Did you add the appropriate labels? (Select the most appropriate one based on the "Type of Improvement")
  • Did you mark the proper milestone (Bug fix: 3.6.x, 5.x, or 6.x depending on impact, API modification or big change: 7.0)?
  • Did you review?
  • Did you check whether all relevant Contributor checkboxes have been checked?
  • Did you do one of the following when ready to merge:
    • Squash: You/ the contributor Enable auto-merge (squash) and clean up the commit message.
    • Merge: Ensure that contributor has cleaned up their commit history, then merge with Create a merge commit.

@adkian-sifive adkian-sifive added the Scala 3 Changes related to upgrading to Scala 3 label Feb 6, 2026
}

// For each synthetic tuple val, find the subsequent selecting ValDefs
syntheticTupleVals.foreach { case (syntheticName, arity) =>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

refactor this handling

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm unresolving this because I think this should be cleaned up.

Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/PluginHelpers.scala Outdated
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala Outdated
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala
}.toMap

// Pattern to match tuple element accessors like _1, _2, etc.
val TupleIndex = "_([0-9]+)".r
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I do not want regex matching in performance critical places like compiler plugins, can we do this a different way?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some ideas--Name has some methods that might be useful, like is(kind: NameKind). Alternatively, if we know the qual is of type tuple and that the name is the right kind of name (probably isTermName? or one of the name kinds), then we can potentially extract the number directly, or just .tail the String if we're sure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

tuple accessor names are predictable, so we can just check for tuple types and extract accessor names manually based on the pattern. i'll try it out

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If there is an actual flag or type in the AST that indicates a tuple extraction that would be better though. It is not wise to rely on the names being predictable in case that predictability changes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also we want to distinguish it from user code that might look similar, e.g. what happens if I write this:

val foo = returnsATuple(...)
val bar = foo._1

If the plugin matches that, it's a bad thing.

Here's why, what if someone wrote this?

val foo @ (fizz, _) = returnsATuple(...)
// then later for some reason:
val bar = foo._1

It's important that we actually distinguish what is an unapply and not just match the pattern of extractor names.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah that's exactly the case i'm checking. this is the issue with unapplys in scala 3 in general though, iirc there's no way to tell between unapplys and tuple destructuring

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah that's exactly the case i'm checking. this is the issue with unapplys in scala 3 in general though, iirc there's no way to tell between unapplys and tuple destructuring

Is that true in Scala 3 in general or is it true because we're running as a later phase?

Also, what about Flags like Synthetic, Case, CaseAccessor?

Copy link
Copy Markdown
Contributor Author

@adkian-sifive adkian-sifive Feb 18, 2026

Choose a reason for hiding this comment

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

Pretty sure this was still an issue in the original naming PR and we were running earlier then

Regarding flags, these are used in helpers to filter stuff but these same flags are used in, for example, Match-based unapplys so on their own won't help here

Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala Outdated
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala Outdated
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/PluginHelpers.scala
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/PluginHelpers.scala Outdated
Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala Outdated
Copy link
Copy Markdown
Contributor

@jackkoenig jackkoenig left a comment

Choose a reason for hiding this comment

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

I'm approving this to unblock moving tests over, but I still want several improvements, see comments but certainly including:

  1. Do collectUnapplyNames in a single traversal of the statements
  2. Remove regex in collectUnapplyNames
  3. Clean up syntheicTupleValues stuff
  4. Get rid of String-y stuff in okVal
  5. Use built-ins for isTupleType and probably tupleArity

}

// For each synthetic tuple val, find the subsequent selecting ValDefs
syntheticTupleVals.foreach { case (syntheticName, arity) =>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm unresolving this because I think this should be cleaned up.

Comment thread plugin/src/main/scala-3/chisel3/internal/plugin/NamingPhase.scala Outdated
@adkian-sifive adkian-sifive merged commit 2a2a65b into main Feb 26, 2026
27 checks passed
@adkian-sifive adkian-sifive deleted the adkian-sifive/scala3-namingphase-support-unapply branch February 26, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scala 3 Changes related to upgrading to Scala 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants