diff options
author | odersky <odersky@gmail.com> | 2017-03-09 10:20:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-09 10:20:25 +0100 |
commit | 8e5c9c4a1a4555883307b7e81fea064134f350f2 (patch) | |
tree | e2feee0b87ed785e32ed8ba8fa2953128498f917 /compiler/src/dotty/tools/dotc/core/TypeComparer.scala | |
parent | 6abaa109e1add82f4add605a5cb3243e34b1ee33 (diff) | |
parent | c7f1f35c36593ac9454c8572a59c649610829b6a (diff) | |
download | dotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.tar.gz dotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.tar.bz2 dotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.zip |
Merge pull request #2045 from dotty-staging/fix-hlist-hmap
Fix type inference for HLists and HMaps
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/TypeComparer.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/TypeComparer.scala | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index b97dfe684..b61fccf31 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1300,23 +1300,28 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case tp1: RefinedType => tp2 match { case tp2: RefinedType if tp1.refinedName == tp2.refinedName => - // Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }`, if `S1 =:= S2` - // (possibly by instantiating type parameters), rewrite to `T1 & T2 { X = S1 }`. - // Otherwise rewrite to `T1 & T2 { X B }` where `B` is the conjunction of - // the bounds of `X` in `T1` and `T2`. - // The first rule above is contentious because it cuts the constraint set. - // But without it we would replace the two aliases by - // `T { X >: S1 | S2 <: S1 & S2 }`, which looks weird and is probably - // not what's intended. + // Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }` rewrite to + // `T1 & T2 { X B }` where `B` is the conjunction of the bounds of `X` in `T1` and `T2`. + // + // However, if `homogenizeArgs` is set, and both aliases `X = Si` are + // nonvariant, and `S1 =:= S2` (possibly by instantiating type parameters), + // rewrite instead to `T1 & T2 { X = S1 }`. This rule is contentious because + // it cuts the constraint set. On the other hand, without it we would replace + // the two aliases by `T { X >: S1 | S2 <: S1 & S2 }`, which looks weird + // and is probably not what's intended. val rinfo1 = tp1.refinedInfo val rinfo2 = tp2.refinedInfo val parent = tp1.parent & tp2.parent - val rinfo = - if (rinfo1.isAlias && rinfo2.isAlias && isSameType(rinfo1, rinfo2)) - rinfo1 - else - rinfo1 & rinfo2 - tp1.derivedRefinedType(parent, tp1.refinedName, rinfo) + + def isNonvariantAlias(tp: Type) = tp match { + case tp: TypeAlias => tp.variance == 0 + case _ => false + } + if (homogenizeArgs && + isNonvariantAlias(rinfo1) && isNonvariantAlias(rinfo2)) + isSameType(rinfo1, rinfo2) // establish new constraint + + tp1.derivedRefinedType(parent, tp1.refinedName, rinfo1 & rinfo2) case _ => NoType } |