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

Improve the Synthetic's tree so it can represent the context param application (with using) #2460

Open
Tracked by #13135
tanishiking opened this issue Aug 31, 2021 · 5 comments

Comments

@tanishiking
Copy link
Member

See the original discussion: scala/scala3#13288 (comment)

Background

Scala3's SemanticDB extractor extracts context params application as Synthetic. scala/scala3#13288

For example

def foo(x: Int)(using Int) = ???
import Foo.given Int
def m() = foo(0)

// synthetics
def m() = foo(0)(x)

Synthetic(
  <foo(0)>,
  ApplyTree(
    OriginalTree(<foo(0)>),
    List(
      IdTree(<x>),
    )
  )
)

Potential problem

  • In the above example, there's no way to tell the synthesized symbol x is an implicit parameter or context params.
    • Because the given argument is imported by import Foo.given Int and there's no SymbolInformation for x is available from the TextDocument.
    • If x is defined in the same TextDocument (e.g. def m(using x: Int) = foo(0)), we can lookup the SymbolInformation and see it's properties.
  • Lack of the symbol's property could be a problem for
    • metals's show implicit arguments feature will show foo(0)(x) which doesn't compile, instead of foo(0)(using x).
    • Maybe in the future, some tools will suffer from the lack of information?

So the discussion is Should Synthetic have complete information to re-construct the original program from the tree?

Counter argument

It might not a big problem for tooling.

  • Though metals's show implicit arguments feature ends up showing foo(0)(x) which is uncompilable decoration, the decorations are never compiled.
  • And there are no tools that use the Synthetic for transforming the original source, as far as I know.

Potential solution

  • Add a flag to ApplyTree so we can tell it is a context-param or implicit param.
  • Insert SymbolInformation for the context-param argument.
    • which contradicts with the original design of SymbolInformation, but I think it works well.
      • "Symbols" is a section of a TextDocument that stores information about Symbols that are defined in the underlying document.

  • Add a flag to IdTree ?
@tanishiking
Copy link
Member Author

I personally think this issue is not so highly prioritized because of the Counter arguments I wrote.

@tgodzik
Copy link
Collaborator

tgodzik commented Aug 31, 2021

Thanks for raising this! Do we know if Scala 3 will drop implicit parameters completely at some point? In that case synthetic ApplyTree cannot really apply to implicits in the future just using.

We could add UsingApplyTree similar like we do for different Apply, which would solve this issue I think.

@bishabosha
Copy link

can you add a flags field to ApplyTree? so generalised for future application kinds?

@tgodzik
Copy link
Collaborator

tgodzik commented Aug 31, 2021

Historically, we don't add boolean flags to trees, but instead add a separate tree node. I think we should be consistent in that regards.

@tanishiking
Copy link
Member Author

👍 to ApplyUsingTree

message ApplyUsingTree {
  Tree function = 1;
  repeated Tree arguments = 2;
}

Since scalameta parses the following code to the scalameta AST below.

def f(using TC, Int) = ???
f(using tc, 1)

Term.ApplyUsing(Term.Name("f"), List(Term.Name("tc"), Lit.Int(1)))

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