Tracking down a weird case where two schemas that obviously shouldn't be equal were being treated as equal in our schema registry. Boiled it down to Schema.strictEquality on Tuple2.
Schema.Tuple2(Schema[String], Schema[Int]) is reported as equal to Schema.Tuple2(Schema[String], Schema[Boolean]). The right side is never compared between the two schemas.
Reproducer (scala-cli):
//> using scala 3.8.3
//> using dep dev.zio::zio-schema:1.8.5
//> using dep dev.zio::zio-schema-derivation:1.8.5
import zio.schema.*
@main def repro(): Unit =
val tuple1 = Schema.Tuple2(Schema[String], Schema[Int])
val tuple2 = Schema.Tuple2(Schema[String], Schema[Boolean])
val eq = Schema.strictEquality.equal(
tuple1.asInstanceOf[Schema[Any]], tuple2.asInstanceOf[Schema[Any]])
println(s"Schema[(String,Int)] === Schema[(String,Boolean)]: $eq")
Output:
Schema[(String,Int)] === Schema[(String,Boolean)]: true
Looks like a copy-paste slip in the Tuple2 case:
|
case (lTuple: Schema.Tuple2[_, _], rTuple: Schema.Tuple2[_, _]) => |
|
lTuple.annotations == rTuple.annotations && |
|
lTuple.left === rTuple.left && |
|
rTuple.right === rTuple.right |
case (lTuple: Schema.Tuple2[_, _], rTuple: Schema.Tuple2[_, _]) =>
lTuple.annotations == rTuple.annotations &&
lTuple.left === rTuple.left &&
rTuple.right === rTuple.right // <-- compares rTuple.right with itself
The next case (Either) uses lEither.right === rEither.right, which is what this should be — lTuple.right === rTuple.right. Happy to send a one-line PR.
Tracking down a weird case where two schemas that obviously shouldn't be equal were being treated as equal in our schema registry. Boiled it down to
Schema.strictEqualityonTuple2.Schema.Tuple2(Schema[String], Schema[Int])is reported as equal toSchema.Tuple2(Schema[String], Schema[Boolean]). The right side is never compared between the two schemas.Reproducer (scala-cli):
Output:
Looks like a copy-paste slip in the
Tuple2case:zio-schema/zio-schema/shared/src/main/scala/zio/schema/SchemaEquality.scala
Lines 65 to 68 in f32240d
The next case (
Either) useslEither.right === rEither.right, which is what this should be —lTuple.right === rTuple.right. Happy to send a one-line PR.