OpenAPI.Parameter overrides equals on (name, in) but inherits the case-class hashCode (uses all fields)
**Describe the bug**
`endpoint.openapi.OpenAPI.Parameter` is a case class with a custom `equals` that returns `true` whenever `(name, in)` match — likely for OpenAPI spec deduplication. There's no matching `hashCode` override, so the auto-generated case-class `hashCode` still mixes in every field. Two `Parameter`s that compare as equal frequently get different hash codes, which silently breaks `Set`, `Map`, `distinct`, etc.
Source:
https://github.com/zio/zio-http/blob/02e1b6b60fc26794cec053d4b0690a64f3c39a9f/zio-http/shared/src/main/scala/zio/http/endpoint/openapi/OpenAPI.scala#L686-L703
```scala
final case class Parameter(
name: String,
in: String,
description: Option[Doc],
required: Option[Boolean] = None,
deprecated: Option[Boolean] = None,
schema: Option[ReferenceOr[JsonSchema]],
explode: Option[Boolean] = None,
examples: Map[String, ReferenceOr[Example]] = Map.empty,
allowReserved: Option[Boolean],
style: Option[String],
content: Option[(String, MediaType)],
) {
override def equals(obj: Any): Boolean = obj match {
case p: Parameter if name == p.name && in == p.in => true
case _ => false
}
// no hashCode override
}
```
**To Reproduce**
```scala
val p1 = Parameter("id", "query", Some(Doc("first")), schema = None, allowReserved = None, style = None, content = None)
val p2 = Parameter("id", "query", Some(Doc("second")), schema = None, allowReserved = None, style = None, content = None)
p1 == p2 // true
p1.hashCode == p2.hashCode // typically false
Set(p1, p2).size // 2 — but they were "equal", so Sets/Maps misbehave
```
**Expected behaviour**
Add a matching `hashCode`:
```scala
override def hashCode(): Int = (name, in).hashCode
```
(Worth a separate look at whether `equals` should really collapse parameters with different schemas to "equal" — but at minimum the contract should hold.) Happy to PR.
0 条评论