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

Inline match does not work on List #8103

Closed
jto opened this issue Jan 27, 2020 · 10 comments
Closed

Inline match does not work on List #8103

jto opened this issue Jan 27, 2020 · 10 comments

Comments

@jto
Copy link

jto commented Jan 27, 2020

The following example was tested in a worksheet, created from dotty-example-project (commit b135f5a) and Dotty 0.21.0-RC1

minimized code

inline def test(cs: List[Int]) <: Any =
  inline cs match
    case 1 :: Nil => 1
    case _ => scala.compiletime.error("Not one")

test(List(1)) // compilation error ("Not one")

expectation

in the given example, the first case should be matched and the value 1 of type 1 should be inlined.

@jto jto added the itype:bug label Jan 27, 2020
@nicolasstucki
Copy link
Contributor

It would require an inline parameter (see #8060). Also removing the default case helps to see the term that is not reduced.

class Test {
  inline def test(inline cs: List[Int]) <: Any =
    inline cs match
      case 1 :: Nil => 1

  test(1 :: Nil)
  test(List(1))
}
-- Error: i8103.scala:6:6 ------------------------------------------------------
6 |  test(1 :: Nil)
  |  ^^^^^^^^^^^^^^
  |  cannot reduce inline match with
  |   scrutinee:  {
  |    Nil.::[Int](1)
  |  } : List[Int]
  |   patterns :  case ::.unapply[Int](1, Nil):::[Int]

@jto
Copy link
Author

jto commented Jan 28, 2020

Hi @nicolasstucki,
Thanks for your reply :)
Looking forward to test inline params!

@odersky
Copy link
Contributor

odersky commented Jan 29, 2020

Should we close this?

@jto
Copy link
Author

jto commented Jan 29, 2020

I just tested on master and it seems to still fail :(

scala> class Test {
     |   inline def test(inline cs: List[Int]) <: Any =
     |     inline cs match
     |       case 1 :: Nil => 1
     |
     |   test(1 :: Nil)
     |   test(List(1))
     | }
6 |  test(1 :: Nil)
  |  ^^^^^^^^^^^^^^
  |  cannot reduce inline match with
  |   scrutinee:  {
  |    Nil.::[Int](1)
  |  } : List[Int]
  |   patterns :  case ::.unapply[Int](1, Nil):::[Int]
  | This location contains code that was inlined from rs$line$1:3

Am I missing something ?

@abgruszecki
Copy link
Contributor

If I remember correctly, all inline pattern matching works based on scrutinee type, not the "shape" of the argument. Here the type of the scrutinee is List[Int], so a pattern for :: won't match.

@jto
Copy link
Author

jto commented Jan 29, 2020

@AleksanderBG I don't understand what you mean by pattern matching works based on scrutinee type. Could you explain how would you rewrite the example ?

@abgruszecki
Copy link
Contributor

@jto to make it work, you mean? The below code works:

scala> class Test {                                                                                                                                                                                                
     |   inline def test(inline cs: List[Int]) <: Any =
     |     inline cs match
     |       case 1 :: _ => 1
     | 
     |   val i: 1 = test(new ::[1](1, Nil))
     | }
// defined class Test

And so does the following:

scala> class Test {                                                                                                                                                                                                
     |   inline def test(inline cs: List[Int]) <: Any =
     |     inline cs match
     |       case _ :: _ => 1
     | 
     |   val i: 1 = test(new ::(1, Nil))
     | }
// defined class Test

But neither of the below:

scala> class Test {                                                                                                                                                                                                
     |   inline def test(inline cs: List[Int]) <: Any =
     |     inline cs match
     |       case _ :: Nil => 1
     | 
     |   val i: 1 = test(new ::(1, Nil))
     | }
6 |  val i: 1 = test(new ::(1, Nil))
  |             ^^^^^^^^^^^^^^^^^^^^
  |             cannot reduce inline match with
  |              scrutinee:  {
  |               new ::[Int](1, Nil)
  |             } : ::[Int]
  |              patterns :  case ::.unapply[Int](_, Nil):::[Int]
  | This location contains code that was inlined from rs$line$3:3

scala> class Test {                                                                                                                                                                                                
     |   inline def test(inline cs: List[Int]) <: Any =
     |     inline cs match
     |       case 1 :: _ => 1
     | 
     |   val i: 1 = test(new ::(1, Nil))
     | }
6 |  val i: 1 = test(new ::(1, Nil))
  |             ^^^^^^^^^^^^^^^^^^^^
  |             cannot reduce inline match with
  |              scrutinee:  {
  |               new ::[Int](1, Nil)
  |             } : ::[Int]
  |              patterns :  case ::.unapply[Int](1, _):::[Int]
  | This location contains code that was inlined from rs$line$3:3

It's clear to us that inline patmat semantics are a bit confusing, but it's just that no one got to improving this part yet.

@jto
Copy link
Author

jto commented Jan 29, 2020

Okay I understand now. Thanks for the examples.

@abgruszecki
Copy link
Contributor

Closing as a duplicate of #6781.

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

4 participants