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

Tuple.Head being unable to work with NonEmptyTuple in match types. #17186

Closed
Decel opened this issue Mar 30, 2023 · 3 comments · Fixed by #17189
Closed

Tuple.Head being unable to work with NonEmptyTuple in match types. #17186

Decel opened this issue Mar 30, 2023 · 3 comments · Fixed by #17189

Comments

@Decel
Copy link
Contributor

Decel commented Mar 30, 2023

Compiler version

3.3.1-RC1

Minimized code

type second[X <: Tuple2[Any, Any]] = Tuple.Head[Tuple.Tail[X]] // error
type middle[X <: Tuple3[Any, Any, Any]] = Tuple.Head[Tuple.Tail[X]] // error

val a: Tuple.Head[Tuple.Tail[Tuple2[Int, String]]] = ??? // works
val b: Tuple.Head[Tuple.Tail[Tuple3[Int, String, Boolean]]] = ??? // works

Output

-- [E057] Type Mismatch Error: ---------------------------------------------------
1 |type second[X <: Tuple2[Any, Any]] = Tuple.Head[Tuple.Tail[X]]
  |                                                ^
  | Type argument Tuple.Tail[X] does not conform to upper bound NonEmptyTuple
  |
  | Note: a match type could not be fully reduced:
  |
  |   trying to reduce  Tuple.Tail[X]
  |   failed since selector X
  |   does not match  case _ *: xs => xs
  |   and cannot be shown to be disjoint from it either.
  |
  | longer explanation available when compiling with `-explain`

Expectation

Should compile.

@Decel Decel added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Mar 30, 2023
@odersky
Copy link
Contributor

odersky commented Mar 30, 2023

I think this should not compile, but the error message should be better.

To resolve this match type, we need to widen X to Tuple2[Any, Any] that does match _ *: xs but does not give us a safe instantiation of xs. It's really the same as #17180.

The error message is misleading, however. It should say that the instantiation is not unique.

@Decel
Copy link
Contributor Author

Decel commented Mar 30, 2023

This kind of behavior can be recreated in a lot of instances:

type RemoveTwo[X <: Tuple3[Any, Any, Any]] = Tuple.Tail[Tuple.Tail[X]] // error

type AltMiddle[X <: Tuple3[Any, Any, Any]] = Tuple.Tail[Tuple.Init[X]] // error

type RemoveTwo[X <: Tuple3[Any, Any, Any]] = Tuple.Head[Tuple.Concat[X, Tuple]] // error

Maybe we shouldn't have NonEmptyTuple as part of the type boundary on any Tuple method and just add additional cases for EmptyTuple?

@Decel
Copy link
Contributor Author

Decel commented Mar 30, 2023

I think this should not compile, but the error message should be better.

To resolve this match type, we need to widen X to Tuple2[Any, Any] that does match _ *: xs but does not give us a safe instantiation of xs. It's really the same as #17180.

The error message is misleading, however. It should say that the instantiation is not unique.

I'd personally treat this as not being related to match types at all. If anything, this is correct behavior since NonEmptyTuple <: Tuple.

I think Tuple.Head and Tuple.Tail should just not guarantee to be non-empty, -- we can just either throw error or return EmptyTuple.

@dwijnand dwijnand added area:match-types and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Mar 31, 2023
nicolasstucki added a commit that referenced this issue Dec 7, 2023
Fixes #17186. 

I think this is correct behaviour since we already allow things like

```Scala
val a = List(1).tail
val b = Tuple1(1).tail
```
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