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

Subtype relation for refined type fails #481

Open
thierry-st opened this issue Sep 21, 2024 · 8 comments
Open

Subtype relation for refined type fails #481

thierry-st opened this issue Sep 21, 2024 · 8 comments
Labels
💎 Bounty bug Something isn't working

Comments

@thierry-st
Copy link

izumi.reflect.Tag subtype relationship is not faithful to compiled ones.

Here is a minimal repro (Scala 2 syntax to allow testing various versions):

import izumi.reflect.Tag

trait A {
  type T
}

trait AInt extends A {
  override type T = Int
}

object App extends App {
  implicitly[AInt <:< A { type T = Int }] // true
  println(Tag[AInt].tag <:< Tag[A { type T = Int }].tag) // false
}

Scastie link

It might be more efficient to tackle this issue and #469 both at once, but they seemed different enough to me to warrant different posts.

It might help to know that the issue is not present for Scala >= 3.2 and izumi-reflect =< 2.2.5. But the issue is present if violating any of these bounds (Scala 2 and/or izumi-reflect >= 2.3.0).

I will report soon the corresponding issue on the ZIO repo.

@thierry-st
Copy link
Author

Here is the link to the corresponding ZIO issue: #9210

@pshirshov
Copy link
Member

pshirshov commented Sep 22, 2024

We would need to preserve full member information in order to support this. Doable but not easy. My primary concerns are tag size and performance.

@neko-kai
Copy link
Member

neko-kai commented Sep 22, 2024

@thierry-st Version 2.3.0 is the one that added structural type / refinement support to Scala 3 version. Before that, the comparison on Scala 3 was only between AInt and A, ignoring the refinement, that's why it succeeded on previous versions.

Currently type/value members are not present at all in izumi-reflect type model for concrete types - they only arise when comparisons between refinements happen.

Since there's no data about type T in AInt tag, the comparison with any refinement will fail.

Changing the design and adding type member data is possible, but not trivial.

(#469 is unfortunately not related)

neko-kai added a commit that referenced this issue Sep 22, 2024
@neko-kai
Copy link
Member

neko-kai commented Sep 22, 2024

@thierry-st Does this limitation of the model make some real-world usages too painful? If not, we'll probably not work on fixing this – although we will accept pull requests.

For now, I've added this issue to the list of known limitations.

Note that the more common opposite case, e.g. Aux pattern, where a refinement is a subtype of a concrete type, is supported.

@thierry-st
Copy link
Author

thierry-st commented Sep 22, 2024

Thanks very much for the clear explanations and the addition to known limitations!

As for painfulness of real-world usages, in the ZIO environment, the limitation can easily be overcome. So the only downside is cognitive cost (ZIO users need to be aware of this issue). Since nobody reacted so far on the ZIO issue, I'm inclined to leave it as is.

Just to let people know, I'm not going to attempt a PR for this, so feel free to go for it!

@pshirshov
Copy link
Member

is cognitive cost

Unfortunately, it seems to be nearly impossible to implement a perfect RTTI at macro level, and the previous attempt made by the compiler team (scala-reflect) had many its own shortcomings. So, we may patch various leaks but it's not always feasible (and not always possible) to do so.

If we can't preserve the full type structures until run-time and bring the full compiler (or, at least, a significant part of the typer) there, discrepancies will always be there together with the associated cognitive cost.

Still, the library is good enough to just work in vast majority of the usecases. 🤷‍♀️

@jdegoes
Copy link
Member

jdegoes commented Nov 8, 2024

/bounty $750

Copy link

algora-pbc bot commented Nov 8, 2024

💎 $750 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #481 with your implementation plan
  2. Submit work: Create a pull request including /claim #481 in the PR body to claim the bounty
  3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Thank you for contributing to zio/izumi-reflect!

Add a bountyShare on socials

@pshirshov pshirshov added the bug Something isn't working label Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💎 Bounty bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants