scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Wrong error message when using setter extension method with wrong type

Open keynmol opened this issue 9 months ago • 3 comments

Compiler version

3.4.1

Minimized example

//> using scala 3.4.1

object types:
  opaque type Struct = Int
  val test: Struct = 25
  extension (s: Struct) 
    def field: Int = s
    def field_=(other: Int) = ()

@main def hello = 
  import types.*
  test.field = "hello"

Output Error/Warning message

[error] ./test.scala:12:3
[error] Reassignment to val field
[error]   test.field = "hello"
[error]   ^^^^^^^^^^^^^^^^^^^^

Why this Error/Warning was not helpful

I expected there to be any information about type mismatch in the error message.

-explain doesn't help:

[error] Explanation
[error] ===========
[error] You can not assign a new value to field as values can't be changed.
[error] Keep in mind that every statement has a value, so you may e.g. use
[error]   val field = if (condition) 2 else 5
[error] In case you need a reassignable name, you can declare it as
[error] variable
[error]   var field = ...
[error]   test.field = "hello"
[error]   ^^^^^^^^^^^^^^^^^^^^

keynmol avatar May 05 '24 15:05 keynmol

scala 2 got extra help for erroneous rewrite to assignment op:

Welcome to Scala 2.13.14 (OpenJDK 64-Bit Server VM, Java 21.0.2).
Type in expressions for evaluation. Or try :help.

scala> object x { def apply() = 42 ; def update(i: Int) = () }
object x

scala> x() += "42"
           ^
       error: value += is not a member of Int
         Expression does not convert to assignment because:
           type mismatch;
            found   : String
            required: Int
           expansion: x.update(x.apply().+("42"))

scala>

compare

Welcome to Scala 3.4.1 (21.0.2, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> object x { def apply() = 42 ; def update(i: Int) = () }
// defined object x

scala> x() += "42"
-- [E008] Not Found Error: ---------------------------------------------------------------------------------------------
1 |x() += "42"
  |^^^^^^
  |value += is not a member of Int - did you mean Int.!=? or perhaps Int.!= or Int.!= or Int.!=?
1 error found

scala>

It might be more complex when extensions are involved, but it's a similar area for reporting.

I suspect scala 2 excludes the unhelpful hint about != on other grounds, let alone recommending it thrice. (As in, "a hint so nice, it's recommended thrice!") Oh, I miscounted, it's four times.

som-snytt avatar May 05 '24 16:05 som-snytt

Reproduced on 3.5.0 (at 8563571e5af).

mbovel avatar May 20 '24 20:05 mbovel

This issue was picked for the Scala Issue Spree of tomorrow, May 21st. @hamzaremmal, @AnotherMedo, @iusildra, @mbovel will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here.

mbovel avatar May 20 '24 20:05 mbovel