aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-19 18:30:13 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-19 18:30:13 +0200
commit36de1429027f635fe7035cf217b944bfc67dcc2c (patch)
tree08e9ff57846df6b4acd385348444e73cb8df932b /src/dotty/tools/dotc
parentaa9ffac0042ed1ab95b5820dfac44a0de0df398c (diff)
downloaddotty-36de1429027f635fe7035cf217b944bfc67dcc2c.tar.gz
dotty-36de1429027f635fe7035cf217b944bfc67dcc2c.tar.bz2
dotty-36de1429027f635fe7035cf217b944bfc67dcc2c.zip
Changed handling of selection prototypes.
Several changes: 1) Selection prototypes now get treated specially in subtype checks to account for def vs val, polymorphism, etc. 2) Selection prototypes will never nest , so quadratic blowup of checking them is avoided. 3) Selection prototypes are never generated for constructor names.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala5
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala25
3 files changed, 27 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 2940f949a..17204bf1c 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -184,7 +184,7 @@ class TypeComparer(implicit val ctx: Context) extends DotClass {
case tp2: RefinedType =>
isSubType(tp1, tp2.parent) && (
tp2.refinedName == nme.WILDCARD ||
- isSubType(tp1.member(tp2.refinedName).info, tp2.refinedInfo))
+ tp2.matchesInfo(tp1.member(tp2.refinedName).info))
case AndType(tp21, tp22) =>
isSubType(tp1, tp21) && isSubType(tp1, tp22)
case OrType(tp21, tp22) =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 1bc8f1646..e263cf076 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1376,6 +1376,11 @@ object Types {
override def underlying(implicit ctx: Context) = parent
+ /** Does goves type match `refinedInfo`. Translates to a subtype check here,
+ * but is overridden in SelectionProto
+ */
+ def matchesInfo(tp: Type)(implicit ctx: Context): Boolean = tp <:< refinedInfo
+
def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType = {
def originalName = parent.typeParams.apply(refinedName.hkParamIndex).name
if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo))
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 7f2ba2959..435e4014a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -20,7 +20,7 @@ import NameOps._
import Flags._
import Decorators._
import ErrorReporting._
-import Applications.{FunProtoType, PolyProtoType}
+import Applications.{FunProtoType, PolyProtoType, Compatibility, normalize}
import EtaExpansion.etaExpand
import util.Positions._
import util.SourcePosition
@@ -58,7 +58,24 @@ object Typer {
}
}
- class SelectionProto(name: Name, tp: Type) extends RefinedType(WildcardType, name)(_ => tp)
+ class SelectionProto(name: Name, tp: Type) extends RefinedType(WildcardType, name)(_ => tp) with Compatibility {
+ override def viewExists(tp: Type, pt: Type)(implicit ctx: Context): Boolean = false
+ override def matchesInfo(tp: Type)(implicit ctx: Context) = {
+ def test(implicit ctx: Context) =
+ isCompatible(normalize(tp), /*(new WildApprox) apply (needed?)*/ refinedInfo)
+ test(ctx.fresh.withNewTyperState)
+ }
+ }
+
+ def selectionProto(name: Name, tp: Type) =
+ if (name.isConstructorName) WildcardType
+ else {
+ val rtp = tp match {
+ case tp: SelectionProto => WildcardType
+ case _ => tp
+ }
+ new SelectionProto(name, rtp)
+ }
object AnySelectionProto extends SelectionProto(nme.WILDCARD, WildcardType)
}
@@ -327,7 +344,7 @@ class Typer extends Namer with Applications with Implicits {
}
def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
- val qual1 = typedExpr(tree.qualifier, new SelectionProto(tree.name, pt))
+ val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt))
val ownType = checkedSelectionType(qual1, tree)
checkValue(ownType, pt, tree.pos)
cpy.Select(tree, qual1, tree.name).withType(ownType)
@@ -613,7 +630,7 @@ class Typer extends Namer with Applications with Implicits {
}
def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
- val qual1 = typedType(tree.qualifier, new SelectionProto(tree.name, pt))
+ val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt))
cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
}