Skip to content

Commit 04c7aa1

Browse files
authored
Merge pull request #5624 from dotty-staging/fix-#5546
Fix #5546: Disallow comparing opaque types under -language:strictEqua…
2 parents b874ed4 + 8e77ed8 commit 04c7aa1

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,11 +831,13 @@ trait Implicits { self: Typer =>
831831
(other ne NoType) && !other.derivesFrom(defn.AnyValClass)
832832
}
833833

834+
// Map all non-opaque abstract types to their upper bound.
835+
// This is done to check whether such types might plausibly be comparable to each other.
834836
val lift = new TypeMap {
835837
def apply(t: Type): Type = t match {
836838
case t: TypeRef =>
837839
t.info match {
838-
case TypeBounds(lo, hi) if lo ne hi => apply(hi)
840+
case TypeBounds(lo, hi) if lo.ne(hi) && !t.symbol.is(Opaque) => apply(hi)
839841
case _ => t
840842
}
841843
case t: RefinedType =>

tests/neg/i5546.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import language.strictEquality
2+
3+
object O {
4+
5+
opaque type Meters = Double
6+
object Meters {
7+
def apply(d: Double): Meters = d
8+
val m: Meters = 1.0
9+
assert(m == 1.0) // OK
10+
}
11+
implicit def eqM: Eq[Meters, Meters] = Eq
12+
13+
opaque type Feet = Double
14+
object Feet { def apply(d: Double): Feet = d }
15+
implicit def eqF: Eq[Feet, Feet] = Eq
16+
17+
def main(args: Array[String]): Unit = {
18+
println(Feet(3) == Meters(3)) // error: cannot compare
19+
println(Feet(3) == 3.0) // error: cannot compare
20+
}
21+
}

0 commit comments

Comments
 (0)