aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeApplications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-20 10:07:24 +0100
committerTobias Schlatter <tobias@meisch.ch>2014-03-21 11:28:30 +0100
commit07939c96715cd5adf7f220d239f61b73dd00edc3 (patch)
treede23b24f90ffc32bcbf6a22447cf93a5521abbd5 /src/dotty/tools/dotc/core/TypeApplications.scala
parent7e1343e86a0d2575d596198d0f889b7d64cdb5a4 (diff)
downloaddotty-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/TypeApplications.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala30
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.