Skip to content
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

Add quoted pattern type splices #6504

Merged
merged 8 commits into from
Jul 2, 2019

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented May 14, 2019

Support type spliced in quoted patterns

New quoted patterns

We introduce type splices $t in type positions. In the following example we want to match a list of any element type

case '{ ($ls: List[$t]).filter($f).filter($g) } =>
  // `t` is of type `Type[T$1]` for some unknown T$1
  // `t` is implicitly available
  '{ $ls.filter(x => ${f('x)} && ${g('x)}) }

If ls is matched against a List[Int] the type t will be Type[Int] or if it was a List[Foo] it would return a Type[Foo].

Note that in $t, t is a pattern and therefore is just a name binding. A fresh type is generated for it and cannot be named.

We can also splice on a type definition type $t. Unlike the previous variant the type will be named $t and can be used by referencing it using back-ticks and could be bounded.

case '{ type $t; ($ls: List[`$t`]).filter($f).filter($g) } =>
  // `t` is of type `Type[`$t`]` for some unknown type `$t`
  // `t` is implicitly available
  '{ $ls.filter(x => ${f('x)} && ${g('x)}) }

Overview of desugaring and tying

case '{ ($ls: List[$t]) } => ...

For each type splice we will create a new type binding in the pattern match ($t @ _ in this case) and a corresponding type in the quoted pattern as a hole (@patternBindHole type $t in this case). All these generated types are inserted at the start of the quoted code.

case scala.internal.quoted.Matcher.unapply[
    Tuple1[$t @ _], // Type binging definition
    Tuple2[Type[$t], Expr[List[$t]]] // Typing the result of the pattern match
  ](
    Tuple2.unapply
      [Type[$t], Expr[List[$t]]] //Propagated from the tuple above
      (implict t @ _, ls @ _: Expr[List[$t]])
  )(
    '{ // Runtime quote Matcher.unapply uses to mach against
        @scala.internal.Quoted.patternBindHole type $t
        scala.internal.Quoted.patternHole[List[$t]]
     }, 
     true, // If there is at least one type splice. Used to instantiate the context with or without GADT constraints
    x$2 // tasty.Reflection instance
  ) => ...

For type definition we do the same as above, except that we just reuse type $t as our @patternBindHole type $t.

case '{ type $t; ($ls: List[`$t`]) } =>

@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch 7 times, most recently from caec229 to ccd2222 Compare May 14, 2019 18:18
@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch 9 times, most recently from a5374ae to d9fd1f0 Compare May 22, 2019 14:40
@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch 8 times, most recently from 50c6137 to 02ee27f Compare May 28, 2019 14:40
@nicolasstucki nicolasstucki marked this pull request as ready for review May 28, 2019 15:31
@nicolasstucki nicolasstucki requested a review from odersky May 28, 2019 15:31
@nicolasstucki
Copy link
Contributor Author

Rebased

Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise LGTM

compiler/src/dotty/tools/dotc/ast/Trees.scala Outdated Show resolved Hide resolved
compiler/src/dotty/tools/dotc/ast/tpd.scala Show resolved Hide resolved
val patType = defn.tupleType(splices.tpes.map(_.widen))
val splicePat = typed(untpd.Tuple(splices.map(untpd.TypedSplice(_))).withSpan(quoted.span), patType)

val (typeBindings, shape, splices) = splitQuotePattern(quoted1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a description of the scheme for translating patterns to doc comment above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

ref(defn.InternalQuoted_patternHoleR).appliedToType(splice.tpe).withSpan(splice.span)
}

/** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a description of the scheme for translating patterns to doc comment above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@odersky odersky assigned nicolasstucki and unassigned odersky Jun 26, 2019
@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch from 723df7f to 486d552 Compare June 28, 2019 11:14
@nicolasstucki
Copy link
Contributor Author

Rebased

@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch from 145f33b to bf29a51 Compare June 28, 2019 20:06
@nicolasstucki nicolasstucki added this to the 0.17 Tech Preview milestone Jun 30, 2019
@nicolasstucki
Copy link
Contributor Author

Will need to be rebased

@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch 2 times, most recently from fc4b9e8 to c2fd6e5 Compare July 1, 2019 13:15
@nicolasstucki
Copy link
Contributor Author

@odersky Requested changes have been addressed.

@nicolasstucki nicolasstucki force-pushed the add-quoted-match-type-splcies branch from c2fd6e5 to 732033f Compare July 2, 2019 12:03
@nicolasstucki
Copy link
Contributor Author

Rebased

@odersky odersky merged commit 0e5e541 into scala:master Jul 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants