Skip to content
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

unhelpful warning for unsupported Scala 2 existential types #13873

Closed
adampauls opened this issue Nov 3, 2021 · 6 comments · Fixed by #13879
Closed

unhelpful warning for unsupported Scala 2 existential types #13873

adampauls opened this issue Nov 3, 2021 · 6 comments · Fixed by #13879
Assignees
Labels
area:pickling area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug itype:enhancement

Comments

@adampauls
Copy link
Contributor

Compiler version

3.1.0

Minimized code

Not sure, but I have a Scala 3 sbt project that depends on a Scala 2.13 project.

Output

[error] An existential type that came from a Scala-2 classfile cannot be
[error] mapped accurately to to a Scala-3 equivalent.
[error] original type    : x forSome type x
[error] reduces to       : x
[error] type used instead: Any
[error] This choice can cause follow-on type errors or hide type errors.
[error] Proceed at own risk.
[error] one error found
[error] one error found

Expectation

The error message would ideally tell me which Scala-2 classfile the symbol came from, or which Scala-3 compilation unit the reference is happening in (or both). We use x forSome type x dozens of times in our Scala code so I can't narrow down where the error is coming from.

@bishabosha bishabosha added stat:needs minimization Needs a self contained minimization and removed stat:needs minimization Needs a self contained minimization labels Nov 4, 2021
@bishabosha
Copy link
Member

here is a reproducer:

compile with Scala 2 to out:

import language.existentials

abstract class Box[T]

object Box {
  def foo(b: Box[x forSome { type x }]) = ???
}

compile with Scala 3 with out on classpath:

@main def Test =
  Box.foo(???)

producing the uninformative error:

An existential type that came from a Scala-2 classfile cannot be
mapped accurately to to a Scala-3 equivalent.
original type    : x forSome x
reduces to       : x
type used instead: Any
This choice can cause follow-on type errors or hide type errors.
Proceed at own risk.

longer explanation available when compiling with `-explain`
1 warning found

@bishabosha bishabosha removed the stat:needs minimization Needs a self contained minimization label Nov 4, 2021
@bishabosha bishabosha changed the title Error message about Scala 2 existential type is not helpful unhelpful warning for unsupported Scala 2 existential types Nov 4, 2021
@bishabosha bishabosha added itype:enhancement area:reporting Error reporting including formatting, implicit suggestions, etc area:pickling and removed itype:bug labels Nov 4, 2021
@bishabosha
Copy link
Member

if you are migrating perhaps it will work to replace all x forSome { type x } with _

@bishabosha
Copy link
Member

Also I would assume that we should be able to treat x forSome { type x } as a wildcard?

@odersky odersky self-assigned this Nov 4, 2021
@odersky
Copy link
Contributor

odersky commented Nov 4, 2021

x forSome { type x } looks strange. It would be a type that is equivalent to

  • Any if used in covariant position,
  • Nothing if used in contravariant position,
  • and would generate an inaccessible field when used in invariant position.

What's the use case for this, I wonder?

@odersky
Copy link
Contributor

odersky commented Nov 4, 2021

Note it's not equivalent to a wildcard.

Array[?] corresponds to Array[x] forSome { type x}, not Array[x forSome { type x }]

@adampauls
Copy link
Contributor Author

adampauls commented Nov 4, 2021

We used this pattern a lot. It was the way we would get code like this to compile:

def compare(x: Comparable[_], y: Comparable[_]): Int = {
  type T = x forSome { type x }
  x.asInstanceOf[Comparable[T]].compareTo(y.asInstanceOf[Comparable[T]])
}

Without the casts, you get

found   : y.type (with underlying type Comparable[_])
[error]  required: _$4

I know you can also do

x.asInstanceOf[Comparable[Any]].compareTo(y.asInstanceOf[Comparable[Any]])

in this case, but I'm pretty sure that doesn't work if there are type bounds on the type parameter. Declaring an explicit type variable also just seems less like a hack. Is there a better way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:pickling area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug itype:enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants