diff options
author | Martin Odersky <odersky@gmail.com> | 2016-06-07 13:28:55 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-11 13:35:01 +0200 |
commit | 463e99a48996fbf7148aa62ec6d2f8b28000d2d4 (patch) | |
tree | 8e82c76c2de8b671dc3c2036a217a44d272c1a78 /src/dotty/tools/dotc | |
parent | 68e73e854e04f7bea20a8c95637729bf6889e17d (diff) | |
download | dotty-463e99a48996fbf7148aa62ec6d2f8b28000d2d4.tar.gz dotty-463e99a48996fbf7148aa62ec6d2f8b28000d2d4.tar.bz2 dotty-463e99a48996fbf7148aa62ec6d2f8b28000d2d4.zip |
Optionally, check kinds match for & and |
Optionally, check kinds of operands of & and | match.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/config/Config.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 30 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 4 |
3 files changed, 38 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala index 63ecdc76d..1c22329f1 100644 --- a/src/dotty/tools/dotc/config/Config.scala +++ b/src/dotty/tools/dotc/config/Config.scala @@ -79,6 +79,11 @@ object Config { */ final val checkProjections = false + /** If this flag is set it is checked that &/| only apply to types + * that are either both hk types or both * types. + */ + final val checkKinds = true + /** The recursion depth for showing a summarized string */ final val summarizeDepth = 2 diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 4f482f460..6fc1fb9dc 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -473,6 +473,31 @@ class TypeApplications(val self: Type) extends AnyVal { case _ => false } + /** Computes the kind of `self` without forcing anything. + * @return 1 if type is known to be higher-kinded + * -1 if type is known to be a * type + * 0 if kind of `self` is unknown (because symbols have not yet completed) + */ + def knownHK(implicit ctx: Context): Int = self match { + case self: TypeRef => + val tsym = self.symbol + if (tsym.isClass) -1 + else tsym.infoOrCompleter match { + case completer: TypeParamsCompleter => + if (completer.completerTypeParams(tsym).nonEmpty) 1 else -1 + case _ => + if (!tsym.isCompleting || tsym.isAliasType) tsym.info.knownHK + else 0 + } + case self: RefinedType => + if (self.isTypeParam) 1 else -1 + case self: SingletonType => -1 + case self: TypeVar => self.origin.knownHK + case self: WildcardType => self.optBounds.knownHK + case self: TypeProxy => self.underlying.knownHK + case _ => -1 + } + /** is receiver of the form T#$Apply? */ def isHKApply(implicit ctx: Context): Boolean = self match { case self @ RefinedType(_, name, _) => Config.newHK && name.isHkArgName && !self.isTypeParam @@ -666,7 +691,10 @@ class TypeApplications(val self: Type) extends AnyVal { res // without this line, typing 974.scala gives a stackoverflow in asSeenFrom. } else instTop(self) - if (reduced ne self) hk.println(i"reduce $self --> $reduced") + if (reduced ne self) { + hk.println(i"reduce $self --> $reduced / ${inst.tyconIsHK}") + //hk.println(s"reduce $self --> $reduced") + } reduced case _ => self } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 7a050c412..986a9c292 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2358,6 +2358,8 @@ object Types { object AndType { def apply(tp1: Type, tp2: Type)(implicit ctx: Context) = { assert(tp1.isInstanceOf[ValueType] && tp2.isInstanceOf[ValueType]) + if (Config.checkKinds) + assert((tp1.knownHK - tp2.knownHK).abs <= 1, i"$tp1 & $tp2 / " + s"$tp1 & $tp2") unchecked(tp1, tp2) } def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context) = { @@ -2392,6 +2394,8 @@ object Types { object OrType { def apply(tp1: Type, tp2: Type)(implicit ctx: Context) = { assertUnerased() + if (Config.checkKinds) + assert((tp1.knownHK - tp2.knownHK).abs <= 1, i"$tp1 | $tp2") unique(new CachedOrType(tp1, tp2)) } def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type = |