Skip to content

Type member selection on argument of type Nothing fails #11864

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
japgolly opened this issue Mar 23, 2021 · 6 comments · Fixed by #11917
Closed

Type member selection on argument of type Nothing fails #11864

japgolly opened this issue Mar 23, 2021 · 6 comments · Fixed by #11917
Assignees
Milestone

Comments

@japgolly
Copy link
Contributor

Compiler version

3.0.0-RC1 with -Ykind-projector -Yerased-terms

Minimized code

final class CallbackTo[+A] {
  inline def map[B](f: A => B)(using erased ev: CallbackTo.MapGuard[B]): CallbackTo[ev.Out] = ???
}

object CallbackTo {

  type MapGuard[A] = { type Out = A }
  erased given MapGuard[A]: MapGuard[A] = ???

  def traverse[A, B](ta: List[A]): CallbackTo[List[B]] =
    val x: CallbackTo[List[A] => List[B]] = ???
    x.map(_(ta))
}

Output

12 |    x.map(_(ta))
   |    ^^^^^^^^^^^^
   |Out cannot be accessed as a member of (ev$proxy1 : Nothing) from module class CallbackTo$.
   | This location contains code that was inlined from x.scala:2
1 error found

Expectation

It should compile.

The problem occurs due to the combination of inline and erased because either of the following work as workarounds:

  • Removing inline from .map
  • Changing MapGuard to not be erased
@japgolly japgolly changed the title Phantom type + inline + erased = crash Type-member-only-type + inline + erased = crash Mar 23, 2021
@nicolasstucki
Copy link
Contributor

Minimized

type Ev = { type Out }
inline def foo(ev: Ev): Option[ev.Out] = ???
def test: Unit = foo(???)

The issue is that when we inline an ??? argument the inliner takes it as if it was of type Nothing and forgets the type of the parameter. Then any member selection fails. Maybe the binder should have type Nothing & Ev where the precise type of the argument is Nothing and the type of the parameter is Ev. If we can keep this type without collapsing it to Nothing then we could have the info we need for the member selection.

This issue appeared with the erased given because we optimize it away early to ???.

@nicolasstucki nicolasstucki changed the title Type-member-only-type + inline + erased = crash Type member selection on argument of type Nothing fails Mar 26, 2021
@nicolasstucki
Copy link
Contributor

This issue is the type selection version of issue #8612

@nicolasstucki
Copy link
Contributor

Null has the same issue

@nicolasstucki
Copy link
Contributor

An alternative might be to use the type of the parameter instead of a bottom type.

@liufengyun
Copy link
Contributor

It seems to me your original proposal to use type ascriptions is a good and principled solution.

@odersky
Copy link
Contributor

odersky commented Mar 26, 2021

I agree, we should try to type ascribe in this case

odersky added a commit to dotty-staging/dotty that referenced this issue Mar 27, 2021
odersky added a commit to dotty-staging/dotty that referenced this issue Mar 27, 2021
michelou pushed a commit to michelou/scala3 that referenced this issue Apr 6, 2021
@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
Development

Successfully merging a pull request may close this issue.

5 participants