aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeOps.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-01-30 20:22:41 +0100
committerMartin Odersky <odersky@gmail.com>2016-02-09 09:40:53 +0100
commit322bcfef33834eb1e57c874c5a745faf65e1b8bc (patch)
treeee7bfd6f07b778da90abe97d84edf955d355d509 /src/dotty/tools/dotc/core/TypeOps.scala
parent7ccd02c2cd23e4187f3e3a378973704cecd6459a (diff)
downloaddotty-322bcfef33834eb1e57c874c5a745faf65e1b8bc.tar.gz
dotty-322bcfef33834eb1e57c874c5a745faf65e1b8bc.tar.bz2
dotty-322bcfef33834eb1e57c874c5a745faf65e1b8bc.zip
Move realizability logic from Types to TypeOps.
Types is already big enough.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeOps.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 34febf3be..26ce4ebf8 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -3,7 +3,7 @@ package dotc
package core
import Contexts._, Types._, Symbols._, Names._, Flags._, Scopes._
-import SymDenotations._, Denotations.Denotation
+import SymDenotations._, Denotations.SingleDenotation
import config.Printers._
import util.Positions._
import Decorators._
@@ -14,6 +14,7 @@ import collection.mutable
import ast.tpd._
trait TypeOps { this: Context => // TODO: Make standalone object.
+ import TypeOps._
/** The type `tp` as seen from prefix `pre` and owner `cls`. See the spec
* for what this means. Called very often, so the code is optimized heavily.
@@ -427,10 +428,36 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
case OrType(l, r) =>
DNF(l) | DNF(r)
case tp =>
- TypeOps.emptyDNF
+ emptyDNF
}
}
+ /** The realizability status of given type `tp`*/
+ def realizability(tp: Type): Realizability = tp.dealias match {
+ case tp: TermRef =>
+ if (tp.symbol.isRealizable) Realizable else NotStable
+ case _: SingletonType | NoPrefix =>
+ Realizable
+ case tp =>
+ def isConcrete(tp: Type): Boolean = tp.dealias match {
+ case tp: TypeRef => tp.symbol.isClass
+ case tp: TypeProxy => isConcrete(tp.underlying)
+ case tp: AndOrType => isConcrete(tp.tp1) && isConcrete(tp.tp2)
+ case _ => false
+ }
+ if (!isConcrete(tp)) NotConcrete
+ else {
+ def hasBadBounds(mbr: SingleDenotation) = {
+ val bounds = mbr.info.bounds
+ !(bounds.lo <:< bounds.hi)
+ }
+ tp.nonClassTypeMembers.find(hasBadBounds) match {
+ case Some(mbr) => new HasProblemBounds(mbr)
+ case _ => Realizable
+ }
+ }
+ }
+
private def enterArgBinding(formal: Symbol, info: Type, cls: ClassSymbol, decls: Scope) = {
val lazyInfo = new LazyType { // needed so we do not force `formal`.
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
@@ -650,4 +677,17 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
object TypeOps {
val emptyDNF = (Nil, Set[Name]()) :: Nil
@sharable var track = false // !!!DEBUG
+
+ // ----- Realizibility Status -----------------------------------------------------
+
+ abstract class Realizability(val msg: String)
+
+ object Realizable extends Realizability("")
+
+ object NotConcrete extends Realizability("is not a concrete type")
+
+ object NotStable extends Realizability("is not a stable reference")
+
+ class HasProblemBounds(mbr: SingleDenotation)(implicit ctx: Context)
+ extends Realizability(i"has a member $mbr with possibly empty bounds ${mbr.info.bounds.lo} .. ${mbr.info.bounds.hi}")
}