From 36de1429027f635fe7035cf217b944bfc67dcc2c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 19 Aug 2013 18:30:13 +0200 Subject: 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. --- src/dotty/tools/dotc/core/TypeComparer.scala | 2 +- src/dotty/tools/dotc/core/Types.scala | 5 +++++ src/dotty/tools/dotc/typer/Typer.scala | 25 +++++++++++++++++++++---- 3 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src/dotty') 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)) } -- cgit v1.2.3