Skip to content

Commit da2262c

Browse files
authored
Merge pull request #5628 from dotty-staging/fix-#5527
Fix #5527: Fix companion module for hk opaque type aliases
2 parents 04c7aa1 + e24ea5d commit da2262c

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -991,10 +991,15 @@ object SymDenotations {
991991
*/
992992
final def companionModule(implicit ctx: Context): Symbol =
993993
if (is(Module)) sourceModule
994-
else if (isOpaqueAlias)
995-
info match {
996-
case TypeAlias(TypeRef(prefix: TermRef, _)) => prefix.termSymbol
994+
else if (isOpaqueAlias) {
995+
def reference(tp: Type): TermRef = tp match {
996+
case TypeRef(prefix: TermRef, _) => prefix
997+
case tp: HKTypeLambda => reference(tp.resType)
998+
case tp: AppliedType => reference(tp.tycon)
997999
}
1000+
val TypeAlias(alias) = info
1001+
reference(alias).termSymbol
1002+
}
9981003
else registeredCompanion.sourceModule
9991004

10001005
private def companionType(implicit ctx: Context): Symbol =

tests/run/i5527.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
trait Contravariant[F[_]] {
2+
def contramap[A, B](fa: F[A])(f: B => A): F[B]
3+
}
4+
5+
object Library {
6+
7+
opaque type Set[A] = A => Boolean
8+
9+
object Set {
10+
def singleton[A](a: A): Set[A] =
11+
_ == a
12+
13+
implicit class SetOps[A](private val set: Set[A]) extends AnyVal {
14+
def contains(a: A): Boolean =
15+
set(a)
16+
}
17+
18+
implicit val setContravariant: Contravariant[Set] = new Contravariant[Set] {
19+
def contramap[A, B](fa: Set[A])(f: B => A): Set[B] =
20+
b => fa(f(b))
21+
}
22+
}
23+
}
24+
25+
object Test extends App {
26+
import Library._
27+
//import Library.Set.setContravariant if this is imported the program will run correctly
28+
29+
val F = implicitly[Contravariant[Set]]
30+
31+
val one = Set.singleton(1)
32+
val char = F.contramap(one)((s: String) => s.length)
33+
assert(char.contains("a"))
34+
assert(!char.contains("ab"))
35+
}

0 commit comments

Comments
 (0)