summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala17
-rw-r--r--test/files/neg/names-defaults-neg.check9
-rw-r--r--test/files/neg/t1181.check6
-rw-r--r--test/files/neg/t556.check4
-rw-r--r--test/files/pos/t6221.scala29
-rw-r--r--test/files/run/t6221.check1
-rw-r--r--test/files/run/t6221/Macros_1.scala22
-rw-r--r--test/files/run/t6221/Test_2.scala10
8 files changed, 80 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8d422f415d..efd258a577 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2794,16 +2794,11 @@ trait Typers extends Adaptations with Tags {
if (numVparams > definitions.MaxFunctionArity)
return MaxFunctionArityError(fun)
- def decompose(pt: Type): (Symbol, List[Type], Type) =
- if ((isFunctionType(pt) || (pt.typeSymbol == PartialFunctionClass && numVparams == 1 && fun.body.isInstanceOf[Match])) && // see bug901 for a reason why next conditions are needed
- ( pt.dealiasWiden.typeArgs.length - 1 == numVparams
- || fun.vparams.exists(_.tpt.isEmpty)
- ))
- (pt.typeSymbol, pt.dealiasWiden.typeArgs.init, pt.dealiasWiden.typeArgs.last)
- else
- (FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType)
-
- val (clazz, argpts, respt) = decompose(pt)
+ val FunctionSymbol = FunctionClass(numVparams)
+ val (argpts, respt) = pt baseType FunctionSymbol match {
+ case TypeRef(_, FunctionSymbol, args :+ res) => (args, res)
+ case _ => (fun.vparams map (_ => NoType), WildcardType)
+ }
if (argpts.lengthCompare(numVparams) != 0)
WrongNumberOfParametersError(fun, argpts)
else {
@@ -2853,7 +2848,7 @@ trait Typers extends Adaptations with Tags {
val formals = vparamSyms map (_.tpe)
val body1 = typed(fun.body, respt)
val restpe = packedType(body1, fun.symbol).deconst.resultType
- val funtpe = appliedType(clazz, formals :+ restpe: _*)
+ val funtpe = appliedType(FunctionSymbol, formals :+ restpe: _*)
treeCopy.Function(fun, vparams, body1) setType funtpe
}
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index f6bd703e1f..cdc12c2490 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -125,9 +125,12 @@ names-defaults-neg.scala:134: error: missing parameter type for expanded functio
names-defaults-neg.scala:135: error: parameter 'a' is already specified at parameter position 1
val taf3 = testAnnFun(b = _: String, a = get(8))
^
-names-defaults-neg.scala:136: error: wrong number of parameters; expected = 2
+names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$3) => testAnnFun(x$3, ((x$4) => b = x$4)))
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
- ^
+ ^
+names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$4) => b = x$4)
+ val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
+ ^
names-defaults-neg.scala:144: error: variable definition needs type because 'x' is used as a named argument in its body.
def t3 { var x = t.f(x = 1) }
^
@@ -165,4 +168,4 @@ names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a m
class u18 { var x: Int = u.f(x = 1) }
^
four warnings found
-41 errors found
+42 errors found
diff --git a/test/files/neg/t1181.check b/test/files/neg/t1181.check
index 3724752a85..13b73d5381 100644
--- a/test/files/neg/t1181.check
+++ b/test/files/neg/t1181.check
@@ -1,8 +1,10 @@
t1181.scala:8: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
case (Nil, Nil) => map
^
-t1181.scala:9: error: missing parameter type
+t1181.scala:9: error: type mismatch;
+ found : scala.collection.immutable.Map[Symbol,Symbol]
+ required: Symbol
_ => buildMap(map.updated(keyList.head, valueList.head), keyList.tail, valueList.tail)
- ^
+ ^
one warning found
one error found
diff --git a/test/files/neg/t556.check b/test/files/neg/t556.check
index c278e13991..5135dc92ef 100644
--- a/test/files/neg/t556.check
+++ b/test/files/neg/t556.check
@@ -1,4 +1,4 @@
-t556.scala:3: error: wrong number of parameters; expected = 1
+t556.scala:3: error: missing parameter type
def g:Int = f((x,y)=>x)
- ^
+ ^
one error found
diff --git a/test/files/pos/t6221.scala b/test/files/pos/t6221.scala
new file mode 100644
index 0000000000..dd7776f596
--- /dev/null
+++ b/test/files/pos/t6221.scala
@@ -0,0 +1,29 @@
+class MyFunc[-A, +B] extends (A => B) { def apply(x: A): B = ??? }
+
+class MyCollection[A] {
+ def map[B](f: MyFunc[A, B]): MyCollection[B] = new MyCollection[B]
+}
+
+class OtherFunc[-A, +B] {}
+
+object Test {
+ implicit def functionToMyFunc[A, B](f: A => B): MyFunc[A, B] = new MyFunc
+
+ implicit def otherFuncToMyFunc[A, B](f: OtherFunc[A, B]): MyFunc[A, B] = new MyFunc
+
+ def main(args: Array[String]) {
+ val col = new MyCollection[Int]
+
+ // Doesn't compile: error: missing parameter type for expanded function ((x$1) => x$1.toString)
+ println(col.map(_.toString))
+
+ // Doesn't compile: error: missing parameter type
+ println(col.map(x => x.toString))
+
+ // Does compile
+ println(col.map((x: Int) => x.toString))
+
+ // Does compile (even though type params of OtherFunc not given)
+ println(col.map(new OtherFunc))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6221.check b/test/files/run/t6221.check
new file mode 100644
index 0000000000..aa1bdd0e6e
--- /dev/null
+++ b/test/files/run/t6221.check
@@ -0,0 +1 @@
+((x) => x.$percent(2).$eq$eq(0))
diff --git a/test/files/run/t6221/Macros_1.scala b/test/files/run/t6221/Macros_1.scala
new file mode 100644
index 0000000000..c9500626d8
--- /dev/null
+++ b/test/files/run/t6221/Macros_1.scala
@@ -0,0 +1,22 @@
+import language.experimental.macros
+import language.implicitConversions
+import scala.reflect.macros.Context
+import scala.reflect.runtime.universe.Tree
+
+class ReflectiveClosure[A, B](val tree: Tree, fn: A => B) extends (A => B) {
+ def apply(x: A) = fn(x)
+}
+
+object ReflectiveClosure {
+ implicit def reflectClosure[A, B](f: A => B): ReflectiveClosure[A, B] = macro Macros.reflectiveClosureImpl[A, B]
+}
+
+object Macros {
+ def reflectiveClosureImpl[A, B](c: Context)(f: c.Expr[A => B]): c.Expr[ReflectiveClosure[A, B]] = {
+ import c.universe._
+ val u = treeBuild.mkRuntimeUniverseRef
+ val m = EmptyTree
+ val tree = c.Expr[scala.reflect.runtime.universe.Tree](Select(c.reifyTree(u, m, f.tree), newTermName("tree")))
+ c.universe.reify(new ReflectiveClosure(tree.splice, f.splice))
+ }
+}
diff --git a/test/files/run/t6221/Test_2.scala b/test/files/run/t6221/Test_2.scala
new file mode 100644
index 0000000000..9f6b2280a7
--- /dev/null
+++ b/test/files/run/t6221/Test_2.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ implicit class PimpedList[T](val list: List[T]) {
+ def query(predicate: ReflectiveClosure[T, Boolean]): List[T] = {
+ println(predicate.tree)
+ list filter predicate
+ }
+ }
+
+ List(1, 2, 3).query(x => x % 2 == 0)
+} \ No newline at end of file