Skip to content

summonInline still fails #12415

Closed
Closed
@soronpo

Description

@soronpo

Possibly related to #12379
@michelou
There are still differences between summonInline and a using argument.

Compiler version

3.0 master branch

Minimized code

import scala.language.implicitConversions
import scala.compiletime.*

object Good:
  trait ~[Of]:
    type To <: Of
    val value : To
  object ~ :
    trait Conversion[Of, From]:
      type To <: Of
      def apply(from : From) : To
    transparent inline implicit def conv[Of, From](inline from : From)(using c : Conversion[Of, from.type]) : ~[Of] =
      new ~[Of]:
        type To = c.To
        val value : To = c(from)

  class Foo[T](value : T)
  transparent inline given [F <: Int] : ~.Conversion[Foo[_], F] = new ~.Conversion[Foo[_], F] {
    type To = Foo[F]
    def apply(from: F): Foo[F] = new Foo(from)
  }
  def foo(x : ~[Foo[_]]) = x.value

  val f1 = foo(1)
  val f1_ : Foo[1] = f1
  val one = 1
  val fOne = foo(one)
  val fOne_ : Foo[one.type] = fOne


object Bad:
  trait ~[Of]:
    type To <: Of
    val value : To
  object ~ :
    trait Conversion[Of, From]:
      type To <: Of
      def apply(from : From) : To
    transparent inline implicit def conv[Of, From](inline from : From) : ~[Of] =
      val c = summonInline[Conversion[Of, from.type]]
      new ~[Of]:
        type To = c.To
        val value : To = c(from)

  class Foo[T](value : T)
  transparent inline given [F <: Int] : ~.Conversion[Foo[_], F] = new ~.Conversion[Foo[_], F] {
    type To = Foo[F]
    def apply(from: F): Foo[F] = new Foo(from)
  }
  def foo(x : ~[Foo[_]]) = x.value

  val f1 = foo(1)
  val f1_ : Foo[1] = f1
  val one = 1
  val fOne = foo(one)
  val fOne_ : Foo[one.type] = fOne

Output

54 |  val f1 = foo(1)
   |               ^
   |               Found:    (1 : Int)
   |               Required: Bad.~[Bad.Foo[?]]

longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: sandbox\Main.scala:57:17 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

57 |  val fOne = foo(one)
   |                 ^^^
   |                 Found:    (Bad.one : Int)
   |                 Required: Bad.~[Bad.Foo[?]]

Expectation

summonInline use should be equivalent to a using clause.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions