aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/TypeAssigner.scala
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2015-10-02 23:25:30 +0200
committerGuillaume Martres <smarter@ubuntu.com>2015-10-09 15:00:08 +0200
commit82a6d6f52065ae39a0a162f95e5002a6ab26cc55 (patch)
treef9a3667539ccc93d1aabc1031c60ed5575b32fde /src/dotty/tools/dotc/typer/TypeAssigner.scala
parentd1014c3a2cf87b783f383e52b8923a42ee1bc31c (diff)
downloaddotty-82a6d6f52065ae39a0a162f95e5002a6ab26cc55.tar.gz
dotty-82a6d6f52065ae39a0a162f95e5002a6ab26cc55.tar.bz2
dotty-82a6d6f52065ae39a0a162f95e5002a6ab26cc55.zip
TypeAssigner#avoid: do not lose type parameters when the base type changes.
Fixes #741.
Diffstat (limited to 'src/dotty/tools/dotc/typer/TypeAssigner.scala')
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 22c062243..7225ede14 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -87,13 +87,28 @@ trait TypeAssigner {
case _ =>
mapOver(tp)
}
- case tp: RefinedType =>
- val tp1 @ RefinedType(parent1, _) = mapOver(tp)
- if (toAvoid(tp1.refinedInfo) && variance > 0) {
- typr.println(s"dropping refinement from $tp1")
- parent1
+ case tp @ RefinedType(parent, name) if variance > 0 =>
+ // The naive approach here would be to first approximate the parent,
+ // but if the base type of the approximated parent is different from
+ // the current base type, then the current refinement won't be valid
+ // if it's a type parameter refinement.
+ // Therefore we first approximate the base type, then use `baseArgInfos`
+ // to get correct refinements for the approximated base type, then
+ // recursively approximate the resulting type.
+ val base = tp.unrefine
+ if (toAvoid(base)) {
+ val base1 = apply(base)
+ apply(base1.appliedTo(tp.baseArgInfos(base1.typeSymbol)))
+ } else {
+ val parent1 = apply(tp.parent)
+ val refinedInfo1 = apply(tp.refinedInfo)
+ if (toAvoid(refinedInfo1)) {
+ typr.println(s"dropping refinement from $tp")
+ parent1
+ } else {
+ tp.derivedRefinedType(parent1, name, refinedInfo1)
+ }
}
- else tp1
case tp: TypeVar if ctx.typerState.constraint.contains(tp) =>
val lo = ctx.typerState.constraint.fullLowerBound(tp.origin)
val lo1 = avoid(lo, symsToAvoid)