aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-06-13 09:34:12 +0200
committerMartin Odersky <odersky@gmail.com>2014-06-13 09:34:12 +0200
commit9a6a4e8ca400835643e839cd98bb5581cbf97ab9 (patch)
tree059a6f4496900effd20de8c3ac55f9fda42180d9 /src/dotty/tools/dotc/core/Types.scala
parent8db6b3e3c28f671942d4a05ec7cd8848c2dd7fa9 (diff)
downloaddotty-9a6a4e8ca400835643e839cd98bb5581cbf97ab9.tar.gz
dotty-9a6a4e8ca400835643e839cd98bb5581cbf97ab9.tar.bz2
dotty-9a6a4e8ca400835643e839cd98bb5581cbf97ab9.zip
More careful with lookupRefined
Avoid to reduce projections `A{ ... }#T` to aliases if the alias would refer to abstract members of the refinement type.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 24586f412..a9bbde407 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -164,6 +164,21 @@ object Types {
case _ => false
}
+ /** Is this type a transitive refinement of the given type or class symbol?
+ * This is true if the type consists of 0 or more refinements or other
+ * non-singleton proxies that lead to the `prefix` type, or, if
+ * `prefix` is a class symbol, lead to an instance type of this class.
+ */
+ def refines(prefix: AnyRef /* RefinedType | ClassSymbol */)(implicit ctx: Context): Boolean =
+ (this eq prefix) || {
+ this match {
+ case base: ClassInfo => base.cls eq prefix
+ case base: SingletonType => false
+ case base: TypeProxy => base.underlying refines prefix
+ case _ => false
+ }
+ }
+
// ----- Higher-order combinators -----------------------------------
/** Returns true if there is a part of this type that satisfies predicate `p`.
@@ -635,11 +650,25 @@ object Types {
*/
def lookupRefined(name: Name)(implicit ctx: Context): Type = stripTypeVar match {
case pre: RefinedType =>
- if (pre.refinedName ne name) pre.parent.lookupRefined(name)
+ def dependsOnThis(tp: Type): Boolean = tp match {
+ case tp @ TypeRef(RefinedThis(rt), _) if rt refines pre =>
+ tp.info match {
+ case TypeBounds(lo, hi) if lo eq hi => dependsOnThis(hi)
+ case _ => true
+ }
+ case RefinedThis(rt) =>
+ rt refines pre
+ case _ => false
+ }
+ if (pre.refinedName ne name)
+ pre.parent.lookupRefined(name)
else pre.refinedInfo match {
- case TypeBounds(lo, hi) /*if lo eq hi*/ => hi
+ case TypeBounds(lo, hi) if lo eq hi =>
+ if (hi.existsPart(dependsOnThis)) NoType else hi
case _ => NoType
}
+ case RefinedThis(rt) =>
+ rt.lookupRefined(name)
case pre: WildcardType =>
WildcardType
case _ =>