Skip to content

Value + is not a member of Int #10082

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
Somainer opened this issue Oct 26, 2020 · 4 comments · Fixed by #10083 or #10100
Closed

Value + is not a member of Int #10082

Somainer opened this issue Oct 26, 2020 · 4 comments · Fixed by #10083 or #10100
Assignees
Milestone

Comments

@Somainer
Copy link
Contributor

Inspired by Context Functions, I decided to practice my bad taste on simulating the it anonymous function parameter. But it doesn't work.

Minimized code

object Kotlin:
  def it[T](using t: T) = t
  def fun[T, U](fn: T ?=> U)(x: T): U = fn(using x)

import Kotlin.{fun, it}
List(1).map(fun(it + 1))

Output

|List(1).map(fun(it + 1))
  |                ^^^^
  |value + is not a member of Int, but could be made available as an extension method.
  |
  |One of the following imports might fix the problem:
  |
  |  import math.BigDecimal.int2bigDecimal
  |  import math.BigInt.int2bigInt
  |  import math.Numeric.BigDecimalAsIfIntegral.mkNumericOps
  |  import math.Numeric.BigDecimalIsFractional.mkNumericOps
  |  import math.Numeric.BigIntIsIntegral.mkNumericOps
  |  import math.Numeric.IntIsIntegral.mkNumericOps
  |  import Long.long2double
  |  import math.BigDecimal.long2bigDecimal
  |  import Long.long2float
  |  import math.BigInt.long2bigInt
  |

Expectation

This code should compile as it has already been inferred as Int.

Workaround

Providing type arguments to fun works.

List(1).map(fun[Int, Int](it + 1))
@liufengyun
Copy link
Contributor

liufengyun commented Oct 26, 2020

The following works:

object Kotlin:
  class Ctx[T](val x: T) extends AnyVal

  def fun[T, U](fn: Ctx[T] ?=> U): T => U = (x: T) => fn(using new Ctx(x))
  def it[T](using ctx: Ctx[T]) = ctx.x


import Kotlin._

@main def Test =
  val res = List(1).map(fun(it + 1))
  assert(res == List(2))

liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 26, 2020
@liufengyun
Copy link
Contributor

value + is not a member of Int

The reason is that from the program we only know that T :> Int, which is correct. By wrapping the parameter in a non-variant class Ctx, the compiler may infer T = Int.

liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 26, 2020
liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 26, 2020
@Somainer
Copy link
Contributor Author

Thank you, it worked.
However, the warning message is very confusing. And I think users like me are not able to find out the reason with the message value + is not a member of Int.

@liufengyun
Copy link
Contributor

We do need to improve the error message. I'll make another PR to fix that.

@liufengyun liufengyun reopened this Oct 27, 2020
@liufengyun liufengyun self-assigned this Oct 27, 2020
liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 27, 2020
The type `site` might be an uninitialized type variable,
but is initialized when we display the error message.
It results in confusing error message as in scala#10082.

We take a string representation of the type `site`
when the error object is created and use that in the
message message.

Now the error message is more sensible:

-- [E008] Not Found Error: tests/neg/i10082.scala:7:30 -------------------------
7 |def Test = List(1).map(fun(it + 1))
  |                           ^^^^
  |                 value + is not a member of T
  |
  |                 where:    T is a type variable with constraint >: Int
  |                 , but could be made available as an extension method.
liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 27, 2020
The type `site` in class `NotAMember` might be an uninitialized type variable,
but is initialized when we display the error message.
It results in confusing error message as in scala#10082.

We avoid instantiating the type variable when there is a unreported
error in current typerstate.
liufengyun added a commit to dotty-staging/dotty that referenced this issue Oct 30, 2020
The type `site` in class `NotAMember` might be an uninitialized type variable,
but is initialized when we display the error message.
It results in confusing error message as in scala#10082.

We avoid instantiating the type variable when there is a unreported
error in current typerstate.
liufengyun added a commit that referenced this issue Oct 30, 2020
Fix #10082: show friendly error message related to  type inference
odersky added a commit to dotty-staging/dotty that referenced this issue Nov 7, 2020
scala#10082 now compiles as well. The original test was about a confusing error message.
odersky added a commit to dotty-staging/dotty that referenced this issue Nov 9, 2020
scala#10082 now compiles as well. The original test was about a confusing error message.
smarter pushed a commit to dotty-staging/dotty that referenced this issue Nov 17, 2020
scala#10082 now compiles as well. The original test was about a confusing error message.
@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
3 participants