Skip to content

Whitelisting scala.util.Try fails to compile. #1790

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
nicolasstucki opened this issue Dec 14, 2016 · 2 comments
Closed

Whitelisting scala.util.Try fails to compile. #1790

nicolasstucki opened this issue Dec 14, 2016 · 2 comments
Assignees

Comments

@nicolasstucki
Copy link
Contributor

This fails to compile with the following error:

178 |      case Failure(e) => f(e)
    |                           ^
    |                           found:    T(e)
    |                           required: Throwable
    | 

Where the code is:

def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
    try this match {
      case Success(v) => s(v)
      case Failure(e) => f(e)
    } catch {
      case NonFatal(e) => Failure(e)
    }
@odersky
Copy link
Contributor

odersky commented Dec 14, 2016

It's the get in class Failure. Name-based pattern matching gets confused.

@odersky
Copy link
Contributor

odersky commented Dec 14, 2016

The problem is that we have a case class Failure that also happens to have a get method. This was not foreseen in our name-based pattern matching scheme, which triggers a get based match if there are get and isDefined members of the right types.

This is a general problem. Basically it means that no case class can have a get member, or we risk getting the wrong match.

To avoid the problem I propose to refine the name-based pattern matching scheme as follows.

  1. If the result type of an unapply is a subtype of ProductN and it has an isDefined method,
    the match succeeds with the result type itself.

  2. If (1) does not apply and the result type of an unapply has a member of form

    val isEmpty: Boolean or
    def isEmpty: Boolean

    and also has a member of form

    val get: T or
    def get: T

then the match succeeds with T if isEmpty is false.

This scheme has the advantage that it avoids accidental triggering of get matches and that it
is compatible with what scalac does.

odersky added a commit to dotty-staging/dotty that referenced this issue Dec 14, 2016
New implementation following the scheme outlined in scala#1790.
@odersky odersky self-assigned this Dec 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants