Skip to content

Better error diagnostics and other fixes for extension methods #10902

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

Merged
merged 9 commits into from
Dec 31, 2020

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Dec 23, 2020

We gave misleading diagnostic before in the case where no extension
method was found since a TypeError was thrown.

Also: Avoid redundant test that prevented eta expansion.
Also: Drop support for extension_ names.

Fixes #10391
Fixes #9507
Fixes #10901

@odersky odersky changed the title Fix #10810: Better error diagnostics for extension methods Fix #10870: Better error diagnostics for extension methods Dec 23, 2020
@odersky odersky changed the title Fix #10870: Better error diagnostics for extension methods Better error diagnostics and other fixes for extension methods Dec 26, 2020
@bishabosha
Copy link
Member

with relation to #10044 , the error now becomes a suggestion to import opaques.arrayOps:

scala> IArray(1,2,3).reverse.sorted                                                                                   
val res0: opaques.IArray[Int] = Array(1, 2, 3)

scala> IArray(1,2,3).reverse.sorted
1 |IArray(1,2,3).reverse.sorted
  |^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |value sorted is not a member of scala.opaques.IArray[Int], but could be made available as an extension method.
  |
  |The following import might fix the problem:
  |
  |  import opaques.arrayOps
  |

Copy link
Member

@bishabosha bishabosha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code like the issue #7056 no longer give a suggestion of a tried extension method, and instead suggest that nothing was found, e.g.

type A
type B <: A

type PartialId[X] = X match {
  case B => X
}

trait T1[T] {
  extension (t1: T) def idnt1: Any
}

given [T <: A](using PartialId[T]): T1[T] = new T1[T] {
  extension (t1: T) def idnt1: Any = ???
}

given PartialId[B] = ???

val x: B = ???
val z = x.idnt1

errors with the following:

-- [E008] Not Found Error: sandbox/cls/example.scala:19:10 ---------------------
19 |val z = x.idnt1
   |        ^^^^^^^
   |        value idnt1 is not a member of B
1 error found

which I believe is probably less helpful compared to the error in M3:

-- [E008] Not Found Error: example.scala:19:10 ---------------------------------
19 |val z = x.idnt1
   |        ^^^^^^^
   |      value idnt1 is not a member of B.
   |      An extension method was tried, but could not be fully constructed:
   |
   |          example$package.given_T1_T[T](given_PartialId_B).idnt1()
1 error found

We gave misleading diagnostic before in the case where no extension
method was found since a TypeError was thrown.
… typed

We now also show with each tried extension method call that failed type checking
the first error message that indicates the failure.
The test was supposed to check that extension method resolution did
produce an extension method and not a normal method. But that test
only gave false negatives, as test sticky-extension method shows.
Bring back explanations if an implicit search was tried to resolve an extension method.
@odersky
Copy link
Contributor Author

odersky commented Dec 28, 2020

The addendums for the implicit search errors were dropped by accident. Last commit brings them back.

The error message for #10044 is now also the same as it was before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment