diff options
author | Martin Odersky <odersky@gmail.com> | 2016-01-30 20:22:41 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-02-09 09:40:53 +0100 |
commit | 322bcfef33834eb1e57c874c5a745faf65e1b8bc (patch) | |
tree | ee7bfd6f07b778da90abe97d84edf955d355d509 /src/dotty/tools/dotc/core/TypeOps.scala | |
parent | 7ccd02c2cd23e4187f3e3a378973704cecd6459a (diff) | |
download | dotty-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.scala | 44 |
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}") } |