Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

4 participants