diff options
author | Martin Odersky <odersky@gmail.com> | 2016-06-04 18:21:11 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-11 13:35:00 +0200 |
commit | 939d9da26ee5992c17cd1fae0a501ed66a49fb95 (patch) | |
tree | 7efeb8e2cc3f4fdcfcbbf8b06051b3b4fc55240b /src/dotty/tools/dotc/core/Types.scala | |
parent | ae1f248ff407b231455a43ecbaf4751c0bb2bbaa (diff) | |
download | dotty-939d9da26ee5992c17cd1fae0a501ed66a49fb95.tar.gz dotty-939d9da26ee5992c17cd1fae0a501ed66a49fb95.tar.bz2 dotty-939d9da26ee5992c17cd1fae0a501ed66a49fb95.zip |
Add a second betaReduce
The new one only reduces straight applications of type lambdas with
definite arguments. It is called very early on appliedTo, and derivedRefinedType.
The old one, now renamed to normalizeHkApply also handles wildcard arguments
and can garbage collect general unneeded hk-refinements. It is called later, at various
places.
TODO: See what functionality of normalizeHkApply should go into betaReduce instead.
Maybe we can even drop normalizeHkApply? However: need to be careful to maintain aliases
for hk type inference.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 403b49da6..2fa4f94c1 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2131,9 +2131,43 @@ object Types { this } - def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType = + def betaReduce(implicit ctx: Context): Type = refinedInfo match { + case TypeAlias(alias) => + def instantiate(rt: RecType) = new TypeMap { + def apply(t: Type) = t match { + case TypeRef(RecThis(`rt`), `refinedName`) => alias + case tp: TypeRef => + val pre1 = apply(tp.prefix) + if (pre1 ne tp.prefix) tp.newLikeThis(pre1) else tp + case _ => mapOver(t) + } + } + def substAlias(tp: Type): Type = tp.safeDealias match { + case tp @ RefinedType(p, rname, rinfo) if tp.isTypeParam => + if (rname == refinedName) p // check bounds? + else tp.derivedRefinedType(substAlias(p), rname, rinfo) + case tp: RecType => + val p1 = substAlias(tp.parent) + if (p1 ne tp.parent) tp.rebind(instantiate(tp)(p1)) + else tp + case _ => + tp + } + val reduced = substAlias(parent) + if (reduced ne parent) { + hk.println(i"REDUCE $this ----> ${reduced}") + reduced + } + else this + case _ => + this + } + + def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): Type = if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this - else RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt))) + else + RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt))) + .betaReduce /** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */ def wrapIfMember(parent: Type)(implicit ctx: Context): Type = |