aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeComparer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-08 18:44:58 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-20 13:02:40 +0100
commit021c251869ddeccc9ff91ab5c0867a11f3c8cea3 (patch)
tree69079094b807562d2cdc676a6ac530170cdfe122 /src/dotty/tools/dotc/core/TypeComparer.scala
parent88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4 (diff)
downloaddotty-021c251869ddeccc9ff91ab5c0867a11f3c8cea3.tar.gz
dotty-021c251869ddeccc9ff91ab5c0867a11f3c8cea3.tar.bz2
dotty-021c251869ddeccc9ff91ab5c0867a11f3c8cea3.zip
Merge refined types when distributing via "|".
Use the equality (where ~ is any form of refinement) T1 { x ~ R1 } & T2 { x ~ R2 } == T1 & T2 { x ~ R1 & R2 } We already did the same thing when distributing via "&".
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeComparer.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index da8263ac1..cfb9477c3 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -890,6 +890,19 @@ class TypeComparer(initctx: Context) extends DotClass {
/** Try to distribute `&` inside type, detect and handle conflicts */
private def distributeAnd(tp1: Type, tp2: Type): Type = tp1 match {
+ // opportunistically merge same-named refinements
+ // this does not change anything semantically (i.e. merging or not merging
+ // gives =:= types), but it keeps the type smaller.
+ case tp1: RefinedType =>
+ tp2 match {
+ case tp2: RefinedType if tp1.refinedName == tp2.refinedName =>
+ tp1.derivedRefinedType(
+ tp1.parent & tp2.parent,
+ tp1.refinedName,
+ tp1.refinedInfo & tp2.refinedInfo)
+ case _ =>
+ NoType
+ }
case tp1: TypeBounds =>
tp2 match {
case tp2: TypeBounds => tp1 & tp2
@@ -935,18 +948,6 @@ class TypeComparer(initctx: Context) extends DotClass {
case _ =>
rt1 & tp2
}
- case tp1: RefinedType =>
- // opportunistically merge same-named refinements
- // this does not change anything semantically (i.e. merging or not merging
- // gives =:= types), but it keeps the type smaller.
- tp2 match {
- case tp2: RefinedType if tp1.refinedName == tp2.refinedName =>
- tp1.derivedRefinedType(
- tp1.parent & tp2.parent, tp1.refinedName,
- tp1.refinedInfo & tp2.refinedInfo)
- case _ =>
- NoType
- }
case tp1: TypeVar if tp1.isInstantiated =>
tp1.underlying & tp2
case tp1: AnnotatedType =>
@@ -957,6 +958,16 @@ class TypeComparer(initctx: Context) extends DotClass {
/** Try to distribute `|` inside type, detect and handle conflicts */
private def distributeOr(tp1: Type, tp2: Type): Type = tp1 match {
+ case tp1: RefinedType =>
+ tp2 match {
+ case tp2: RefinedType if tp1.refinedName == tp2.refinedName =>
+ tp1.derivedRefinedType(
+ tp1.parent | tp2.parent,
+ tp1.refinedName,
+ tp1.refinedInfo | tp2.refinedInfo)
+ case _ =>
+ NoType
+ }
case tp1: TypeBounds =>
tp2 match {
case tp2: TypeBounds => tp1 | tp2