From cc2e613189ce78d160ab88281736df948361c6ad Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 2 Feb 2015 15:11:43 +1000 Subject: SI-9131 Fix use of apply syntactic sugar with by-name param After typechecking a tree, the typer adapts it to the current mode and expected type. If we are in FUNmode (typechecking the qualifier of a value- or type-application), and the tree does not already have a MethodType or PolyType, it is reinterepreted as `qual.apply`. In doing so, `insertApply` stabilizes the type of `qual`, e.g. replacing `Ident(foo).setType(typeOf[Int])` with `Ident(foo).setType(typeOf[foo.type])`. However, this does not check for by-name parameters, which cannot form the basis for a singleton type, as we can see by trying that directly: ``` scala> def foo(a: => String) { type T = a.type } :7: error: stable identifier required, but a.type found. def foo(a: => String) { type T = a.type } ^ ``` When I last touched this code in SI-6206 / 267650cf9, I noted: // TODO reconcile the overlap between Typers#stablize and TreeGen.stabilize I didn't get around to that, but Adriaan gave that code a thorough cleanup in fada1ef6b. It appears that on the back of his work, we can now remove the local stabilization logic in `insertApply` in favour of `TreeGen.stabilize`. We then avoid the ill-formed singleton type, and the spurious "apply is not a member" type error. I did have to modify `isStableIdent` to check the symbol's info in addition to the tree's type for by-name-ness. --- test/files/pos/t9131.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/files/pos/t9131.scala (limited to 'test/files/pos') diff --git a/test/files/pos/t9131.scala b/test/files/pos/t9131.scala new file mode 100644 index 0000000000..1a186a0a24 --- /dev/null +++ b/test/files/pos/t9131.scala @@ -0,0 +1,12 @@ +class Test { + + def byNameFunc(f: (=> (() => Any)) => Any): Unit = () + + def test = { + // "value apply is not a member of => () => Any" + byNameFunc(z => z()) + // okay + byNameFunc(z => z.apply()) + byNameFunc(z => {val f = z; f()}) + } +} -- cgit v1.2.3