diff options
author | Martin Odersky <odersky@gmail.com> | 2014-02-16 13:12:37 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-02-21 18:42:50 +0100 |
commit | 77fc4d0831dc7a7ddaa74677e2659cdea4a2f52f (patch) | |
tree | a55363c03dca3a56767ed37b0cd36bb5bb009f13 /src | |
parent | c3f4e845d6354931ac011073219b8a133446c381 (diff) | |
download | dotty-77fc4d0831dc7a7ddaa74677e2659cdea4a2f52f.tar.gz dotty-77fc4d0831dc7a7ddaa74677e2659cdea4a2f52f.tar.bz2 dotty-77fc4d0831dc7a7ddaa74677e2659cdea4a2f52f.zip |
Disentangling SelectionProto and RefinedType
There were too many problems caused by it, and too little gained. So, now SelectionProto is no longer a Subtype of RefinedType.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 49 |
4 files changed, 30 insertions, 35 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index c3b2e1713..aab70a61b 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -937,8 +937,11 @@ object Types { /** A marker trait for types that apply only to term symbols */ trait TermType extends Type + /** A marker trait for types that can be types of values or prototypes of value types */ + trait ValueTypeOrProto extends TermType + /** A marker trait for types that can be types of values */ - trait ValueType extends TermType + trait ValueType extends ValueTypeOrProto /** A marker trait for types that are guaranteed to contain only a * single non-null value (they might contain null in addition). @@ -1283,8 +1286,6 @@ object Types { override def underlying(implicit ctx: Context) = parent - protected def isProto: Boolean = false - /** Derived refined type, with a twist: A refinement with a higher-kinded type param placeholder * is transformed to a refinement of the original type parameter if that one exists. */ @@ -1315,8 +1316,7 @@ object Types { case that: RefinedType => this.parent == that.parent && this.refinedName == that.refinedName && - this.refinedInfo == that.refinedInfo && - !that.isProto + this.refinedInfo == that.refinedInfo case _ => false } diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 87f9fc29e..6fad6738e 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -7,7 +7,7 @@ import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annot import StdNames.nme import ast.{Trees, untpd} import typer.Namer -import typer.Inferencing.ViewProto +import typer.Inferencing.{SelectionProto, ViewProto} import Trees._ import scala.annotation.switch @@ -107,6 +107,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close } + case tp: SelectionProto => + return toText(RefinedType(WildcardType, tp.name, tp.memberProto)) case tp: ViewProto => return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType) case tp: TypeRef => diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 74e79269f..a66864269 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -76,7 +76,7 @@ object Implicits { def discard = pt match { case pt: ViewProto => discardForView(ref.widen, pt.argType) - case _: ValueType => !defn.isFunctionType(pt) && discardForValueType(ref.widen) + case _: ValueTypeOrProto => !defn.isFunctionType(pt) && discardForValueType(ref.widen) case _ => false } diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 409d4a356..a313f70ac 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -53,7 +53,7 @@ object Inferencing { case _ => true } - case pt: ValueType if !(pt isRef defn.UnitClass) => + case _: ValueTypeOrProto if !(pt isRef defn.UnitClass) => mt match { case mt: MethodType => mt.isDependent || isCompatible(normalize(mt, pt), pt) @@ -73,48 +73,41 @@ object Inferencing { * * [ ].name: proto */ - abstract class SelectionProto(val name: Name, proto: Type, val compat: Compatibility) - extends RefinedType(WildcardType, name) with ProtoType { - override val refinedInfo = proto - override def isMatchedBy(tp1: Type)(implicit ctx: Context) = + abstract case class SelectionProto(val name: Name, val memberProto: Type, val compat: Compatibility) + extends CachedProxyType with ProtoType with ValueTypeOrProto { + + override def isMatchedBy(tp1: Type)(implicit ctx: Context) = { name == nme.WILDCARD || { val mbr = tp1.member(name) - mbr.exists && mbr.hasAltWith(m => compat.normalizedCompatible(m.info, proto)) - } - override def isProto = true - override def toString = "Proto" + super.toString - override def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType = { - val tp1 @ RefinedType(parent1, refinedName1) = super.derivedRefinedType(parent, refinedName, refinedInfo) - if (tp1 eq this) this - else { - assert(parent == WildcardType) - SelectionProto(refinedName1, tp1.refinedInfo, compat) + mbr.exists && mbr.hasAltWith(m => compat.normalizedCompatible(m.info, memberProto)) } } - def derivedSelectionProto(name: Name, proto: Type, compat: Compatibility)(implicit ctx: Context) = - if ((name eq this.name) && (proto eq this.proto) && (compat eq this.compat)) this - else SelectionProto(name, proto, compat) + + def underlying(implicit ctx: Context) = WildcardType + + def derivedSelectionProto(name: Name, memberProto: Type, compat: Compatibility)(implicit ctx: Context) = + if ((name eq this.name) && (memberProto eq this.memberProto) && (compat eq this.compat)) this + else SelectionProto(name, memberProto, compat) override def equals(that: Any): Boolean = that match { case that: SelectionProto => - (name eq that.name) && (refinedInfo == that.refinedInfo) && (compat eq that.compat) + (name eq that.name) && (memberProto == that.memberProto) && (compat eq that.compat) case _ => false } - def map(tm: TypeMap)(implicit ctx: Context) = derivedSelectionProto(name, tm(proto), compat) - def fold[T](x: T, ta: TypeAccumulator[T])(implicit ctx: Context) = ta(x, this) + def map(tm: TypeMap)(implicit ctx: Context) = derivedSelectionProto(name, tm(memberProto), compat) + def fold[T](x: T, ta: TypeAccumulator[T])(implicit ctx: Context) = ta(x, memberProto) - override def computeHash = addDelta(doHash(name, proto), if (compat == NoViewsAllowed) 1 else 0) + override def computeHash = addDelta(doHash(name, memberProto), if (compat == NoViewsAllowed) 1 else 0) } - class CachedSelectionProto(name: Name, proto: Type, compat: Compatibility) extends SelectionProto(name, proto, compat) + class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility) extends SelectionProto(name, memberProto, compat) object SelectionProto { - def apply(name: Name, proto: Type, compat: Compatibility)(implicit ctx: Context): SelectionProto = { - val rt = new CachedSelectionProto(name, proto, compat) - if (compat eq NoViewsAllowed) ctx.uniqueRefinedTypes.enterIfNew(rt).asInstanceOf[SelectionProto] - else rt + def apply(name: Name, memberProto: Type, compat: Compatibility)(implicit ctx: Context): SelectionProto = { + val selproto = new CachedSelectionProto(name, memberProto, compat) + if (compat eq NoViewsAllowed) unique(selproto) else selproto } } @@ -552,7 +545,7 @@ object Inferencing { else tp.derivedOrType(tp1a, tp2a) case tp: SelectionProto => - tp.derivedSelectionProto(tp.name, wildApprox(tp.refinedInfo), NoViewsAllowed) + tp.derivedSelectionProto(tp.name, wildApprox(tp.memberProto), NoViewsAllowed) case tp: ViewProto => tp.derivedViewProto(wildApprox(tp.argType), wildApprox(tp.resultType)) case _: ThisType | _: BoundType | NoPrefix => // default case, inlined for speed |