Skip to content

Extension method tried, but could not be fully constructed when using polymorphic operand #10901

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

Closed
hmf opened this issue Dec 23, 2020 · 1 comment · Fixed by #10902
Closed
Milestone

Comments

@hmf
Copy link

hmf commented Dec 23, 2020

Minimized code

Possible bug in self-contained example below due to polymorphic types.

import scala.annotation.targetName

object BugExp4Point2D {

  sealed trait ColumnType[T]
  case object DoubleT extends ColumnType[Double]
  case object IntT extends ColumnType[Int]

  object dsl {


    extension [T1:Numeric, T2:Numeric](x: T1)

      // N - N
      @targetName("point2DConstant")
      def º(y: T2): Point2D[T1,T2] = ???


      // N - C
      @targetName("point2DConstantData")
      def º(y: ColumnType[T2]): Point2D[T1,T2] = ???



    extension [T1:Numeric, T2:Numeric](x: ColumnType[T1])
      // C - C
      @targetName("point2DData")
      def º(y: ColumnType[T2]): Point2D[T1,T2] = ???

      // C - N
      @targetName("point2DDataConstant")
      def º(y: T2): Point2D[T1,T2] = ???


  }

  case class Point2D[T1:Numeric, T2:Numeric](x:T1, y:T2)

  import dsl._

  def main(args: Array[String]): Unit = {
    val x = IntT
    val y = DoubleT

    val pos1: Point2D[Int,Double] = x º y
    val pos2: Point2D[Int,Double] = 100 º 200.1
    val pos3: Point2D[Int,Double] = 101 º y
    val pos4: Point2D[Int,Double] = x º 201.1

  }
}

Output

[error] -- [E008] Not Found Error: /home/hhh/IdeaProjects/snol/splotly/src/gg/BugExp4Point2D.scala:55:38 
[error] 55 |    val pos1: Point2D[Int,Double] = x º y
[error]    |                                    ^^^
[error]    |      value º is not a member of object gg.BugExp4Point2D.IntT.
[error]    |      An extension method was tried, but could not be fully constructed:
[error]    |
[error]    |          º(x)
[error] -- [E008] Not Found Error: /home/hhh/IdeaProjects/snol/splotly/src/gg/BugExp4Point2D.scala:58:38 
[error] 58 |    val pos4: Point2D[Int,Double] = x º 201.1
[error]    |                                    ^^^
[error]    |      value º is not a member of object gg.BugExp4Point2D.IntT.
[error]    |      An extension method was tried, but could not be fully constructed:
[error]    |
[error]    |          º(x)

Expectation

I expected pos1 and pos4 to be handled correctly just as pos2 and pos3 are.
What is different in pos1 and pos4 is that the first operand uses a polymorphic type parameter.
If it is a bug, any way of circumventing this temporarily?

Tested on M3.

EDIT: Forgot to indicate that if we remove the last extension and pos4, the example compiles correctly.

@hmf hmf added the itype:bug label Dec 23, 2020
odersky added a commit to dotty-staging/dotty that referenced this issue Dec 23, 2020
… typed

We now also show with each tried extension method call that failed type checking
the first error message that indicates the failure.
@bishabosha
Copy link
Member

bishabosha commented Dec 28, 2020

using this variation without extension methods we still get the same ambiguities that cause the extensions to not be found in the original example:

import scala.annotation.targetName

object BugExp4Point2D {

  sealed trait ColumnType[T]
  case object DoubleT extends ColumnType[Double]
  case object IntT extends ColumnType[Int]

  object dsl {


    // N - N
    @targetName("point2DConstant")
    def º[T1:Numeric, T2:Numeric](x: T1)(y: T2): Point2D[T1,T2] = ???


    // N - C
    @targetName("point2DConstantData")
    def º[T1:Numeric, T2:Numeric](x: T1)(y: ColumnType[T2]): Point2D[T1,T2] = ???


    // C - C
    @targetName("point2DData")
    def º[T1:Numeric, T2:Numeric](x: ColumnType[T1])(y: ColumnType[T2]): Point2D[T1,T2] = ???

    // C - N
    @targetName("point2DDataConstant")
    def º[T1:Numeric, T2:Numeric](x: ColumnType[T1])(y: T2): Point2D[T1,T2] = ???


  }

  case class Point2D[T1:Numeric, T2:Numeric](x:T1, y:T2)

  import dsl._

  def main(args: Array[String]): Unit = {
    val x = IntT
    val y = DoubleT

    val pos1: Point2D[Int,Double] = º(x)(y)
    val pos2: Point2D[Int,Double] = º(100)(200.1)
    val pos3: Point2D[Int,Double] = º(101)(y)
    val pos4: Point2D[Int,Double] = º(x)(201.1)

  }
}

odersky added a commit to dotty-staging/dotty that referenced this issue Dec 28, 2020
… typed

We now also show with each tried extension method call that failed type checking
the first error message that indicates the failure.
@Kordyjan Kordyjan added this to the 3.0.0 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants