Skip to content

Expand non-transparent macros after Typer #9984

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

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented Oct 12, 2020

The technical change

  • Inline transparent inline definitions in typer
  • Inline other inline after typer.

Sematic changes

  • inline given
    • transparent inline given f: T = ...: does the same as all inline definition did before
      • transparent inline given f: T = (...): T can be used to emulate the previous version inline given
    • inline given f: T = ...: if an error is emitted during the inlining then the error is reported to the user.
  • scala.compiletime.testing.{typeChecks, typeCheckErrors} must be used directly or inside a transparent inline
  • Add missing type parameter bound checks for non-transparent inlines (see Missing bounds check for transparent inline type parameters #10552). Transparent inlines still have this issue.

@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch 3 times, most recently from af0ed15 to 4da92f1 Compare October 13, 2020 11:11
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch 4 times, most recently from 1a94a4c to f1afb7c Compare October 22, 2020 14:36
@nicolasstucki nicolasstucki self-assigned this Oct 23, 2020
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch 4 times, most recently from f42cdcc to 8043ce0 Compare October 30, 2020 12:28
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch from 8043ce0 to 64e5eab Compare November 3, 2020 14:29
@nicolasstucki nicolasstucki modified the milestones: 3.0.0, 3.0.0-M1, 3.0.0-M2 Nov 4, 2020
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch from 64e5eab to 6535013 Compare November 9, 2020 09:19
@nicolasstucki nicolasstucki modified the milestones: 3.0.0-M2, 3.0.0-RC1 Nov 19, 2020
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch 3 times, most recently from 9954554 to 3b874d9 Compare November 23, 2020 13:16
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch 3 times, most recently from 4199f34 to 0c61b36 Compare November 30, 2020 09:07
@dottybot
Copy link
Member

dottybot commented Feb 6, 2021

performance test scheduled: 9 job(s) in queue, 1 running.

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.

Can we try without overriding typer and test performance again?

@@ -272,6 +276,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
checkNoConstructorProxy(tree)
transformSelect(tree, Nil)
case tree: Apply =>
if tree.symbol.is(Inline) && !Inliner.inInlineMethod then
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed here? Don't we get to an Ident or Select eventually, which sets needsInlining. Also, why do we handle Apply here but not TypeApply. If this is in fact needed for some reason it would be good to add a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is redundant. I removed it.

@@ -329,6 +338,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
)
}
case tree: ValDef =>
if tree.symbol.is(Inline, butNot = Param) then
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this be triggered by

inline val x = 2

? Those things are extremely common, so we should avoid running the inliner just for these.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, then we would need to check that the RHS of an inline val is a constant after the Inlining phase. I try to fit it into another phase.

Copy link
Contributor

Choose a reason for hiding this comment

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

That would cause many more traversals, so yes, good to do this somewhere else.

@@ -1235,8 +1254,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
super.ensureAccessible(tpe, superAccess, pos)
}

override def typed(tree: untpd.Tree, pt: Type = WildcardType)(using Context): Tree =
Copy link
Contributor

Choose a reason for hiding this comment

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

In fact, it might be better to do this test only in typedApply and typedTypeApply. Concentrating everything in typed is more elegant but might have performance implications. I am also nervous about making calls to typed more megamorphic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the logic back to typedApply, typedTypeApply, typedIdent and typedSelect. I kept the rest of the refactoring which avoids the duplication of the code that is now in needsInlining.

@odersky odersky assigned nicolasstucki and unassigned odersky Feb 6, 2021
@dottybot
Copy link
Member

dottybot commented Feb 6, 2021

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/9984/ to see the changes.

Benchmarks is based on merging with master (a63b1d1)

@nicolasstucki
Copy link
Contributor Author

test performance with #quotes please

@dottybot
Copy link
Member

dottybot commented Feb 8, 2021

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

dottybot commented Feb 8, 2021

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/9984/ to see the changes.

Benchmarks is based on merging with master (16bf86f)

Those are checked by the Ident or Select of their function parts
@nicolasstucki nicolasstucki force-pushed the move-blackbox-macro-exapnsion-after-typer branch from 981defd to bdf2482 Compare February 8, 2021 10:26
@nicolasstucki nicolasstucki requested a review from odersky February 8, 2021 14:06
@nicolasstucki
Copy link
Contributor Author

@liufengyun could you have a look at the new commits?

Copy link
Contributor

@liufengyun liufengyun left a comment

Choose a reason for hiding this comment

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

LGTM

@deusaquilus
Copy link
Contributor

deusaquilus commented Feb 15, 2021

@nicolasstucki It seems like this is working for me out of the box! I don't need to modify anything.
I do have one question though. If the typing phase is now before blackbox macros, how come the Quill parser is running after a typing mistake.

Say I make a typing mistake on purpose:

    inline def q = quote {
      query[SanePerson] // hello
    }
    inline def name(p: SanePerson) = p.name
    inline def qq = quote {
      q.map(p => name(p.name)) // purposely making a typing mistake
    }

Why does the macro even run if there was an error on a previous phase?

image

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