aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/Definitions.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-12-03 12:22:44 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-17 18:34:27 +0100
commit8450556080c5fd8f8553bec4f39ea08fbb05c9d2 (patch)
tree066c2e02e885295d5f4b85b0cc55a140beac281f /compiler/src/dotty/tools/dotc/core/Definitions.scala
parentd69e8490dc66f98719fa1483e57d824c3a61f99c (diff)
downloaddotty-8450556080c5fd8f8553bec4f39ea08fbb05c9d2.tar.gz
dotty-8450556080c5fd8f8553bec4f39ea08fbb05c9d2.tar.bz2
dotty-8450556080c5fd8f8553bec4f39ea08fbb05c9d2.zip
Add ImplicitFunctionN classes
These are always synthetic; generated on demand.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Definitions.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala30
1 files changed, 21 insertions, 9 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 3f1f3e294..b90cd597f 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -87,23 +87,32 @@ class Definitions {
}
/** The trait FunctionN, for some N */
- private def newFunctionNTrait(n: Int) = {
+ private def newFunctionNTrait(name: TypeName) = {
val completer = new LazyType {
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
val cls = denot.asClass.classSymbol
val decls = newScope
+ val arity = name.functionArity
val argParams =
- for (i <- List.range(0, n)) yield
- enterTypeParam(cls, s"T$i".toTypeName, Contravariant, decls)
- val resParam = enterTypeParam(cls, s"R".toTypeName, Covariant, decls)
+ for (i <- List.range(0, arity)) yield
+ enterTypeParam(cls, name ++ "$T" ++ i.toString, Contravariant, decls)
+ val resParam = enterTypeParam(cls, name ++ "$R", Covariant, decls)
+ val (implicitFlag, parentTraits) =
+ if (name.startsWith(tpnme.ImplicitFunction)) {
+ val superTrait =
+ FunctionType(arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil)
+ (Implicit, ctx.normalizeToClassRefs(superTrait :: Nil, cls, decls))
+ }
+ else (EmptyFlags, Nil)
val applyMeth =
decls.enter(
newMethod(cls, nme.apply,
- MethodType(argParams.map(_.typeRef), resParam.typeRef), Deferred))
- denot.info = ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: Nil, decls)
+ MethodType(argParams.map(_.typeRef), resParam.typeRef), Deferred | implicitFlag))
+ denot.info =
+ ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: parentTraits, decls)
}
}
- newClassSymbol(ScalaPackageClass, s"Function$n".toTypeName, Trait, completer)
+ newClassSymbol(ScalaPackageClass, name, Trait, completer)
}
private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
@@ -659,6 +668,9 @@ class Definitions {
lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply)
def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
+ def ImplicitFunctionClass(n: Int)(implicit ctx: Context) =
+ ctx.requiredClass("scala.ImplicitFunction" + n.toString)
+
def FunctionType(n: Int)(implicit ctx: Context): TypeRef =
if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n)
else FunctionClass(n).typeRef
@@ -834,8 +846,8 @@ class Definitions {
val newDecls = new MutableScope(oldDecls) {
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
val res = super.lookupEntry(name)
- if (res == null && name.functionArity > MaxImplementedFunctionArity)
- newScopeEntry(newFunctionNTrait(name.functionArity))
+ if (res == null && name.isTypeName && name.functionArity > MaxImplementedFunctionArity)
+ newScopeEntry(newFunctionNTrait(name.asTypeName))
else res
}
}