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

Scala 3 does not perform implicit conversion using <:< #12955

Closed
Swoorup opened this issue Jun 27, 2021 · 15 comments · Fixed by #13662
Closed

Scala 3 does not perform implicit conversion using <:< #12955

Swoorup opened this issue Jun 27, 2021 · 15 comments · Fixed by #13662
Labels
area:implicits related to implicits itype:bug
Milestone

Comments

@Swoorup
Copy link

Swoorup commented Jun 27, 2021

Compiler version

3.0.2-RC1-bin-SNAPSHOT

Minimized code

import Tuple.Union

type Channel = "orders" | "trades"

def getChannelList[Channels <: NonEmptyTuple](c: Channels)(using Union[Channels] <:< Channel) = 
  val channels: List[Channel] = c.toList
  channels

Expectation

Compiles fine

Output

fails to compile with error:

[error] 6 |  val channels: List[Channel] = c.toList
[error]   |                                ^^^^^^^^
[error]   |Found:    List[Tuple.Union[(c : Channels)]]
[error]   |Required: List[Channel]
[error]   |
[error]   |where:    Channels is a type in method getChannelList with bounds <: NonEmptyTuple
[error]   |
[error]   |
[error]   |Note: a match type could not be fully reduced:
[error]   |
[error]   |  trying to reduce  Tuple.Union[(c : Channels)]
[error]   |  trying to reduce  scala.Tuple.Fold[(c : Channels), Nothing, [x, y] =>> x | y]
[error]   |  failed since selector  (c : Channels)
[error]   |  matches none of the cases
[error]   |
[error]   |    case EmptyTuple => Nothing
[error]   |    case h *: t => h | scala.Tuple.Fold[t, Nothing, [x, y] =>> x | y]
@nicolasstucki
Copy link
Contributor

Might be related to #12721

@SethTisue
Copy link
Member

@dwijnand I don't think you meant to assign me?

@dwijnand
Copy link
Member

dwijnand commented Jul 9, 2021

You were going to look if related PRs would fix this, and I was trying to get you hooked in enough to see if you could look into it further...

@SethTisue SethTisue removed their assignment Jul 12, 2021
@SethTisue
Copy link
Member

I have no recollection of that, and I don't have any special expertise here, so hopefully someone else would like to look into it.

@Swoorup
Copy link
Author

Swoorup commented Jul 12, 2021

I am surprised fixing this #10897 didn't fix this issue.

@SethTisue
Copy link
Member

LOL, I just found a note I wrote to myself that says "I told Dale I would definitely follow up on this" 😅

But actually, it appears that all I was going to do was verify that it isn't actually fixed yet. And now @Swoorup has already checked that. (And I just double-checked it.)

@nicolasstucki
Copy link
Contributor

Minimized

def test[A, B](using A <:< B) =
  val b: B = ??? : A

@nicolasstucki nicolasstucki added area:implicits related to implicits and removed area:match-types labels Jul 26, 2021
@nicolasstucki nicolasstucki changed the title Tuple.Union fails to reduce to Union type despite constraining Scala 3 does not perform implicit conversion using <:< Jul 26, 2021
@smarter
Copy link
Member

smarter commented Jul 26, 2021

It works with implicit, but I don't recall that being an intentional difference?

def test[A, B](implicit ev: A <:< B) =
  val b: B = ??? : A
  b

@Swoorup
Copy link
Author

Swoorup commented Aug 10, 2021

btw this is also happening when you have =:=

@odersky
Copy link
Contributor

odersky commented Oct 2, 2021

It's because <:< is declared to be a function, not a Conversion. In Scala 3 we only convert with Conversion instances. This is to avoid the famous puzzler where having an implicit parameter of Map type introduces an implicit conversion.

Maybe we need to special-case <:< and =:=.

@Swoorup
Copy link
Author

Swoorup commented Oct 3, 2021

=:=

@odersky odersky linked a pull request Oct 3, 2021 that will close this issue
@Swoorup
Copy link
Author

Swoorup commented Nov 1, 2021

@odersky
I am not sure this should be closed as fixed. The example I have still fails with 3.1.1-RC1
This might have to do with Tuple though

image

@bishabosha
Copy link
Member

bishabosha commented Nov 1, 2021

@Swoorup this should fix your example:

import Tuple.Union

type Channel = "orders" | "trades"

def getChannelList[Channels <: NonEmptyTuple](c: Channels)(using ev: Union[c.type] <:< Channel) =
  given (List[Union[c.type]] <:< List[Channel]) = ev.liftCo
  val channels: List[Channel] = c.toList
  channels

@bishabosha
Copy link
Member

bishabosha commented Nov 1, 2021

I dont think it does, actually, I can't get an implicit evidence calling getChannelList

@bishabosha
Copy link
Member

bishabosha commented Nov 1, 2021

maybe Tuple.Union does not work well with type parameters?, seems fine to infer the constraint directly:

scala> import Tuple.Union
                                                                                                                                                          
scala> type Channel = "orders" | "trades"
// defined alias type Channel = "orders" | "trades"
                                                                                                                                                          
scala> summon[Tuple.Union[("orders", "trades")] <:< Channel]
val res0: ("orders" | "trades") =:= ("orders" | "trades") = generalized constraint

scala> def foo[Channels <: NonEmptyTuple](using Tuple.Union[Channels] <:< Channel) = ???
def foo
  [Channels <: NonEmptyTuple]
    (using x$1: Tuple.Union[Channels] <:< Channel): Nothing

scala> foo[("orders", "trades")]
-- Error: ----------------------------------------------------------------------
1 |foo[("orders", "trades")]
  |                         ^
  |Cannot prove that Tuple.Union[(("orders" : String), ("trades" : String))] <:< Channel.
1 error found

@Kordyjan Kordyjan added this to the 3.1.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:implicits related to implicits itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants