summaryrefslogtreecommitdiff
path: root/test/files/neg/t5903a.check
Commit message (Collapse)AuthorAgeFilesLines
* SI-7897, SI-6675 improves name-based patmatPaul Phillips2013-12-151-1/+1
| | | | | | | | | | | | | | | | | | | This emerges from a recent attempt to eliminate pattern matcher related duplication and to bake the scalac-independent logic out of it. I had in mind something a lot cleaner, but it was a whole lot of work to get it here and I can take it no further. Key file to admire is PatternExpander.scala, which should provide a basis for some separation of concerns. The bugs addressed are a CCE involving Tuple1 and an imprecise warning regarding multiple pattern crushing. Editorial: auto-tupling unapply results was a terrible idea which should never have escaped from the crib. It is tantamount to purposely throwing type safety down the toilet in the very place where people need type safety the most. See SI-6111 and SI-6675 for some other comments.
* SI-7895 Avoid cascade of "symbol not found" in pattern matchesJason Zaugg2013-10-091-4/+1
| | | | | | If we can't type check the `Foo` in `case Foo(a, b) => (a, b)`, we should enter error symbols for `a` and `b` to avoid further errors being reported in the case body.
* SI-5903 extractor macrosEugene Burmako2013-08-181-0/+7
Establishes a pattern that can be used to implement extractor macros that give the programmer control over signatures of unapplications at compile-time. === The pattern === In a nutshell, given an unapply method (for simplicity, in this example the scrutinee is of a concrete type, but it's also possible to have the extractor be polymorphic, as demonstrated in the tests): ``` def unapply(x: SomeType) = ??? ``` One can write a macro that generates extraction signatures for unapply on per-call basis, using the target of the calls (c.prefix) and the type of the scrutinee (that comes with x), and then communicate these signatures to the typechecker. For example, here's how one can define a macro that simply passes the scrutinee back to the pattern match (for information on how to express signatures that involve multiple extractees, visit https://github.com/scala/scala/pull/2848). ``` def unapply(x: SomeType) = macro impl def impl(c: Context)(x: c.Tree) = { q""" new { class Match(x: SomeType) { def isEmpty = false def get = x } def unapply(x: SomeType) = new Match(x) }.unapply($x) """ } ``` In addition to the matcher, which implements domain-specific matching logic, there's quite a bit of boilerplate here, but every part of it looks necessary to arrange a non-frustrating dialogue with the typer. Maybe something better can be done in this department, but I can't see how, without introducing modifications to the typechecker. Even though the pattern uses structural types, somehow no reflective calls are being generated (as verified by -Xlog-reflective-calls and then by manual examination of the produced code). That's a mystery to me, but that's also good news, since that means that extractor macros aren't going to induce performance penalties. Almost. Unfortunately, I couldn't turn matchers into value classes because one can't declare value classes local. Nevertheless, I'm leaving a canary in place (neg/t5903e) that will let us know once this restriction is lifted. === Use cases === In particular, the pattern can be used to implement shapeshifting pattern matchers for string interpolators without resorting to dirty tricks. For example, quasiquote unapplications can be unhardcoded now: ``` def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], ...) = { ... fun.tpe match { case ExtractorType(unapply) if mode.inPatternMode => // this hardcode in Typers.scala is no longer necessary if (unapply == QuasiquoteClass_api_unapply) macroExpandUnapply(...) else doTypedUnapply(tree, fun0, fun, args, mode, pt) } } ``` Rough implementation strategy here would involve writing an extractor macro that destructures c.prefix, analyzes parts of StringContext and then generates an appropriate matcher as outlined above. === Implementation details === No modifications to core logic of typer or patmat are necessary, as we're just piggybacking on https://github.com/scala/scala/pull/2848. The only minor change I introduced is a guard against misbehaving extractor macros that don't conform to the pattern (e.g. expand into blocks or whatever else). Without the guard we'd crash with an NPE, with the guard we get a sane compilation error.