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

Open code patterns have issues when substituting arguments with a generic/bound type. #15165

Closed
rmgk opened this issue May 11, 2022 · 4 comments · Fixed by #16951
Closed

Open code patterns have issues when substituting arguments with a generic/bound type. #15165

rmgk opened this issue May 11, 2022 · 4 comments · Fixed by #16951
Assignees
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug
Milestone

Comments

@rmgk
Copy link

rmgk commented May 11, 2022

Compiler version

3.1.2 (also tested some 3.1 and 3.2 nightly versions)

Minimized example

Consider we want to transform val bindings into function application, that is, we want to take the following snippet

  valToFun {
    val a: Int = 1
    a + 1
  }

and transform it into (x => x + 1).apply(1) using the valToFun macro below:

import scala.quoted.*

inline def valToFun[T](inline expr: T): T =
  ${ impl('expr) }

def impl[T: Type](expr: Expr[T])(using quotes: Quotes): Expr[T] =
  expr match
    case '{ { val ident = ($a: α); $rest(ident): T } } =>
      '{
        { (y: α) =>
          ${
            val bound   = '{ ${ rest }(y) }
            Expr.betaReduce(bound)
          }
        }.apply($a)
      }

Output

This outputs

undefined: ident.+ # -1: TermRef(TermRef(NoPrefix,val ident),+) at inlining [7:5]

pointing at the a of a + 1

Expectation

Should compile and work just fine, as slight variants also work fine:

It works when adding type ascription's to the use site:

  valToFun {
    val a: Int = 1
    (a: Int) + 1
  }

It also works when replacing the generic type extracted in the quote by an explicit type (i.e., replace α with Int)

@rmgk rmgk added the stat:needs triage Every issue needs to have an "area" and "itype" label label May 11, 2022
@nicolasstucki nicolasstucki self-assigned this May 12, 2022
@nicolasstucki nicolasstucki added itype:bug area:metaprogramming:quotes Issues related to quotes and splices and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 12, 2022
@nicolasstucki
Copy link
Contributor

Minimized

import scala.quoted.*

inline def valToFun[T](inline expr: T): T =
  ${ impl('expr) }

def impl[T: Type](expr: Expr[T])(using quotes: Quotes): Expr[T] =
  expr match
    case '{ { val ident = ($a: α); $rest(ident): T } } =>
      '{ { (y: α) => $rest(y) }.apply(???) }

@nicolasstucki
Copy link
Contributor

Minimization

def test =  { (y: Int) => y + 1 }.apply(???)

The issue seems to be related to beta reduction with arguments of type Nothing.

@nicolasstucki
Copy link
Contributor

The issue is that we beta reduce into

val y: Nothing = ???
y.+(1)

@nicolasstucki
Copy link
Contributor

Second issue is that when we match

    case '{ { val ident = ($a: α); $rest(ident): T } } =>

rest is '{ (ident: α) => ident.+(1) } instead of '{ (ident: Int) => ident.+(1) }

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Feb 16, 2023
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Feb 17, 2023
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Feb 17, 2023
To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a `Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes scala#15165
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Feb 17, 2023
To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a `Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes scala#15165
nicolasstucki added a commit that referenced this issue Feb 21, 2023
Use parameter type as binding type when the argument is of type
`Nothing` or `null`.

Fixes part of #15165
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Feb 21, 2023
To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a `Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes scala#15165
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 2, 2023
To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a `Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes scala#15165
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 3, 2023
To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a `Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes scala#15165
nicolasstucki added a commit that referenced this issue Mar 3, 2023
…6951)

To be able to construct the lambda returned by the HOAS pattern we need:
first resolve the type variables and then use the result to construct
the
signature of the lambdas.

To simplify this transformation, `QuoteMatcher` returns a
`Seq[MatchResult]`
instead of an untyped `Tuple` containing `Expr[?]`. The tuple is created
once we have accumulated and processed all extracted values.

Fixes #15165
@Kordyjan Kordyjan added this to the 3.3.1 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants