Skip to content

Match fails using quasiquotes #8600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Blaisorblade opened this issue Mar 24, 2020 · 6 comments · Fixed by #8684
Closed

Match fails using quasiquotes #8600

Blaisorblade opened this issue Mar 24, 2020 · 6 comments · Fixed by #8684

Comments

@Blaisorblade
Copy link
Contributor

Blaisorblade commented Mar 24, 2020

The issue is described in https://users.scala-lang.org/t/implementing-map-fusion-with-dotty-macros/5791/4?u=blaisorblade — sorry for not minimizing it further. Basically, the match in

  def mapImpl[A: Type, B: Type] (first: Expr[Pipe[A]], fn: Expr[A => B])(using qctx: QuoteContext): Expr[Pipe[B]] = {
    first match {
      case '{ Mapped($iFirst, $iFn) } =>
        '{ Mapped($iFirst, $iFn andThen $fn) }
      case _ =>
        '{ Mapped($first, $fn) }
    }
  }

fails to match against Mapped(foo, bar) (as produced by macro Source(List(1, 2, 3)).map(x => x + 1)). Using tasty reflection, I can make that match work by stripping Typed and Inlined nodes.
Additionally, I wanted to match against TypeApply by something like
case '{ Mapped[$A, $B]($iFirst, $iFn) } => (or using _ for $A), but I could not find a working syntax to express that.

To reproduce, check out https://github.com/Blaisorblade/dotty-map-fusion-staging-experiment.

@Blaisorblade
Copy link
Contributor Author

Based on followup, it seems that you must use something like $expr : <type> to match against a Typed node — but $expr : $type gives $expr an unspecified type so the right pattern was case '{ Mapped.apply[$a, A]($first, $lfn): Pipe[A] } =>.

@biboudis
Copy link
Contributor

Is this a documentation issue or an inference issue, because I saw that this worked in the end:

'{ Mapped.apply[$a, A]($first, $lfn): Pipe[A]}

@nicolasstucki I think we can document this for now. WDYT?

https://github.com/Blaisorblade/dotty-map-fusion-staging-experiment/pull/1/files

@Blaisorblade
Copy link
Contributor Author

It's at least a documentation issue; once one describes what's supposed to happen, some more bugs might be there...

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Mar 27, 2020

I saw something similar when I had an inline parameter that came from a blackbox inline. There, the extra ascription appears as part of the encoding of the blackbox inline. Is this the case for this one?

I wonder if we should be lenient and match expressions as if they were not there (as long as types match). We already ignore them on the pattern side. See Matcher.scala#L178-L182.

@Blaisorblade
Copy link
Contributor Author

Whence the Typed node

I saw something similar when I had an inline parameter that came from a blackbox inline. There, the extra ascription appears as part of the encoding of the blackbox inline. Is this the case for this one?

That's my assumption; there's a variant of this example without macros and without need for such annotations.

Doc issue: "Typed matches" are undocumented

The only documented syntax is $x: $t, and IIUC it's not documented as syntax for matching Typed nodes, but as syntax for matching arbitrary nodes and capturing their type. Which is it?

http://dotty.epfl.ch/docs/reference/metaprogramming/macros.html#recovering-precise-types-using-patterns

Specifying the semantics of typed matches in quasiquotes

I wonder if we should be lenient and match expressions as if they were not there (as long as types match). We already ignore them on the pattern side. See Matcher.scala#L178-L182 .

That might be a good idea, but then the problem remains when types don't match. The behavior in that case becomes part of the API, so it will eventually have to be documented.

Doc issue: It's unclear how to write quasiquote matches

I'm fine with being as explicit '{ Mapped.apply[$a, A]($first, $lfn): Pipe[A]}, but that should be made clear, because there are limits to trial and error; I did try something like that, but not exactly this variant, and I got errors (probably on Mapped.apply[$A, $B]($first, $lfn): $t or some permutation like that).

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 7, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 7, 2020
@nicolasstucki nicolasstucki linked a pull request Apr 7, 2020 that will close this issue
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 7, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 7, 2020
nicolasstucki added a commit that referenced this issue Apr 8, 2020
Fix #8600: Match trough type ascription
@Blaisorblade
Copy link
Contributor Author

Ah, #8687 is also relevant. Cool, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants