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

Type is simplified too much before being passed to an implicit macro #17544

Open
neko-kai opened this issue May 19, 2023 · 3 comments
Open

Type is simplified too much before being passed to an implicit macro #17544

neko-kai opened this issue May 19, 2023 · 3 comments

Comments

@neko-kai
Copy link
Contributor

Compiler version

3.3.0-RC6 and 3.2.2

Minimized code

// file:exampleMacro.scala

package example

import scala.quoted.*

case class X[T](x: String)

object X {
  inline given exampleMacro[T]: X[T] = ${ exampleMacroImpl[T] }

  def exampleMacroImpl[T: Type](using qctx: Quotes): Expr[X[T]] = {
    '{ X[T](${ Expr(Type.show[T]) }) }
  }
}
// file:example.scala

package example

trait TraitSuper
trait TraitSub extends TraitSuper

@main def main: Unit = {
  println(X.exampleMacro[TraitSuper & TraitSub].x) // outputs: verbatim type tree
  println(implicitly[X[TraitSuper & TraitSub]].x) // output: modified type tree
}

Output

example.TraitSuper & example.TraitSub
example.TraitSub

Expectation

The type received on the macro side differs when the macro is invoked implicitly versus when the macro is invoked explicitly – expected to receive the same type tree in both cases.

@neko-kai neko-kai added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 19, 2023
neko-kai added a commit to zio/izumi-reflect that referenced this issue May 20, 2023
…t fail because of scala/scala3#17544

Add `removeIntersectionTautologies` and `removeUnionTautologies` methods to `LightTypeTag`

Ensure at type level that IntersectionReference and UnionReference can't be nested.

Fix maybeUnion not removing Nothing from unions and not widening to top types
neko-kai added a commit to zio/izumi-reflect that referenced this issue May 20, 2023
…t fail because of scala/scala3#17544 (#393)

* Try to unify Scala 2 and 3 handling of tautological intersections, but fail because of scala/scala3#17544

Add `removeIntersectionTautologies` and `removeUnionTautologies` methods to `LightTypeTag`

Ensure at type level that IntersectionReference and UnionReference can't be nested.

Fix maybeUnion not removing Nothing from unions and not widening to top types

* Fix Scala 2 build

* Fix Scala 2.11 build

* Fix Scala 2.12 build

* Fix mima error on 2.12
@bishabosha
Copy link
Member

bishabosha commented May 22, 2023

These types are equivalent (=:=), so you should not rely upon structural equality, is there another case where they are not equivalent?

@neko-kai
Copy link
Contributor Author

neko-kai commented May 22, 2023

@bishabosha
Theoretically I shouldn't rely on the way equivalent types are written, but to do so in the case of izumi-reflect, I would have to perform a quadratic operation at runtime to remove the redundant members of intersection when constructing a Tag. Since when used in ZIO, intersection tags with type parameters can appear in hot spots, I would rather avoid doing that - although maybe that's the right thing to do anyway. This is the case that surfaces this - zio/izumi-reflect@339b5b8#diff-9d5c97bbb6049264132a5d88dbee33be24fcb9f2b14ef8ba542b400c9bbf532aR177
Since in def tag1[T: Tag]: Tag[T with Trait1] = Tag[T with Trait1] I can't tell what T is until runtime, I can't remove Trait1 from the intersection before runtime. Now when a concrete Tag is summoned for Trait3[Dep] with Trait1 the Trait1 doesn't get into the macro and the tags end up unequal wrt their serialized form.

@bishabosha
Copy link
Member

bishabosha commented May 22, 2023

could you benchmark this slow path in "typical" use cases?

@szymon-rd szymon-rd added area:inline and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants