diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-07-08 16:05:05 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-07-08 16:05:05 -0700 |
commit | 72863241ead712ace45071a21b84288959f6ce53 (patch) | |
tree | 2dc6ad982cc7cac0955042f9da9cf59568ee81df | |
parent | 9e064f783e7ee42b9d27655e2b15d830f8bae5f0 (diff) | |
parent | ede32ba3421be657a4369b847e60d5fb2b9def14 (diff) | |
download | scala-72863241ead712ace45071a21b84288959f6ce53.tar.gz scala-72863241ead712ace45071a21b84288959f6ce53.tar.bz2 scala-72863241ead712ace45071a21b84288959f6ce53.zip |
Merge pull request #2650 from paulp/issue/6221
SI-6221 inference with Function1 subtypes.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 17 | ||||
-rw-r--r-- | test/files/neg/names-defaults-neg.check | 9 | ||||
-rw-r--r-- | test/files/neg/t1181.check | 6 | ||||
-rw-r--r-- | test/files/neg/t556.check | 4 | ||||
-rw-r--r-- | test/files/pos/t6221.scala | 29 | ||||
-rw-r--r-- | test/files/run/t6221.check | 1 | ||||
-rw-r--r-- | test/files/run/t6221/Macros_1.scala | 22 | ||||
-rw-r--r-- | test/files/run/t6221/Test_2.scala | 10 |
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 353e8e4810..0ae68d2ba1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2797,16 +2797,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 { @@ -2856,7 +2851,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 |