Fix #4132: Make PathCodec.Annotated equals symmetric with matching hashCode - #4170
Fix #4132: Make PathCodec.Annotated equals symmetric with matching hashCode#4170987Nabil wants to merge 1 commit into
Conversation
…shCode Annotated's equals delegated directly to the inner codec (asymmetric, annotations ignored) while the case-class hashCode included the annotations Chunk. Violates equals/hashCode contract. Fixed to symmetrically compare Annotated instances by their codec only (matching hashCode). Annotations remain metadata. Fixes #4132
✅ Deploy Preview for zio-http ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Grok via xAI seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR fixes incorrect equals/hashCode behavior for PathCodec.Annotated, ensuring equality is symmetric and that hash-based collections behave consistently by treating annotations as metadata only.
Changes:
- Make
PathCodec.Annotated.equalssymmetric by comparing only underlyingcodecwhen both sides areAnnotated. - Override
PathCodec.Annotated.hashCodeto align withequalsby delegating tocodec.hashCode.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| override def equals(that: Any): Boolean = that match { | ||
| case o: Annotated[_] => codec.equals(o.codec) | ||
| case _ => false | ||
| } |
Fixes #4132.\n\n## Summary\n
PathCodec.Annotated(the public wrapper from??/example/annotate, used for docs + OpenAPI) had:\nscala\noverride def equals(that: Any): Boolean = codec.equals(that)\n\nThis was asymmetric, ignored annotations, and used the default case-classhashCode(which includes the annotationsChunk).\n\nAll core operations peelAnnotatedcorrectly, but public==,RoutePatternequality, and hash-based collections were broken.\n\n## Fix\nscala\noverride def equals(that: Any): Boolean = that match {\n case o: Annotated[_] => codec.equals(o.codec)\n case _ => false\n}\n\noverride def hashCode(): Int = codec.hashCode\n\nAnnotations stay as pure metadata (consistent with how everything else handles them).\n\n(Verified on main + full call-site analysis.)