diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-08 18:44:58 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-03-20 13:02:40 +0100 |
commit | 021c251869ddeccc9ff91ab5c0867a11f3c8cea3 (patch) | |
tree | 69079094b807562d2cdc676a6ac530170cdfe122 /src/dotty/tools/dotc/core/TypeComparer.scala | |
parent | 88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4 (diff) | |
download | dotty-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.scala | 35 |
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 |