aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-01-07 14:47:18 +0700
committerMartin Odersky <odersky@gmail.com>2017-01-07 14:47:18 +0700
commit69feaa89167ebeb708535dd4abf3a79a410130f0 (patch)
treeec93cdc0b05ccb22628ca9dee454e33e4df3e8ee /compiler/src/dotty/tools/dotc
parent7e3f69ace983adfbc9bbf44954f9a5845add3d43 (diff)
downloaddotty-69feaa89167ebeb708535dd4abf3a79a410130f0.tar.gz
dotty-69feaa89167ebeb708535dd4abf3a79a410130f0.tar.bz2
dotty-69feaa89167ebeb708535dd4abf3a79a410130f0.zip
Change scheme to use Selectable
Use base types instead of implicits. This is more robust in the presence of type abstraction.
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Dynamic.scala41
3 files changed, 23 insertions, 23 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index c900f0b64..6e67087a3 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -508,8 +508,7 @@ class Definitions {
lazy val LanguageModuleRef = ctx.requiredModule("scala.language")
def LanguageModuleClass(implicit ctx: Context) = LanguageModuleRef.symbol.moduleClass.asClass
lazy val NonLocalReturnControlType: TypeRef = ctx.requiredClassRef("scala.runtime.NonLocalReturnControl")
- lazy val ProjectorType: TypeRef = ctx.requiredClassRef("scala.Projector")
- def ProjectorClass(implicit ctx: Context) = ProjectorType.symbol.asClass
+ lazy val SelectableType: TypeRef = ctx.requiredClassRef("scala.Selectable")
lazy val ClassTagType = ctx.requiredClassRef("scala.reflect.ClassTag")
def ClassTagClass(implicit ctx: Context) = ClassTagType.symbol.asClass
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index f53571bdc..4a9c50dad 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -414,7 +414,6 @@ object StdNames {
val genericArrayOps: N = "genericArrayOps"
val get: N = "get"
val getClass_ : N = "getClass"
- val getMethod : N = "getMethod"
val getOrElse: N = "getOrElse"
val hasNext: N = "hasNext"
val hashCode_ : N = "hashCode"
@@ -482,6 +481,7 @@ object StdNames {
val sameElements: N = "sameElements"
val scala_ : N = "scala"
val selectDynamic: N = "selectDynamic"
+ val selectDynamicMethod: N = "selectDynamicMethod"
val selectOverloadedMethod: N = "selectOverloadedMethod"
val selectTerm: N = "selectTerm"
val selectType: N = "selectType"
diff --git a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
index 4b7584559..49dd98523 100644
--- a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
@@ -33,8 +33,8 @@ object Dynamic {
*
* The first matching rule of is applied.
*
- * 2. Translates member seclections on structural types by means of an implicit
- * Projector instance. @See handleStructural.
+ * 2. Translates member selections on structural types to calls of `selectDynamic`
+ * or `selectDynamicMethod` on a `Selectable` instance. @See handleStructural.
*
*/
trait Dynamic { self: Typer with Applications =>
@@ -116,44 +116,45 @@ trait Dynamic { self: Typer with Applications =>
*
* If `U` is a value type, map `x.a` to the equivalent of:
*
- * implicitly[Projector[T]].get(x, "a").asInstanceOf[U]
+ * (x: Selectable).selectDynamic(x, "a").asInstanceOf[U]
*
* If `U` is a method type (T1,...,Tn)R, map `x.a` to the equivalent of:
*
- * implicitly[Projector[T]].getMethod(x, "a")(CT1, ..., CTn).asInstanceOf[(T1,...,Tn) => R]
+ * (x: Selectable).selectDynamicMethod(x, "a")(CT1, ..., CTn).asInstanceOf[(T1,...,Tn) => R]
*
- * where CT1,...,CTn are the classtags representing the erasure of T1,...,Tn.
+ * where CT1,...,CTn are the class tags representing the erasure of T1,...,Tn.
*
- * The small print: (1) T is forced to be fully defined. (2) It's an error if
- * U is neither a value nor a method type, or a dependent method type, or of too
- * large arity (limit is Definitions.MaxStructuralMethodArity).
+ * It's an error if U is neither a value nor a method type, or a dependent method
+ * type, or of too large arity (limit is Definitions.MaxStructuralMethodArity).
*/
def handleStructural(tree: Tree)(implicit ctx: Context): Tree = {
val Select(qual, name) = tree
- def issueError(msgFn: String => String): Unit = ctx.error(msgFn("reflective call"), tree.pos)
- def implicitArg(tpe: Type) = inferImplicitArg(tpe, issueError, tree.pos.endPos)
- val projector = implicitArg(defn.ProjectorType.appliedTo(qual.tpe.widen))
-
- def structuralCall(getterName: TermName, formals: List[Tree]) = {
+ def structuralCall(selectorName: TermName, formals: List[Tree]) = {
+ val selectable = adapt(qual, defn.SelectableType)
val scall = untpd.Apply(
- untpd.TypedSplice(projector.select(getterName)),
- (qual :: Literal(Constant(name.toString)) :: formals).map(untpd.TypedSplice(_)))
+ untpd.TypedSplice(selectable.select(selectorName)),
+ (Literal(Constant(name.toString)) :: formals).map(untpd.TypedSplice(_)))
typed(scall)
}
+
def fail(reason: String) =
errorTree(tree, em"Structural access not allowed on method $name because it $reason")
- fullyDefinedType(tree.tpe.widen, "structural access", tree.pos) match {
+
+ tree.tpe.widen match {
case tpe: MethodType =>
if (tpe.isDependent)
fail(i"has a dependent method type")
else if (tpe.paramNames.length > Definitions.MaxStructuralMethodArity)
fail(i"takes too many parameters")
- val ctags = tpe.paramTypes.map(pt =>
- implicitArg(defn.ClassTagType.appliedTo(pt :: Nil)))
- structuralCall(nme.getMethod, ctags).asInstance(tpe.toFunctionType())
+ else {
+ def issueError(msgFn: String => String): Unit = ctx.error(msgFn(""), tree.pos)
+ val ctags = tpe.paramTypes.map(pt =>
+ inferImplicitArg(defn.ClassTagType.appliedTo(pt :: Nil), issueError, tree.pos.endPos))
+ structuralCall(nme.selectDynamicMethod, ctags).asInstance(tpe.toFunctionType())
+ }
case tpe: ValueType =>
- structuralCall(nme.get, Nil).asInstance(tpe)
+ structuralCall(nme.selectDynamic, Nil).asInstance(tpe)
case tpe: PolyType =>
fail("is polymorphic")
case tpe =>