diff options
author | Martin Odersky <odersky@gmail.com> | 2015-10-24 12:31:46 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-10-24 12:31:56 +0200 |
commit | 308e637dd35ba8c5e46c1bacf309ad2d82cd93bd (patch) | |
tree | ac2f12e2554ee7d703a9735925ea87298bd9ba3f /src | |
parent | 396df3b7bb954c674911b8e144ba0e1c77ffab00 (diff) | |
download | dotty-308e637dd35ba8c5e46c1bacf309ad2d82cd93bd.tar.gz dotty-308e637dd35ba8c5e46c1bacf309ad2d82cd93bd.tar.bz2 dotty-308e637dd35ba8c5e46c1bacf309ad2d82cd93bd.zip |
Revise typeParams to account for existential hk types
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 64 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 1 |
2 files changed, 37 insertions, 28 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 47935f79e..f63005d8a 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -48,33 +48,43 @@ class TypeApplications(val self: Type) extends AnyVal { * For a typeref referring to a class, the type parameters of the class. * For a typeref referring to a Lambda class, the type parameters of * its right hand side or upper bound. - * For a refinement type, the type parameters of its parent, unless the refinement - * re-binds the type parameter with a type-alias. - * For any other non-singleton type proxy, the type parameters of its underlying type. - * For any other type, the empty list. + * For a refinement type, the type parameters of its parent, dropping + * any type parameter that is-rebound by the refinement. "Re-bind" means: + * The refinement contains a TypeAlias for the type parameter, or + * it introduces bounds for the type parameter, and we are not in the + * special case of a type Lambda, where a LambdaTrait gets refined + * with the bounds on its hk args. See `LambdaAbstract`, where these + * types get introduced, and see `isBoundedLambda` below for the test. */ final def typeParams(implicit ctx: Context): List[TypeSymbol] = /*>|>*/ track("typeParams") /*<|<*/ { self match { - case tp: ClassInfo => - tp.cls.typeParams - case tp: TypeRef => - val tsym = tp.typeSymbol + case self: ClassInfo => + self.cls.typeParams + case self: TypeRef => + val tsym = self.typeSymbol if (tsym.isClass) tsym.typeParams - else if (tsym.isAliasType) tp.underlying.typeParams + else if (tsym.isAliasType) self.underlying.typeParams else { val lam = LambdaClass(forcing = false) if (lam.exists) lam.typeParams else Nil } - case tp: RefinedType => - val tparams = tp.parent.typeParams - tp.refinedInfo match { - case rinfo: TypeAlias => tparams.filterNot(_.name == tp.refinedName) - case _ => tparams + case self: RefinedType => + def isBoundedLambda(tp: Type): Boolean = tp match { + case tp: TypeRef => tp.typeSymbol.isLambdaTrait + case tp: RefinedType => tp.refinedName.isLambdaArgName && isBoundedLambda(tp.parent) + case _ => false + } + val tparams = self.parent.typeParams + self.refinedInfo match { + case rinfo: TypeBounds if rinfo.isAlias || isBoundedLambda(self) => + tparams.filterNot(_.name == self.refinedName) + case _ => + tparams } - case tp: SingletonType => + case self: SingletonType => Nil - case tp: TypeProxy => - tp.underlying.typeParams + case self: TypeProxy => + self.underlying.typeParams case _ => Nil } @@ -91,23 +101,23 @@ class TypeApplications(val self: Type) extends AnyVal { */ final def rawTypeParams(implicit ctx: Context): List[TypeSymbol] = { self match { - case tp: ClassInfo => - tp.cls.typeParams - case tp: TypeRef => - val tsym = tp.typeSymbol + case self: ClassInfo => + self.cls.typeParams + case self: TypeRef => + val tsym = self.typeSymbol if (tsym.isClass) tsym.typeParams - else if (tsym.isAliasType) tp.underlying.rawTypeParams + else if (tsym.isAliasType) self.underlying.rawTypeParams else Nil case _: BoundType | _: SingletonType => Nil - case tp: TypeProxy => - tp.underlying.rawTypeParams + case self: TypeProxy => + self.underlying.rawTypeParams case _ => Nil } } - /** If type `tp` is equal, aliased-to, or upperbounded-by a type of the form + /** If type `self` is equal, aliased-to, or upperbounded-by a type of the form * `LambdaXYZ { ... }`, the class symbol of that type, otherwise NoSymbol. * symbol of that type, otherwise NoSymbol. * @param forcing if set, might force completion. If not, never forces @@ -125,7 +135,7 @@ class TypeApplications(val self: Type) extends AnyVal { NoSymbol }} - /** Is type `tp` equal, aliased-to, or upperbounded-by a type of the form + /** Is type `self` equal, aliased-to, or upperbounded-by a type of the form * `LambdaXYZ { ... }`? */ def isLambda(implicit ctx: Context): Boolean = @@ -137,7 +147,7 @@ class TypeApplications(val self: Type) extends AnyVal { def isSafeLambda(implicit ctx: Context): Boolean = LambdaClass(forcing = false).exists - /** Is type `tp` a Lambda with all hk$i fields fully instantiated? */ + /** Is type `self` a Lambda with all hk$i fields fully instantiated? */ def isInstantiatedLambda(implicit ctx: Context): Boolean = isSafeLambda && typeParams.isEmpty diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 98b8357b9..b2d45b661 100644 --- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -27,7 +27,6 @@ import ValueClasses._ * Unfortunately this phase ended up being not Y-checkable unless types are erased. A cast to an ConstantType(3) or x.type * cannot be rewritten before erasure. */ - trait TypeTestsCasts { import ast.tpd._ |