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

Implicit polymorphic function value not used for an implicit conversion #12088

Open
noresttherein opened this issue Jul 17, 2020 · 2 comments
Open
Milestone

Comments

@noresttherein
Copy link

reproduction steps

using Scala 2.13.1,

	private[this] val cast = identity[Any] _

	abstract class TypeUnionLevel4Implicits {
		implicit def implicitUnionUnification[L, R, U <: Any | Any](implicit left :L => U, right :R => U) :(L | R) => U =
			left.asInstanceOf[(L | R) => U]
	}

	sealed abstract class TypeUnionLevel3Implicits extends TypeUnionLevel4Implicits {
		implicit def implicitRightComposedUnionMember[X, L, R <: Any | Any](implicit right :X => R) :X => (L | R) =
			right.asInstanceOf[X => (L | R)]
	}

	sealed abstract class TypeUnionLevel2Implicits extends TypeUnionLevel3Implicits {
		implicit def implicitLeftComposedUnionMember[X, L <: Any | Any, R](implicit left :X => L) :X => (L | R) =
			left.asInstanceOf[X => (L | R)]
	}

	sealed abstract class TypeUnionLevel1Implicits extends TypeUnionLevel2Implicits {
		implicit def implicitRightUnionMember[L, R] :R => (L | R) = cast.asInstanceOf[R => (L | R)]
	}

	object TypeUnion extends TypeUnionLevel1Implicits {
		implicit def implicitLeftUnionMember[L, R] :L => (L | R) = cast.asInstanceOf[L => (L | R)]

		type |[+L, +R]
	}


	implicitly[String => (String | Int)]
	implicitly[String => (Int | String)]
	val left = "left" :String | Int
	val right = "right" :Int | String
	
	implicitly[(String | Int) => (Int | String)]
	val swap = (left :String | Int) :Int | String
	implicitly[String => (Int | String | Double)]
	val middle = "middle" :Int | String | Double
	implicitly[String => (String | Int | Double | Short)]
	implicitly[String => (Short | (Double | (Int | String)))]
	val farLeft = "farLeft" :String | Int | Double | Short
	val farRight = "farRight" :Short | Double | Int | String
	implicitly[(String | Int | Double | Short) => (Short | Double | Int | String)]
	val shuffle = farLeft :Short | Double | Int | String

All lines explicitly summoning functions with implicitly compile.
None of the following lines in which these conversions should manifest (except for left and right declarations) compile.

problem

(explain how the above behavior isn't what you expected)
This goes against SLS as I understand it and certainly is very confusing.

@SethTisue
Copy link
Member

abandoned PR in this area: scala/scala#9148

@SethTisue SethTisue added this to the Backlog milestone Oct 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants