Skip to content

Fix issue with static this references erroring in quoted code #22618

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

Merged
merged 1 commit into from
Feb 20, 2025

Conversation

jchyb
Copy link
Contributor

@jchyb jchyb commented Feb 17, 2025

Previously, inherited methods, even if accessed via static objects, were not able to be used in quotations, unless explicitly pointed to with a non-this prefix. This was due to the fact that during the cross-stage safety check, first the method itself was checked for if it was static (which for the inherited method, it was not), and if not, the prefix was checked further, erroring on any this tree found along the way.

This was fixed by allowing this trees if they point to static objects. This way not only is the initial issue fixed, but also we are able to freely reference static methods with this, like '{this.objectMethod} (whereas previously, only '{Object.objectMethod} or '{objectMethod} were allowed, despite them all pointing to the same static method).

Fixes #22592

Previously, inherited methods, even if accessed via static objects,
were not able to be used in quotations, unless explicitly pointed to
with a non-`this` prefix. This was due to the fact that during the
cross-stage safety check, first the method itself was checked for if it
was static (which for the inherited method, it was not), and if not,
the prefix was checked further, erroring on any `this` tree found along
the way.

This was fixed by allowing `this` trees if they point to static objects.
This way not only is the initial issue fixed, but also we are able to
freely reference static methods with `this`, like '{this.objectMethod}
(whereas previously, only '{Object.objectMethod} or '{objectMethod}
were allowed, despite them all pointing to the same static method).
Copy link
Member

@hamzaremmal hamzaremmal left a comment

Choose a reason for hiding this comment

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

I've pushed a bit the tests locally and everything behaves as expected:

import scala.quoted.*

trait Foo:
  def inherited = ()
  def inheritedArg(arg: Any) = ()

type HideBar = Bar
class Bar extends Foo:
  def local = ()
  def localArg(arg: Any) = ()

  val self: HideBar = this

  def macro01(using Quotes): Expr[Unit] = '{ local }
  def macro02(using Quotes): Expr[Unit] = '{ inherited }
  //def macro03(using Quotes): Expr[Unit] = '{ Bar.local }
  //def macro04(using Quotes): Expr[Unit] = '{ Bar.inherited }
  def macro05(using Quotes): Expr[Unit] = '{ this.local }
  def macro06(using Quotes): Expr[Unit] = '{ this.inherited }
  def macro07(using Quotes): Expr[Unit] = '{ self.local }
  def macro08(using Quotes): Expr[Unit] = '{ self.inherited }
  def macro09(using Quotes): Expr[Unit] = '{ localArg(this) }
  def macro10(using Quotes): Expr[Unit] = '{ inheritedArg(this) }
  //def macro11(using Quotes): Expr[Unit] = '{ Bar.localArg(this) }
  //def macro12(using Quotes): Expr[Unit] = '{ Bar.inheritedArg(this) }
  def macro13(using Quotes): Expr[Unit] = '{ this.localArg(this) }
  def macro14(using Quotes): Expr[Unit] = '{ this.inheritedArg(this) }
  def macro15(using Quotes): Expr[Unit] = '{ self.localArg(this) }
  def macro16(using Quotes): Expr[Unit] = '{ self.inheritedArg(this) }

and

import scala.quoted.*

trait Foo:
  def inherited = ()
  def inheritedArg(arg: Any) = ()

type HideBar = Bar.type
object Bar extends Foo:
  def local = ()
  def localArg(arg: Any) = ()

  val self: HideBar = this

  def macro01(using Quotes): Expr[Unit] = '{ local }
  def macro02(using Quotes): Expr[Unit] = '{ inherited }
  def macro03(using Quotes): Expr[Unit] = '{ Bar.local }
  def macro04(using Quotes): Expr[Unit] = '{ Bar.inherited }
  def macro05(using Quotes): Expr[Unit] = '{ this.local }
  def macro06(using Quotes): Expr[Unit] = '{ this.inherited }
  def macro07(using Quotes): Expr[Unit] = '{ self.local }
  def macro08(using Quotes): Expr[Unit] = '{ self.inherited }
  def macro09(using Quotes): Expr[Unit] = '{ localArg(this) }
  def macro10(using Quotes): Expr[Unit] = '{ inheritedArg(this) }
  def macro11(using Quotes): Expr[Unit] = '{ Bar.localArg(this) }
  def macro12(using Quotes): Expr[Unit] = '{ Bar.inheritedArg(this) }
  def macro13(using Quotes): Expr[Unit] = '{ this.localArg(this) }
  def macro14(using Quotes): Expr[Unit] = '{ this.inheritedArg(this) }
  def macro15(using Quotes): Expr[Unit] = '{ self.localArg(this) }
  def macro16(using Quotes): Expr[Unit] = '{ self.inheritedArg(this) }

@hamzaremmal hamzaremmal merged commit 3ae11ab into scala:main Feb 20, 2025
29 checks passed
@hamzaremmal hamzaremmal deleted the fix-i22592-inherited-in-quote branch February 20, 2025 13:36
@jchyb
Copy link
Contributor Author

jchyb commented Feb 20, 2025

Thank you @hamzaremmal! It was a good idea to test those additional cases, especially the HideBar ones (I hadn't thought of that case).

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.

Inherited methods cannot be called from splice
3 participants