diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-20 10:07:24 +0100 |
---|---|---|
committer | Tobias Schlatter <tobias@meisch.ch> | 2014-03-21 11:28:30 +0100 |
commit | 07939c96715cd5adf7f220d239f61b73dd00edc3 (patch) | |
tree | de23b24f90ffc32bcbf6a22447cf93a5521abbd5 /src/dotty/tools/dotc/core | |
parent | 7e1343e86a0d2575d596198d0f889b7d64cdb5a4 (diff) | |
download | dotty-07939c96715cd5adf7f220d239f61b73dd00edc3.tar.gz dotty-07939c96715cd5adf7f220d239f61b73dd00edc3.tar.bz2 dotty-07939c96715cd5adf7f220d239f61b73dd00edc3.zip |
Fix of t1279a: baseTypeWithArgs
baseTypeWithArgs now also keeps track of refinements in the subtypes. Without
that, the approximated lub in t1279a is too coarse and the program fails to typecheck.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 2e936e2f1..b61f39ed7 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -10,6 +10,7 @@ import util.common._ import Names._ import Flags._ import util.Positions.Position +import config.Printers._ import collection.mutable object TypeApplications { @@ -195,13 +196,32 @@ class TypeApplications(val self: Type) extends AnyVal { NoType } - /** The base type including all type arguments of this type. + /** The base type including all type arguments and applicable refinements + * of this type. Refinements are applicable if they refine a member of + * the parent type which furthermore is not a name-mangled type parameter. * Existential types in arguments are returned as TypeBounds instances. */ - final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = self.dealias match { - case AndType(tp1, tp2) => tp1.baseTypeWithArgs(base) & tp2.baseTypeWithArgs(base) - case OrType(tp1, tp2) => tp1.baseTypeWithArgs(base) | tp2.baseTypeWithArgs(base) - case _ => self.baseTypeRef(base).appliedTo(baseArgInfos(base)) + final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"btwa ${self.show} wrt $base", core, show = true) { + def default = self.baseTypeRef(base).appliedTo(baseArgInfos(base)) + self match { + case tp: TypeRef => + tp.info match { + case TypeBounds(_, hi) => hi.baseTypeWithArgs(base) + case _ => default + } + case tp @ RefinedType(parent, name) if !tp.member(name).symbol.is(ExpandedTypeParam) => + val pbase = parent.baseTypeWithArgs(base) + if (pbase.member(name).exists) RefinedType(pbase, name, tp.refinedInfo) + else pbase + case tp: TermRef => + tp.underlying.baseTypeWithArgs(base) + case AndType(tp1, tp2) => + tp1.baseTypeWithArgs(base) & tp2.baseTypeWithArgs(base) + case OrType(tp1, tp2) => + tp1.baseTypeWithArgs(base) | tp2.baseTypeWithArgs(base) + case _ => + default + } } /** Translate a type of the form From[T] to To[T], keep other types as they are. |