@@ -2130,6 +2130,89 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
2130
2130
true
2131
2131
}
2132
2132
}
2133
+
2134
+ def notIntersection (tp : Type , pt : Type ): Boolean =
2135
+ trace(i " notIntersection( $tp, $pt) " )
2136
+ {
2137
+ import typer .Inferencing ._
2138
+
2139
+ def incompatibleClasses : Boolean = {
2140
+ import Flags ._
2141
+ val tpClassSym = tp.classSymbol
2142
+ val ptClassSym = pt.classSymbol
2143
+ println(i " tpClassSym= $tpClassSym, fin= ${tpClassSym.is(Final )}" )
2144
+ println(i " ptClassSym= $ptClassSym, fin= ${ptClassSym.is(Final )}" )
2145
+ tpClassSym.exists && ptClassSym.exists && {
2146
+ println(" here" )
2147
+ if (tpClassSym.is(Final )) ! tpClassSym.derivesFrom(ptClassSym)
2148
+ else if (ptClassSym.is(Final )) ! ptClassSym.derivesFrom(tpClassSym)
2149
+ else if (! tpClassSym.is(Flags .Trait ) && ! ptClassSym.is(Flags .Trait ))
2150
+ ! (tpClassSym.derivesFrom(ptClassSym) || ptClassSym.derivesFrom(tpClassSym))
2151
+ else false
2152
+ }
2153
+ }
2154
+
2155
+ def loop (tp : Type ): Boolean =
2156
+ trace.force(i " loop( $tp) // ${tp.toString}" )
2157
+ {
2158
+ if (constrainPatternType(pt, tp)) true
2159
+ else if (incompatibleClasses) {
2160
+ // println("incompatible classes")
2161
+ false
2162
+ }
2163
+ else tp match {
2164
+ case _ : ConstantType =>
2165
+ // constants cannot possibly intersect with types that aren't their supertypes
2166
+ false
2167
+ case tp : SingletonType => loop(tp.underlying)
2168
+ case tp : TypeRef if tp.symbol.isClass => loop(tp.firstParent)
2169
+ case tp @ AppliedType (tycon : TypeRef , _) if tycon.symbol.isClass =>
2170
+ val ptClassSym = pt.classSymbol
2171
+ def firstParentSharedWithPt (tp : Type , tpClassSym : ClassSymbol ): Symbol =
2172
+ trace.force(i " f( $tp) " )
2173
+ {
2174
+ var parents = tpClassSym.info.parents
2175
+ // println(i"parents of $tpClassSym = $parents%, %")
2176
+ parents match {
2177
+ case first :: rest =>
2178
+ if (first.classSymbol == defn.ObjectClass ) parents = rest
2179
+ case _ => ;
2180
+ }
2181
+ parents match {
2182
+ case first :: _ =>
2183
+ val firstClassSym = first.classSymbol.asClass
2184
+ val res = if (ptClassSym.derivesFrom(firstClassSym)) firstClassSym
2185
+ else firstParentSharedWithPt(first, firstClassSym)
2186
+ res
2187
+ case _ => NoSymbol
2188
+ }
2189
+ }
2190
+ val sym = firstParentSharedWithPt(tycon, tycon.symbol.asClass)
2191
+ // println(i"sym=$sym ; tyconsym=${tycon.symbol}")
2192
+ if (! sym.exists) true
2193
+ else ! (sym == tycon.symbol) && loop(tp.baseType(sym))
2194
+ case tp : TypeProxy =>
2195
+ loop(tp.superType)
2196
+ case _ => false
2197
+ }
2198
+ }
2199
+
2200
+ pt match {
2201
+ case AndType (pt1, pt2) =>
2202
+ notIntersection(tp, pt1) && notIntersection(tp, pt2)
2203
+ case OrType (pt1, pt2) =>
2204
+ either(notIntersection(tp, pt1), notIntersection(tp, pt2))
2205
+ case _ =>
2206
+ tp match {
2207
+ case OrType (tp1, tp2) =>
2208
+ either(notIntersection(tp1, pt), notIntersection(tp2, pt))
2209
+ case AndType (tp1, tp2) =>
2210
+ notIntersection(tp1, pt) && notIntersection(tp2, pt)
2211
+ case _ =>
2212
+ loop(tp)
2213
+ }
2214
+ }
2215
+ }
2133
2216
}
2134
2217
2135
2218
object TypeComparer {
0 commit comments