Skip to content

Fix Java generic signatures for context functions#25632

Open
SolalPirelli wants to merge 2 commits intoscala:mainfrom
dotty-staging:solal/returned-context-function-signature
Open

Fix Java generic signatures for context functions#25632
SolalPirelli wants to merge 2 commits intoscala:mainfrom
dotty-staging:solal/returned-context-function-signature

Conversation

@SolalPirelli
Copy link
Copy Markdown
Contributor

Fixes #10039

How much have you relied on LLM-based tools in this contribution?

not

How was the solution tested?

test from the issue turned into a fully automated one

@SolalPirelli SolalPirelli marked this pull request as ready for review March 26, 2026 15:20
@SolalPirelli SolalPirelli requested a review from bishabosha March 26, 2026 15:21
Copy link
Copy Markdown
Member

@tanishiking tanishiking left a comment

Choose a reason for hiding this comment

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

Nice catch! I left some concerns but otherwise looks good

// Returned context functions are erased by putting their parameters into the method's parameters,
// so we must duplicate that logic here
case AppliedType(tycon, args) if tycon.typeSymbol.name.isContextFunction =>
vparams ++= args.take(args.length - 1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We might want to filter out .filterNot(_.hasAnnotation(defn.ErasedParamAnnot)) similar to for normal parameters, otherwise, erased type parameter will remain in generic signature, while it is removed in descriptor ?

import language.experimental.erasedDefinitions

class CanSerialize extends compiletime.Erased

object Test:
  trait Ctx
  def foo(x: Int): CanSerialize ?=> Ctx ?=> String = "foo"

(I didn't know about this feature until I see the vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot)) line above :p
https://docs.scala-lang.org/scala3/reference/experimental/erased-defs.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it seems that for method that contains Erased parameter, the result type will be RefinedType instead of AppliedType.

We'd like to pattern match against

case defn.FunctionTypeOfMethod(mt: MethodType) if mt.isContextualMethod

?

case mtd: MethodType =>
vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot))
recur(mtd.resType)
mtd.resType match
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
mtd.resType match
mtd.resType.dealias match

otherwise, it doesn't catch the following case?

object Test:
   trait Ctx
   type Handler = Ctx ?=> String
   def foo(x: Int): Handler = "hello"

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.

Java generic signature and descriptor alignment for context functions

2 participants