@@ -105,7 +105,8 @@ class CheckRealizable(implicit ctx: Context) {
105
105
/** `Realizable` if `tp` has good bounds, a `HasProblem...` instance
106
106
* pointing to a bad bounds member otherwise. "Has good bounds" means:
107
107
*
108
- * - all type members have good bounds
108
+ * - all type members have good bounds (except for opaque helpers)
109
+ * - all refinements of the underlying type have good bounds (except for opaque companions)
109
110
* - all base types are class types, and if their arguments are wildcards
110
111
* they have good bounds.
111
112
* - base types do not appear in multiple instances with different arguments.
@@ -114,10 +115,15 @@ class CheckRealizable(implicit ctx: Context) {
114
115
*/
115
116
private def boundsRealizability (tp : Type ) = {
116
117
118
+ def isOpaqueCompanionThis = tp match {
119
+ case tp : ThisType => tp.cls.isOpaqueCompanion
120
+ case _ => false
121
+ }
122
+
117
123
val memberProblems =
118
124
for {
119
125
mbr <- tp.nonClassTypeMembers
120
- if ! (mbr.info.loBound <:< mbr.info.hiBound)
126
+ if ! (mbr.info.loBound <:< mbr.info.hiBound) && ! mbr.symbol.isOpaqueHelper
121
127
}
122
128
yield new HasProblemBounds (mbr.name, mbr.info)
123
129
@@ -126,7 +132,7 @@ class CheckRealizable(implicit ctx: Context) {
126
132
name <- refinedNames(tp)
127
133
if (name.isTypeName)
128
134
mbr <- tp.member(name).alternatives
129
- if ! (mbr.info.loBound <:< mbr.info.hiBound)
135
+ if ! (mbr.info.loBound <:< mbr.info.hiBound) && ! isOpaqueCompanionThis
130
136
}
131
137
yield new HasProblemBounds (name, mbr.info)
132
138
0 commit comments