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

Match Type producing a List in all cases is not always recognized as List but as IterableOnce #11729

Closed
daenenk opened this issue Mar 13, 2021 · 3 comments · Fixed by #12847
Closed

Comments

@daenenk
Copy link

daenenk commented Mar 13, 2021

Compiler version 3.0.0-RC1

Minimized code

type Return[X] = X match
    case List[t] => List[t]
    case Any => List[X]

object Return:
  def apply[A](a:A):Return[A] = a match 
    case a: List[t] => a
    case a: Any => List(a)

object Test:
  Return(1).map(x => x)

Output

WARNING: method map in class IterableOnceExtensionMethods is deprecated since 2.13.0: Use .iterator.map instead or consider requiring an Iterable

Expectation

This should work. the same way as

  List(1).map(x => x)
@OlivierBlanvillain
Copy link
Contributor

The issue is that the compiler keeps Return's type variable around for too long, you can fix it by specifying it (Return[Int](1).map(x => x) or splitting the statement in two (val x = Return(1); x.map(x => x))

@smarter
Copy link
Member

smarter commented Mar 15, 2021

ah, so I guess we end up with Return[?T] where ?T >: Int which is not enough to conclude that there's a map on this type because it's a match type? But typedSelect calls couldInstantiateTypeVar whose job is to instantiate any type variable that might uncover members, and when it sees a match type it should instantiate its type variables: https://github.com/lampepfl/dotty/blob/60cbef1436d82b275bb1f9b155cf0fb2b74ed8e4/compiler/src/dotty/tools/dotc/typer/Inferencing.scala#L103-L108, any idea why this doesn't trigger here?

@daenenk
Copy link
Author

daenenk commented Mar 18, 2021

I have a similar example, looks like a similar issue

Code

type Boxed[X] = X match
   case Box[t] => Box[t]
   case Any => Box[X]

def box[X](x: X): Boxed[X] = x match
   case b: Box[t] => b
   case x: Any => Box(x)

case class Box[A](a:A):
  def map[B](f: A => B): Box[B] = Box(f(a))

object Test:
   box(box(1)).map(_ + 1)

Output

error: value map is not a member of Boxed[Boxed[Int]]

Expected output

The following snippet does work, so I expect the above to behave the same

object Test:
  box(1).map(_ + 1)

  val b = box(1)
  val bb = box(b)
  bb.map(_ + 1)

when I modify the match type declaration to:

type Boxed[X] <: Box[?] = X match
   case Box[t] => Box[t]
   case Any => Box[X]

the line

    box(1).map(_ + 1)

gives the error

Found:    Int => Int
Required: Boxed[Int]#A => Int

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.

3 participants