@@ -298,16 +298,14 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
298
298
// Since projections of types don't include null, intersection with null is empty.
299
299
return Empty
300
300
}
301
- val and = AndType (tp1, tp2)
302
- // Then, no leaf of the and-type tree `and` is a subtype of `and`.
303
- val res = inhabited(and)
301
+ val res = ctx.typeComparer.intersecting(tp1, tp2)
304
302
305
- debug.println(s " atomic intersection: ${and .show} = ${res}" )
303
+ debug.println(s " atomic intersection: ${AndType (tp1, tp2) .show} = ${res}" )
306
304
307
305
if (! res) Empty
308
306
else if (tp1.isSingleton) Typ (tp1, true )
309
307
else if (tp2.isSingleton) Typ (tp2, true )
310
- else Typ (and , true )
308
+ else Typ (AndType (tp1, tp2) , true )
311
309
}
312
310
313
311
/** Whether the extractor is irrefutable */
@@ -516,101 +514,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
516
514
517
515
val childTp = if (child.isTerm) child.termRef else child.typeRef
518
516
519
- val resTp = instantiate(childTp, parent)(ctx.fresh.setNewTyperState())
520
-
521
- if (! resTp.exists || ! inhabited(resTp)) {
522
- debug.println(s " [refine] unqualified child ousted: ${childTp.show} !< ${parent.show}" )
523
- NoType
524
- }
525
- else {
526
- debug.println(s " $child instantiated ------> $resTp" )
527
- resTp.dealias
528
- }
529
- }
530
-
531
- /** Can this type be inhabited by a value?
532
- *
533
- * Check is based on the following facts:
534
- *
535
- * - single inheritance of classes
536
- * - final class cannot be extended
537
- * - intersection of a singleton type with another irrelevant type (patmat/i3574.scala)
538
- *
539
- */
540
- def inhabited (tp : Type )(implicit ctx : Context ): Boolean = {
541
- // convert top-level type shape into "conjunctive normal form"
542
- def cnf (tp : Type ): Type = tp match {
543
- case AndType (OrType (l, r), tp) =>
544
- OrType (cnf(AndType (l, tp)), cnf(AndType (r, tp)))
545
- case AndType (tp, o : OrType ) =>
546
- cnf(AndType (o, tp))
547
- case AndType (l, r) =>
548
- val l1 = cnf(l)
549
- val r1 = cnf(r)
550
- if (l1.ne(l) || r1.ne(r)) cnf(AndType (l1, r1))
551
- else AndType (l1, r1)
552
- case OrType (l, r) =>
553
- OrType (cnf(l), cnf(r))
554
- case tp @ RefinedType (OrType (tp1, tp2), _, _) =>
555
- OrType (
556
- cnf(tp.derivedRefinedType(tp1, refinedName = tp.refinedName, refinedInfo = tp.refinedInfo)),
557
- cnf(tp.derivedRefinedType(tp2, refinedName = tp.refinedName, refinedInfo = tp.refinedInfo))
558
- )
559
- case tp : RefinedType =>
560
- val parent1 = cnf(tp.parent)
561
- val tp1 = tp.derivedRefinedType(parent1, refinedName = tp.refinedName, refinedInfo = tp.refinedInfo)
562
-
563
- if (parent1.ne(tp.parent)) cnf(tp1) else tp1
564
- case tp : TypeAlias =>
565
- cnf(tp.alias)
566
- case _ =>
567
- tp
568
- }
569
-
570
- def isSingleton (tp : Type ): Boolean = tp.dealias match {
571
- case AndType (l, r) => isSingleton(l) || isSingleton(r)
572
- case OrType (l, r) => isSingleton(l) && isSingleton(r)
573
- case tp => tp.isSingleton
574
- }
575
-
576
- def recur (tp : Type ): Boolean = tp.dealias match {
577
- case AndType (tp1, tp2) =>
578
- recur(tp1) && recur(tp2) && {
579
- val bases1 = tp1.widenDealias.classSymbols
580
- val bases2 = tp2.widenDealias.classSymbols
581
-
582
- debug.println(s " bases of ${tp1.show}: " + bases1)
583
- debug.println(s " bases of ${tp2.show}: " + bases2)
584
- debug.println(s " ${tp1.show} <:< ${tp2.show} : " + (tp1 <:< tp2))
585
- debug.println(s " ${tp2.show} <:< ${tp1.show} : " + (tp2 <:< tp1))
586
-
587
- val noClassConflict =
588
- bases1.forall(sym1 => sym1.is(Trait ) || bases2.forall(sym2 => sym2.is(Trait ) || sym1.isSubClass(sym2))) ||
589
- bases1.forall(sym1 => sym1.is(Trait ) || bases2.forall(sym2 => sym2.is(Trait ) || sym2.isSubClass(sym1)))
590
-
591
- debug.println(s " class conflict for ${tp.show}? " + ! noClassConflict)
592
-
593
- noClassConflict &&
594
- (! isSingleton(tp1) || tp1 <:< tp2) &&
595
- (! isSingleton(tp2) || tp2 <:< tp1) &&
596
- (! bases1.exists(_ is Final ) || tp1 <:< maxTypeMap.apply(tp2)) &&
597
- (! bases2.exists(_ is Final ) || tp2 <:< maxTypeMap.apply(tp1))
598
- }
599
- case OrType (tp1, tp2) =>
600
- recur(tp1) || recur(tp2)
601
- case tp : RefinedType =>
602
- recur(tp.parent)
603
- case tp : TypeRef =>
604
- recur(tp.prefix) && ! (tp.classSymbol.is(AbstractFinal ))
605
- case _ =>
606
- true
607
- }
608
-
609
- val res = recur(cnf(tp))
610
-
611
- debug.println(s " ${tp.show} inhabited? " + res)
612
-
613
- res
517
+ instantiate(childTp, parent)(ctx.fresh.setNewTyperState()).dealias
614
518
}
615
519
616
520
/** expose abstract type references to their bounds or tvars according to variance */
0 commit comments