diff options
author | Martin Odersky <odersky@gmail.com> | 2016-06-29 20:15:22 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-11 13:35:05 +0200 |
commit | 646bf97d7c2e66b4332b86f2e6cd6440fc442215 (patch) | |
tree | 9e1734cfe4c2b93fbbcaaea31dbbe464d8ffe3b6 /src/dotty/tools | |
parent | 8805dd4f821e06a688fcf492b61033fe0992e752 (diff) | |
download | dotty-646bf97d7c2e66b4332b86f2e6cd6440fc442215.tar.gz dotty-646bf97d7c2e66b4332b86f2e6cd6440fc442215.tar.bz2 dotty-646bf97d7c2e66b4332b86f2e6cd6440fc442215.zip |
Beta-reduce with wildcard arguments if this is safe.
Makes pos/partialApplications compile.
- Fix appliedTo for aliasTypes
Returned a general TypeBounds instance before.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 48 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 6 |
2 files changed, 45 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 274fc8ff8..714d2a5e3 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -223,6 +223,44 @@ object TypeApplications { mapOver(tp) } } + + /** A type map that tries to reduce a (part of) the result type of the type lambda `tycon` + * with the given `args`(some of which are wildcard arguments represented by type bounds). + * Non-wildcard arguments are substituted everywhere as usual. A wildcard argument + * `>: L <: H` is substituted for a type lambda parameter `X` only if `X` appears + * in a toplevel refinement of the form + * + * { type A = X } + * + * and there are no other occurrences of `X` in the reduced type. In that case + * the refinement above is replaced by + * + * { type A >: L <: U } + * + * The `allReplaced` field indicates whether all occurrences of type lambda parameters + * in the reduced type have been replaced with arguments. + */ + class Reducer(tycon: TypeLambda, args: List[Type])(implicit ctx: Context) extends TypeMap { + private var available = Set((0 until args.length): _*) + var allReplaced = true + def hasWildcardArg(p: PolyParam) = + p.binder == tycon && args(p.paramNum).isInstanceOf[TypeBounds] + def apply(t: Type) = t match { + case t @ TypeAlias(p: PolyParam) if hasWildcardArg(p) && available.contains(p.paramNum) => + available -= p.paramNum + args(p.paramNum) + case p: PolyParam if p.binder == tycon => + if (hasWildcardArg(p)) { allReplaced = false; p } + else args(p.paramNum) + case _: TypeBounds | _: HKApply => + val saved = available + available = Set() + try mapOver(t) + finally available = saved + case _ => + mapOver(t) + } + } } import TypeApplications._ @@ -733,12 +771,16 @@ class TypeApplications(val self: Type) extends AnyVal { self.stripTypeVar match { case self: TypeLambda => if (!args.exists(_.isInstanceOf[TypeBounds])) self.instantiate(args) - else self match { - case EtaExpansion(selfTycon) => selfTycon.appliedTo(args) - case _ => HKApply(self, args) + else { + val reducer = new Reducer(self, args) + val reduced = reducer(self.resType) + if (reducer.allReplaced) reduced + else HKApply(self, args) } case self: AndOrType => self.derivedAndOrType(self.tp1.appliedTo(args), self.tp2.appliedTo(args)) + case self: TypeAlias => + self.derivedTypeAlias(self.alias.appliedTo(args)) case self: TypeBounds => self.derivedTypeBounds(self.lo, self.hi.appliedTo(args)) case self: LazyRef => diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index e6cd0a0df..d0c299ae4 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1409,12 +1409,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { mergeNames(names1, names2, nme.syntheticParamName), formals1, tp1.resultType & tp2.resultType.subst(tp2, tp1)) case _ => - tp2 match { - case tp2 @ MethodType(names2, formals2) => - println( - TypeComparer.explained(implicit ctx => isSameType(formals1.head, formals2.head))) - case _ => - } mergeConflict(tp1, tp2) } case tp1: PolyType => |